import { useState, useEffect, type FormEvent } from 'react';
import { toast } from 'sonner';
import type { Port, Vlan, VlanMode } from '../../types';
import { Modal } from '../ui/Modal';
import { Button } from '../ui/Button';
import { Badge } from '../ui/Badge';
import { apiClient } from '../../api/client';
import { useRackStore } from '../../store/useRackStore';

interface PortConfigModalProps {
  portId: string;
  open: boolean;
  onClose: () => void;
}

export function PortConfigModal({ portId, open, onClose }: PortConfigModalProps) {
  const { racks, updateModuleLocal } = useRackStore();
  const [port, setPort] = useState<Port | null>(null);
  const [vlans, setVlans] = useState<Vlan[]>([]);
  const [label, setLabel] = useState('');
  const [mode, setMode] = useState<VlanMode>('ACCESS');
  const [nativeVlanId, setNativeVlanId] = useState<string>('');
  const [taggedVlanIds, setTaggedVlanIds] = useState<string[]>([]);
  const [notes, setNotes] = useState('');
  const [loading, setLoading] = useState(false);
  const [fetching, setFetching] = useState(false);
  // Quick-create VLAN
  const [newVlanId, setNewVlanId] = useState('');
  const [newVlanName, setNewVlanName] = useState('');
  const [creatingVlan, setCreatingVlan] = useState(false);

  // Find the port from store
  useEffect(() => {
    if (!open) return;
    let found: Port | undefined;
    for (const rack of racks) {
      for (const mod of rack.modules) {
        found = mod.ports.find((p) => p.id === portId);
        if (found) break;
      }
      if (found) break;
    }
    if (found) {
      setPort(found);
      setLabel(found.label ?? '');
      setMode(found.mode);
      setNativeVlanId(found.nativeVlan?.toString() ?? '');
      setTaggedVlanIds(found.vlans.filter((v) => v.tagged).map((v) => v.vlanId));
      setNotes(found.notes ?? '');
    }
  }, [open, portId, racks]);

  // Load VLAN list
  useEffect(() => {
    if (!open) return;
    setFetching(true);
    apiClient.vlans
      .list()
      .then(setVlans)
      .catch(() => toast.error('Failed to load VLANs'))
      .finally(() => setFetching(false));
  }, [open]);

  async function handleSubmit(e: FormEvent) {
    e.preventDefault();
    setLoading(true);
    try {
      const vlanAssignments = [
        ...(mode === 'ACCESS' && nativeVlanId
          ? [{ vlanId: vlans.find((v) => v.vlanId === Number(nativeVlanId))?.id ?? '', tagged: false }]
          : []),
        ...(mode !== 'ACCESS'
          ? taggedVlanIds.map((id) => ({ vlanId: id, tagged: true }))
          : []),
      ].filter((v) => v.vlanId);

      await apiClient.ports.update(portId, {
        label: label.trim() || undefined,
        mode,
        nativeVlan: nativeVlanId ? Number(nativeVlanId) : null,
        notes: notes.trim() || undefined,
        vlans: vlanAssignments,
      });

      // Refresh racks to reflect changes
      const portsInRack = racks.flatMap((r) => r.modules).find((m) => m.ports.some((p) => p.id === portId));
      if (portsInRack) {
        const updatedPorts = await apiClient.modules.getPorts(portsInRack.id);
        updateModuleLocal(portsInRack.id, { ports: updatedPorts });
      }

      toast.success('Port saved');
      onClose();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Save failed');
    } finally {
      setLoading(false);
    }
  }

  async function handleCreateVlan() {
    const id = Number(newVlanId);
    if (!id || !newVlanName.trim()) return;
    setCreatingVlan(true);
    try {
      const created = await apiClient.vlans.create({ vlanId: id, name: newVlanName.trim() });
      setVlans((v) => [...v, created].sort((a, b) => a.vlanId - b.vlanId));
      setNewVlanId('');
      setNewVlanName('');
      toast.success(`VLAN ${id} created`);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to create VLAN');
    } finally {
      setCreatingVlan(false);
    }
  }

  function toggleTaggedVlan(vlanDbId: string) {
    setTaggedVlanIds((prev) =>
      prev.includes(vlanDbId) ? prev.filter((id) => id !== vlanDbId) : [...prev, vlanDbId]
    );
  }

  if (!port) return null;

  return (
    <Modal open={open} onClose={onClose} title={`Port ${port.portNumber} Configuration`} size="md">
      <form onSubmit={handleSubmit} className="space-y-4">
        {/* Port info */}
        <div className="flex items-center gap-2">
          <Badge variant="slate">{port.portType}</Badge>
          <span className="text-xs text-slate-500">Port #{port.portNumber}</span>
        </div>

        {/* Label */}
        <div className="space-y-1">
          <label className="block text-sm text-slate-300">Label</label>
          <input
            value={label}
            onChange={(e) => setLabel(e.target.value)}
            disabled={loading}
            placeholder="e.g. Server 1 uplink"
            className="w-full bg-slate-900 border border-slate-600 rounded-lg px-3 py-2 text-sm text-slate-100 placeholder:text-slate-600 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50"
          />
        </div>

        {/* Mode */}
        <div className="space-y-1">
          <label className="block text-sm text-slate-300">Mode</label>
          <div className="flex gap-2">
            {(['ACCESS', 'TRUNK', 'HYBRID'] as VlanMode[]).map((m) => (
              <button
                key={m}
                type="button"
                onClick={() => setMode(m)}
                className={`px-3 py-1.5 rounded text-xs font-medium border transition-colors ${
                  mode === m
                    ? 'bg-blue-600 border-blue-500 text-white'
                    : 'bg-slate-900 border-slate-600 text-slate-400 hover:border-slate-500'
                }`}
              >
                {m}
              </button>
            ))}
          </div>
        </div>

        {/* Native VLAN */}
        <div className="space-y-1">
          <label className="block text-sm text-slate-300">Native VLAN</label>
          <select
            value={nativeVlanId}
            onChange={(e) => setNativeVlanId(e.target.value)}
            disabled={loading || fetching}
            className="w-full bg-slate-900 border border-slate-600 rounded-lg px-3 py-2 text-sm text-slate-100 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50"
          >
            <option value="">— Untagged —</option>
            {vlans.map((v) => (
              <option key={v.id} value={v.vlanId.toString()}>
                VLAN {v.vlanId} — {v.name}
              </option>
            ))}
          </select>
        </div>

        {/* Tagged VLANs — Trunk/Hybrid only */}
        {mode !== 'ACCESS' && (
          <div className="space-y-1">
            <label className="block text-sm text-slate-300">Tagged VLANs</label>
            <div className="max-h-32 overflow-y-auto bg-slate-900 border border-slate-600 rounded-lg p-2 flex flex-wrap gap-1.5">
              {vlans.length === 0 && (
                <span className="text-xs text-slate-600">No VLANs defined yet</span>
              )}
              {vlans.map((v) => (
                <button
                  key={v.id}
                  type="button"
                  onClick={() => toggleTaggedVlan(v.id)}
                  className={`px-2 py-0.5 rounded text-xs border transition-colors ${
                    taggedVlanIds.includes(v.id)
                      ? 'bg-blue-700 border-blue-500 text-white'
                      : 'bg-slate-800 border-slate-600 text-slate-400 hover:border-slate-400'
                  }`}
                >
                  {v.vlanId} {v.name}
                </button>
              ))}
            </div>
          </div>
        )}

        {/* Quick-create VLAN */}
        <div className="border border-slate-700 rounded-lg p-3 space-y-2">
          <p className="text-xs font-medium text-slate-400">Quick-create VLAN</p>
          <div className="flex gap-2">
            <input
              type="number"
              min={1}
              max={4094}
              value={newVlanId}
              onChange={(e) => setNewVlanId(e.target.value)}
              placeholder="VLAN ID"
              className="w-24 bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-xs text-slate-100 placeholder:text-slate-600 focus:outline-none focus:ring-1 focus:ring-blue-500"
            />
            <input
              value={newVlanName}
              onChange={(e) => setNewVlanName(e.target.value)}
              placeholder="Name"
              className="flex-1 bg-slate-900 border border-slate-600 rounded px-2 py-1.5 text-xs text-slate-100 placeholder:text-slate-600 focus:outline-none focus:ring-1 focus:ring-blue-500"
            />
            <Button
              type="button"
              size="sm"
              variant="secondary"
              onClick={handleCreateVlan}
              loading={creatingVlan}
              disabled={!newVlanId || !newVlanName.trim()}
            >
              Add
            </Button>
          </div>
        </div>

        {/* Notes */}
        <div className="space-y-1">
          <label className="block text-sm text-slate-300">Notes</label>
          <textarea
            rows={2}
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
            disabled={loading}
            className="w-full bg-slate-900 border border-slate-600 rounded-lg px-3 py-2 text-sm text-slate-100 placeholder:text-slate-600 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50 resize-none"
          />
        </div>

        <div className="flex justify-end gap-3">
          <Button variant="secondary" size="sm" type="button" onClick={onClose} disabled={loading}>
            Cancel
          </Button>
          <Button size="sm" type="submit" loading={loading}>
            Save Port
          </Button>
        </div>
      </form>
    </Modal>
  );
}
