import { useEffect, useState } from 'react';
import { Plus, Trash2, Network, Cable } from 'lucide-react';
import { api } from '../api';
import { Card, Badge, StatusBadge, Btn, Field, inputCls, Modal, Spinner, ErrorBox, Table } from '../components/ui';

const STATUS_LABELS = { active: 'Actief', standby: 'Standby', decommissioned: 'Uitgefaseerd' };
const DEVICE_TYPES = ['switch', 'router', 'firewall', 'loadbalancer', 'ap', 'other'];
const CONN_TYPES = { rack_device: 'Rack-device', network_device: 'Netwerkdevice', external: 'Extern' };
const MEDIA_TYPES = ['copper', 'sfp', 'sfp+', 'qsfp', 'dac', 'fiber'];

const EMPTY_DEVICE = {
  client_id: '', name: '', device_type: 'switch', model: '', manufacturer: '',
  ip_address: '', mgmt_ip: '', ports_count: 24, os_version: '', status: 'active', notes: ''
};
const EMPTY_CONN = {
  client_id: '', name: '', from_type: 'network_device', from_id: '', from_port: '',
  to_type: 'network_device', to_id: '', to_port: '', media_type: 'copper',
  speed: '1GbE', vlan: '', status: 'active', notes: ''
};

function TabBar({ tabs, active, onChange }) {
  return (
    <div className="flex gap-1 border-b border-border-soft">
      {tabs.map(t => (
        <button
          key={t.key}
          onClick={() => onChange(t.key)}
          className={`px-3.5 py-2 text-[13px] font-medium border-b-2 -mb-px transition-colors ${
            active === t.key ? 'border-accent text-accent' : 'border-transparent text-muted hover:text-text'
          }`}
        >
          {t.label}
        </button>
      ))}
    </div>
  );
}

export default function Networking() {
  const [tab, setTab] = useState('devices');
  const [clients, setClients] = useState([]);

  // Devices state
  const [devices, setDevices] = useState(null);
  const [devError, setDevError] = useState(null);
  const [devModal, setDevModal] = useState(false);
  const [editDev, setEditDev] = useState(null);
  const [devForm, setDevForm] = useState(EMPTY_DEVICE);

  // Connections state
  const [conns, setConns] = useState(null);
  const [connError, setConnError] = useState(null);
  const [connModal, setConnModal] = useState(false);
  const [editConn, setEditConn] = useState(null);
  const [connForm, setConnForm] = useState(EMPTY_CONN);

  const [saving, setSaving] = useState(false);
  const [saveError, setSaveError] = useState(null);

  const loadDevices = () => {
    setDevError(null);
    api.get('/networking/devices').then(setDevices).catch(setDevError);
  };
  const loadConns = () => {
    setConnError(null);
    api.get('/networking/connections').then(setConns).catch(setConnError);
  };

  useEffect(() => { loadDevices(); loadConns(); }, []);
  useEffect(() => { api.get('/clients').then(setClients).catch(() => {}); }, []);

  // ---- Device modal ----
  const openDevNew = () => {
    setEditDev(null);
    setDevForm(EMPTY_DEVICE);
    setSaveError(null);
    setDevModal(true);
  };
  const openDevEdit = (d) => {
    setEditDev(d);
    setDevForm({
      client_id: d.client_id, name: d.name || '', device_type: d.device_type || 'switch',
      model: d.model || '', manufacturer: d.manufacturer || '', ip_address: d.ip_address || '',
      mgmt_ip: d.mgmt_ip || '', ports_count: d.ports_count ?? 24, os_version: d.os_version || '',
      status: d.status || 'active', notes: d.notes || ''
    });
    setSaveError(null);
    setDevModal(true);
  };
  const saveDev = async (e) => {
    e.preventDefault();
    setSaving(true);
    setSaveError(null);
    const body = { ...devForm, ports_count: parseInt(devForm.ports_count, 10) || 24 };
    try {
      if (editDev) {
        await api.put(`/networking/devices/${editDev.id}`, body);
      } else {
        await api.post('/networking/devices', body);
      }
      setDevModal(false);
      loadDevices();
    } catch (err) {
      setSaveError(err);
    } finally {
      setSaving(false);
    }
  };
  const deleteDev = async () => {
    if (!editDev) return;
    if (!window.confirm(`Device "${editDev.name}" verwijderen?`)) return;
    setSaving(true);
    setSaveError(null);
    try {
      await api.del(`/networking/devices/${editDev.id}`);
      setDevModal(false);
      loadDevices();
    } catch (err) {
      setSaveError(err);
    } finally {
      setSaving(false);
    }
  };

  // ---- Connection modal ----
  const openConnNew = () => {
    setEditConn(null);
    setConnForm(EMPTY_CONN);
    setSaveError(null);
    setConnModal(true);
  };
  const openConnEdit = (c) => {
    setEditConn(c);
    setConnForm({
      client_id: c.client_id, name: c.name || '', from_type: c.from_type || 'network_device',
      from_id: c.from_id ?? '', from_port: c.from_port || '', to_type: c.to_type || 'network_device',
      to_id: c.to_id ?? '', to_port: c.to_port || '', media_type: c.media_type || 'copper',
      speed: c.speed || '1GbE', vlan: c.vlan || '', status: c.status || 'active', notes: c.notes || ''
    });
    setSaveError(null);
    setConnModal(true);
  };
  const saveConn = async (e) => {
    e.preventDefault();
    setSaving(true);
    setSaveError(null);
    const body = {
      ...connForm,
      from_id: connForm.from_id === '' ? null : parseInt(connForm.from_id, 10),
      to_id: connForm.to_id === '' ? null : parseInt(connForm.to_id, 10)
    };
    try {
      if (editConn) {
        await api.put(`/networking/connections/${editConn.id}`, body);
      } else {
        await api.post('/networking/connections', body);
      }
      setConnModal(false);
      loadConns();
    } catch (err) {
      setSaveError(err);
    } finally {
      setSaving(false);
    }
  };
  const deleteConn = async () => {
    if (!editConn) return;
    if (!window.confirm('Deze connectie verwijderen?')) return;
    setSaving(true);
    setSaveError(null);
    try {
      await api.del(`/networking/connections/${editConn.id}`);
      setConnModal(false);
      loadConns();
    } catch (err) {
      setSaveError(err);
    } finally {
      setSaving(false);
    }
  };

  const endpointLabel = (type, port) =>
    [CONN_TYPES[type] || type || '-', port].filter(Boolean).join(' · ');

  return (
    <div className="space-y-5 fade-in">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-xl font-bold tracking-tight">Netwerken</h1>
          <p className="text-[13px] text-muted mt-0.5">Netwerkdevices en connecties</p>
        </div>
        {tab === 'devices' ? (
          <Btn onClick={openDevNew}><Plus className="w-4 h-4" /> Nieuw device</Btn>
        ) : (
          <Btn onClick={openConnNew}><Plus className="w-4 h-4" /> Nieuwe connectie</Btn>
        )}
      </div>

      <TabBar
        tabs={[{ key: 'devices', label: 'Devices' }, { key: 'connections', label: 'Connecties' }]}
        active={tab}
        onChange={setTab}
      />

      {tab === 'devices' && (
        <Card padding={false}>
          <div className="p-4">
            {devError ? <ErrorBox error={devError} onRetry={loadDevices} /> : !devices ? <Spinner /> : (
              <Table
                columns={[
                  { label: 'Naam', render: d => <span className="font-medium flex items-center gap-2"><Network className="w-3.5 h-3.5 text-muted" />{d.name}</span> },
                  { label: 'Type', render: d => <Badge color="blue">{d.device_type}</Badge> },
                  { label: 'Cliënt', key: 'client_name' },
                  { label: 'Model', render: d => <span className="text-muted">{d.model || '-'}</span> },
                  { label: 'IP', render: d => <span className="text-muted">{d.ip_address || '-'}</span> },
                  { label: 'Mgmt IP', render: d => <span className="text-muted">{d.mgmt_ip || '-'}</span> },
                  { label: 'Poorten', render: d => d.ports_count ?? '-' },
                  { label: 'Status', render: d => <StatusBadge status={d.status} labels={STATUS_LABELS} /> }
                ]}
                rows={devices}
                keyFn={d => d.id}
                onRowClick={openDevEdit}
                empty={<div className="text-center text-muted text-[13px] py-8">Nog geen netwerkdevices</div>}
              />
            )}
          </div>
        </Card>
      )}

      {tab === 'connections' && (
        <Card padding={false}>
          <div className="p-4">
            {connError ? <ErrorBox error={connError} onRetry={loadConns} /> : !conns ? <Spinner /> : (
              <Table
                columns={[
                  { label: 'Naam', render: c => <span className="font-medium flex items-center gap-2"><Cable className="w-3.5 h-3.5 text-muted" />{c.name || '-'}</span> },
                  { label: 'Cliënt', key: 'client_name' },
                  { label: 'Van', render: c => endpointLabel(c.from_type, c.from_port) },
                  { label: 'Naar', render: c => endpointLabel(c.to_type, c.to_port) },
                  { label: 'Media', render: c => <Badge color="purple">{c.media_type || '-'}</Badge> },
                  { label: 'Snelheid', render: c => <span className="text-muted">{c.speed || '-'}</span> },
                  { label: 'VLAN', render: c => <span className="text-muted">{c.vlan || '-'}</span> },
                  { label: 'Status', render: c => <StatusBadge status={c.status} labels={STATUS_LABELS} /> }
                ]}
                rows={conns}
                keyFn={c => c.id}
                onRowClick={openConnEdit}
                empty={<div className="text-center text-muted text-[13px] py-8">Nog geen connecties</div>}
              />
            )}
          </div>
        </Card>
      )}

      {/* Device-modal */}
      <Modal open={devModal} onClose={() => setDevModal(false)} title={editDev ? 'Device bewerken' : 'Nieuw device'} wide>
        <form onSubmit={saveDev} className="space-y-3">
          {saveError && <ErrorBox error={saveError} />}
          <div className="grid grid-cols-2 gap-3">
            <Field label="Cliënt *">
              <select className={inputCls} value={devForm.client_id} onChange={e => setDevForm({ ...devForm, client_id: e.target.value })} required disabled={!!editDev}>
                <option value="">— Kies cliënt —</option>
                {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </Field>
            <Field label="Naam *">
              <input className={inputCls} value={devForm.name} onChange={e => setDevForm({ ...devForm, name: e.target.value })} required />
            </Field>
          </div>
          <div className="grid grid-cols-2 gap-3">
            <Field label="Type *">
              <select className={inputCls} value={devForm.device_type} onChange={e => setDevForm({ ...devForm, device_type: e.target.value })} required>
                {DEVICE_TYPES.map(t => <option key={t} value={t}>{t}</option>)}
              </select>
            </Field>
            <Field label="Model">
              <input className={inputCls} value={devForm.model} onChange={e => setDevForm({ ...devForm, model: e.target.value })} />
            </Field>
          </div>
          <div className="grid grid-cols-2 gap-3">
            <Field label="Fabrikant">
              <input className={inputCls} value={devForm.manufacturer} onChange={e => setDevForm({ ...devForm, manufacturer: e.target.value })} />
            </Field>
            <Field label="Aantal poorten">
              <input type="number" min="0" className={inputCls} value={devForm.ports_count} onChange={e => setDevForm({ ...devForm, ports_count: e.target.value })} />
            </Field>
          </div>
          <div className="grid grid-cols-2 gap-3">
            <Field label="IP-adres">
              <input className={inputCls} value={devForm.ip_address} onChange={e => setDevForm({ ...devForm, ip_address: e.target.value })} />
            </Field>
            <Field label="Mgmt IP">
              <input className={inputCls} value={devForm.mgmt_ip} onChange={e => setDevForm({ ...devForm, mgmt_ip: e.target.value })} />
            </Field>
          </div>
          <div className="grid grid-cols-2 gap-3">
            <Field label="OS-versie">
              <input className={inputCls} value={devForm.os_version} onChange={e => setDevForm({ ...devForm, os_version: e.target.value })} />
            </Field>
            <Field label="Status">
              <select className={inputCls} value={devForm.status} onChange={e => setDevForm({ ...devForm, status: e.target.value })}>
                <option value="active">Actief</option>
                <option value="standby">Standby</option>
                <option value="decommissioned">Uitgefaseerd</option>
              </select>
            </Field>
          </div>
          <Field label="Notities">
            <textarea rows={2} className={inputCls} value={devForm.notes} onChange={e => setDevForm({ ...devForm, notes: e.target.value })} />
          </Field>
          <div className="flex items-center justify-between gap-2 pt-1">
            <div>
              {editDev && (
                <Btn variant="danger" type="button" onClick={deleteDev} loading={saving}>
                  <Trash2 className="w-3.5 h-3.5" /> Verwijderen
                </Btn>
              )}
            </div>
            <div className="flex gap-2">
              <Btn variant="secondary" type="button" onClick={() => setDevModal(false)}>Annuleren</Btn>
              <Btn type="submit" loading={saving}>Opslaan</Btn>
            </div>
          </div>
        </form>
      </Modal>

      {/* Connectie-modal */}
      <Modal open={connModal} onClose={() => setConnModal(false)} title={editConn ? 'Connectie bewerken' : 'Nieuwe connectie'} wide>
        <form onSubmit={saveConn} className="space-y-3">
          {saveError && <ErrorBox error={saveError} />}
          <div className="grid grid-cols-2 gap-3">
            <Field label="Cliënt *">
              <select className={inputCls} value={connForm.client_id} onChange={e => setConnForm({ ...connForm, client_id: e.target.value })} required disabled={!!editConn}>
                <option value="">— Kies cliënt —</option>
                {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
            </Field>
            <Field label="Naam">
              <input className={inputCls} value={connForm.name} onChange={e => setConnForm({ ...connForm, name: e.target.value })} />
            </Field>
          </div>
          <div className="grid grid-cols-3 gap-3">
            <Field label="Van type *">
              <select className={inputCls} value={connForm.from_type} onChange={e => setConnForm({ ...connForm, from_type: e.target.value })} required>
                {Object.entries(CONN_TYPES).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
              </select>
            </Field>
            <Field label="Van ID">
              <input type="number" min="0" className={inputCls} value={connForm.from_id} onChange={e => setConnForm({ ...connForm, from_id: e.target.value })} />
            </Field>
            <Field label="Van poort">
              <input className={inputCls} placeholder="bijv. Gi0/1" value={connForm.from_port} onChange={e => setConnForm({ ...connForm, from_port: e.target.value })} />
            </Field>
          </div>
          <div className="grid grid-cols-3 gap-3">
            <Field label="Naar type *">
              <select className={inputCls} value={connForm.to_type} onChange={e => setConnForm({ ...connForm, to_type: e.target.value })} required>
                {Object.entries(CONN_TYPES).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
              </select>
            </Field>
            <Field label="Naar ID">
              <input type="number" min="0" className={inputCls} value={connForm.to_id} onChange={e => setConnForm({ ...connForm, to_id: e.target.value })} />
            </Field>
            <Field label="Naar poort">
              <input className={inputCls} placeholder="bijv. eth0" value={connForm.to_port} onChange={e => setConnForm({ ...connForm, to_port: e.target.value })} />
            </Field>
          </div>
          <div className="grid grid-cols-3 gap-3">
            <Field label="Mediatype">
              <select className={inputCls} value={connForm.media_type} onChange={e => setConnForm({ ...connForm, media_type: e.target.value })}>
                {MEDIA_TYPES.map(m => <option key={m} value={m}>{m}</option>)}
              </select>
            </Field>
            <Field label="Snelheid">
              <input className={inputCls} value={connForm.speed} onChange={e => setConnForm({ ...connForm, speed: e.target.value })} />
            </Field>
            <Field label="VLAN">
              <input className={inputCls} value={connForm.vlan} onChange={e => setConnForm({ ...connForm, vlan: e.target.value })} />
            </Field>
          </div>
          <Field label="Status">
            <select className={inputCls} value={connForm.status} onChange={e => setConnForm({ ...connForm, status: e.target.value })}>
              <option value="active">Actief</option>
              <option value="standby">Standby</option>
              <option value="decommissioned">Uitgefaseerd</option>
            </select>
          </Field>
          <Field label="Notities">
            <textarea rows={2} className={inputCls} value={connForm.notes} onChange={e => setConnForm({ ...connForm, notes: e.target.value })} />
          </Field>
          <div className="flex items-center justify-between gap-2 pt-1">
            <div>
              {editConn && (
                <Btn variant="danger" type="button" onClick={deleteConn} loading={saving}>
                  <Trash2 className="w-3.5 h-3.5" /> Verwijderen
                </Btn>
              )}
            </div>
            <div className="flex gap-2">
              <Btn variant="secondary" type="button" onClick={() => setConnModal(false)}>Annuleren</Btn>
              <Btn type="submit" loading={saving}>Opslaan</Btn>
            </div>
          </div>
        </form>
      </Modal>
    </div>
  );
}
