import { useState } from 'react'
import modalStyles from './modal-interactive.module.css'
import { RotateCcw } from 'lucide-react'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { EDGE_TYPE_LABELS, type EdgeData, type EdgeLineStyle, type EdgePathStyle, type EdgeType, type MarkerShape } from '@/types'
import { EDGE_DEFAULT_COLORS } from '@/utils/edgeColors'
import { normalizeMarker } from '@/utils/edgeMarkers'
import {
  EDGE_LINE_STYLES, EDGE_LINE_STYLE_LABELS, EDGE_TYPE_BASE_WIDTH, EDGE_TYPE_DEFAULT_LINE,
  clampWidthMult, dashArrayFor,
} from '@/utils/edgeLineStyle'
import { MarkerShapePicker } from './MarkerShapePicker'

const EDGE_TYPES = Object.entries(EDGE_TYPE_LABELS) as [EdgeType, string][]

type AnimMode = 'none' | 'basic' | 'snake' | 'flow'

function toAnimMode(v: EdgeData['animated']): AnimMode {
  if (v === true || v === 'snake') return 'snake'
  if (v === 'flow') return 'flow'
  if (v === 'basic') return 'basic'
  return 'none'
}

interface EdgeModalProps {
  open: boolean
  onClose: () => void
  onSubmit: (data: EdgeData) => void
  onDelete?: () => void
  onClearWaypoints?: () => void
  initial?: Partial<EdgeData>
  title?: string
}

export function EdgeModal({ open, onClose, onSubmit, onDelete, onClearWaypoints, initial, title = 'Connect Nodes' }: EdgeModalProps) {
  const [type, setType] = useState<EdgeType>(initial?.type ?? 'ethernet')
  const [label, setLabel] = useState(initial?.label ?? '')
  const [vlanId, setVlanId] = useState(initial?.vlan_id?.toString() ?? '')
  const [customColor, setCustomColor] = useState<string | undefined>(initial?.custom_color)
  const [pathStyle, setPathStyle] = useState<EdgePathStyle>(initial?.path_style ?? 'bezier')
  const [animation, setAnimation] = useState<AnimMode>(() => toAnimMode(initial?.animated))
  const [markerStart, setMarkerStart] = useState<MarkerShape>(normalizeMarker(initial?.marker_start))
  const [markerEnd, setMarkerEnd] = useState<MarkerShape>(normalizeMarker(initial?.marker_end))
  // Undefined = follow the edge type's default line preset (live, like color).
  const [lineStyle, setLineStyle] = useState<EdgeLineStyle | undefined>(initial?.line_style)
  const [widthMult, setWidthMult] = useState<number>(clampWidthMult(initial?.width_mult))

  const effectiveColor = customColor ?? EDGE_DEFAULT_COLORS[type]
  const effectiveLineStyle = lineStyle ?? EDGE_TYPE_DEFAULT_LINE[type]
  const previewWidth = EDGE_TYPE_BASE_WIDTH[type] * widthMult

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    onSubmit({
      type,
      label: label.trim() || undefined,
      vlan_id: type === 'vlan' && vlanId ? parseInt(vlanId) : undefined,
      custom_color: customColor,
      path_style: pathStyle,
      line_style: effectiveLineStyle,
      width_mult: widthMult,
      animated: animation !== 'none' ? animation : undefined,
      marker_start: markerStart,
      marker_end: markerEnd,
    })
    onClose()
  }

  const handleDelete = () => {
    onDelete?.()
    onClose()
  }

  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="bg-[#161b22] border-[#30363d] text-foreground max-w-xs">
        <DialogHeader>
          <DialogTitle className="text-sm font-semibold">{title}</DialogTitle>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="flex flex-col gap-3 mt-2">
          <div className="flex flex-col gap-1.5">
            <Label className="text-xs text-muted-foreground">Link Type</Label>
            <Select value={type} onValueChange={(v) => setType(v as EdgeType)}>
              <SelectTrigger className={`bg-[#21262d] border-[#30363d] text-sm h-8 cursor-pointer ${modalStyles['modal-interactive']} ${modalStyles['modal-radius']}`} aria-label="Edge type selector">
                <SelectValue>{EDGE_TYPE_LABELS[type]}</SelectValue>
              </SelectTrigger>
              <SelectContent className="bg-[#21262d] border-[#30363d]">
                {EDGE_TYPES.map(([value, label]) => (
                  <SelectItem key={value} value={value} className="text-sm">{label}</SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>

          {type === 'vlan' && (
            <div className="flex flex-col gap-1.5">
              <Label className="text-xs text-muted-foreground">VLAN ID</Label>
              <Input
                type="number"
                min={1}
                max={4094}
                value={vlanId}
                onChange={(e) => setVlanId(e.target.value)}
                placeholder="e.g. 20"
                className={`bg-[#21262d] border-[#30363d] font-mono text-sm h-8 ${modalStyles['modal-radius']}`}
              />
            </div>
          )}

          <div className="flex flex-col gap-1.5">
            <Label className="text-xs text-muted-foreground">Label <span className="text-muted-foreground/50">(optional, multi-line)</span></Label>
            <Textarea
              value={label}
              onChange={(e) => setLabel(e.target.value)}
              placeholder={'e.g. 1G, trunk...\nsecond line'}
              rows={2}
              className={`bg-[#21262d] border-[#30363d] text-sm min-h-16 resize-none ${modalStyles['modal-radius']}`}
            />
          </div>

          <div className="flex flex-col gap-1.5">
            <Label className="text-xs text-muted-foreground">Path Style</Label>
            <div className={`flex rounded-md overflow-hidden border border-[#30363d] ${modalStyles['modal-interactive']}`}> 
              {(['bezier', 'smooth'] as EdgePathStyle[]).map((style) => (
                <button
                  key={style}
                  type="button"
                  onClick={() => setPathStyle(style)}
                  className="flex-1 py-1 text-xs capitalize transition-colors cursor-pointer"
                  tabIndex={0}
                  aria-label={`Path style ${style}`}
                  style={{
                    background: pathStyle === style ? '#00d4ff22' : '#21262d',
                    color: pathStyle === style ? '#00d4ff' : '#8b949e',
                    borderRight: style === 'bezier' ? '1px solid #30363d' : undefined,
                  }}
                >
                  {style === 'bezier' ? 'Bezier' : 'Smooth step'}
                </button>
              ))}
            </div>
          </div>

          <div className="flex flex-col gap-1.5">
            <div className="flex items-center justify-between">
              <Label className="text-xs text-muted-foreground">Line Style</Label>
              <svg width={56} height={12} aria-hidden>
                <line
                  x1={2}
                  y1={6}
                  x2={54}
                  y2={6}
                  stroke={effectiveColor}
                  strokeWidth={previewWidth}
                  strokeDasharray={dashArrayFor(effectiveLineStyle, previewWidth)}
                  strokeLinecap={effectiveLineStyle === 'dotted' ? 'round' : 'butt'}
                />
              </svg>
            </div>
            <div className={`flex rounded-md overflow-hidden border border-[#30363d] ${modalStyles['modal-interactive']}`}>
              {EDGE_LINE_STYLES.map((ls, i) => (
                <button
                  key={ls}
                  type="button"
                  onClick={() => setLineStyle(ls)}
                  className="flex-1 py-1 text-xs transition-colors cursor-pointer"
                  tabIndex={0}
                  aria-label={`Line style ${ls}`}
                  style={{
                    background: effectiveLineStyle === ls ? '#00d4ff22' : '#21262d',
                    color: effectiveLineStyle === ls ? '#00d4ff' : '#8b949e',
                    borderRight: i < EDGE_LINE_STYLES.length - 1 ? '1px solid #30363d' : undefined,
                  }}
                >
                  {EDGE_LINE_STYLE_LABELS[ls]}
                </button>
              ))}
            </div>
          </div>

          <div className="flex flex-col gap-1.5">
            <div className="flex items-center justify-between">
              <Label className="text-xs text-muted-foreground">Line Width</Label>
              <span className="text-xs text-muted-foreground">{widthMult}×</span>
            </div>
            <input
              type="range"
              min={1}
              max={4}
              step={1}
              value={widthMult}
              onChange={(e) => setWidthMult(clampWidthMult(parseInt(e.target.value, 10)))}
              aria-label="Line width multiplier"
              className="w-full h-1 accent-[#00d4ff]"
            />
          </div>

          <div className="flex flex-col gap-1.5">
            <Label className="text-xs text-muted-foreground">Animation</Label>
            <div className={`flex rounded-md overflow-hidden border border-[#30363d] ${modalStyles['modal-interactive']}`}> 
              {(['none', 'basic', 'snake', 'flow'] as AnimMode[]).map((mode, i) => (
                <button
                  key={mode}
                  type="button"
                  onClick={() => setAnimation(mode)}
                  className="flex-1 py-1 text-xs capitalize transition-colors cursor-pointer"
                  tabIndex={0}
                  aria-label={`Animation mode ${mode}`}
                  style={{
                    background: animation === mode ? '#00d4ff22' : '#21262d',
                    color: animation === mode ? '#00d4ff' : '#8b949e',
                    borderRight: i < 3 ? '1px solid #30363d' : undefined,
                  }}
                >
                  {mode === 'none' ? 'None' : mode === 'basic' ? 'Basic' : mode === 'snake' ? 'Snake' : 'Flow'}
                </button>
              ))}
            </div>
          </div>

          <div className="flex flex-col gap-1.5">
            <Label className="text-xs text-muted-foreground">Endpoints</Label>
            <div className="flex flex-col gap-1.5">
              <MarkerShapePicker label="Start" value={markerStart} onChange={setMarkerStart} />
              <MarkerShapePicker label="End" value={markerEnd} onChange={setMarkerEnd} />
            </div>
          </div>

          <div className="flex flex-col gap-1.5">
            <div className="flex items-center justify-between">
              <Label className="text-xs text-muted-foreground">Color</Label>
              {customColor && (
                <button
                  type="button"
                  onClick={() => setCustomColor(undefined)}
                  className="flex items-center gap-1 text-[10px] text-muted-foreground/60 hover:text-muted-foreground transition-colors"
                >
                  <RotateCcw size={10} /> Reset
                </button>
              )}
            </div>
            <label
              className={`relative flex items-center gap-2.5 px-2.5 h-8 rounded-md border cursor-pointer ${modalStyles['modal-interactive']}`}
              style={{ borderColor: customColor ? effectiveColor : '#30363d', background: '#21262d' }}
              tabIndex={0}
              aria-label="Edge color picker"
            >
              <input
                type="color"
                value={effectiveColor}
                onChange={(e) => setCustomColor(e.target.value)}
                className="absolute opacity-0 w-0 h-0"
              />
              <div className="w-4 h-4 rounded-sm shrink-0 border border-white/10" style={{ background: effectiveColor }} />
              <span className="font-mono text-xs" style={{ color: customColor ? effectiveColor : '#8b949e' }}>
                {effectiveColor}
              </span>
              {!customColor && <span className="text-[10px] text-muted-foreground/50 ml-auto">default</span>}
            </label>
          </div>

          {onClearWaypoints && initial?.waypoints && initial.waypoints.length > 0 && (
            <button
              type="button"
              onClick={() => { onClearWaypoints(); onClose() }}
              className="text-[10px] text-muted-foreground hover:text-[#e3b341] transition-colors text-left"
            >
              Clear path ({initial.waypoints.length} point{initial.waypoints.length !== 1 ? 's' : ''})
            </button>
          )}

          <div className="flex justify-between gap-2 pt-1">
            {onDelete ? (
              <Button type="button" variant="ghost" size="sm" className="text-[#f85149] hover:text-[#f85149] hover:bg-[#f85149]/10 cursor-pointer" onClick={handleDelete}>
                Delete
              </Button>
            ) : <span />}
            <div className="flex gap-2">
              <Button type="button" variant="ghost" size="sm" className="cursor-pointer" onClick={onClose}>Cancel</Button>
              <Button type="submit" size="sm" className="bg-[#00d4ff] text-[#0d1117] hover:bg-[#00d4ff]/90 cursor-pointer">
                {onDelete ? 'Save' : 'Connect'}
              </Button>
            </div>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  )
}
