import { useEffect, useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { Clock, Plus, FileText, Pencil, Trash2, Euro } from 'lucide-react';
import { api, qs, fmt } from '../api';
import { Card, KpiCard, Badge, Btn, Field, inputCls, Modal, Spinner, EmptyState, ErrorBox, Table } from '../components/ui';

const today = () => new Date().toISOString().split('T')[0];

const EMPTY_ENTRY = {
  client_id: '', engagement_id: '', date: '', hours: '',
  description: '', billable: true, hourly_rate: 150
};

function EntryModal({ open, onClose, entry, clients, engagements, onSaved }) {
  const [form, setForm] = useState(EMPTY_ENTRY);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    if (!open) return;
    setError(null);
    setForm(entry ? {
      client_id: entry.client_id || '',
      engagement_id: entry.engagement_id || '',
      date: entry.date || today(),
      hours: entry.hours ?? '',
      description: entry.description || '',
      billable: !!entry.billable,
      hourly_rate: entry.hourly_rate ?? 150
    } : { ...EMPTY_ENTRY, date: today() });
  }, [open, entry]);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const clientEngagements = form.client_id
    ? engagements.filter(e => String(e.client_id) === String(form.client_id))
    : [];

  const submit = async (e) => {
    e.preventDefault();
    setSaving(true);
    setError(null);
    try {
      const body = { ...form, client_id: form.client_id || null, engagement_id: form.engagement_id || null };
      if (entry) await api.put(`/time/${entry.id}`, body);
      else await api.post('/time', body);
      onSaved();
      onClose();
    } catch (err) {
      setError(err);
    } finally {
      setSaving(false);
    }
  };

  return (
    <Modal open={open} onClose={onClose} title={entry ? 'Uren bewerken' : 'Uren toevoegen'}>
      <form onSubmit={submit} className="space-y-4">
        <ErrorBox error={error} />
        <div className="grid grid-cols-2 gap-3">
          <Field label="Cliënt">
            <select className={inputCls} value={form.client_id} onChange={e => setForm(f => ({ ...f, client_id: e.target.value, engagement_id: '' }))}>
              <option value="">— Geen —</option>
              {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
          </Field>
          <Field label="Engagement">
            <select
              className={`${inputCls} disabled:opacity-50`}
              value={form.engagement_id}
              onChange={e => set('engagement_id', e.target.value)}
              disabled={!form.client_id}
            >
              <option value="">— Geen —</option>
              {clientEngagements.map(e => <option key={e.id} value={e.id}>{e.title} — {e.client_name}</option>)}
            </select>
          </Field>
        </div>
        <div className="grid grid-cols-2 gap-3">
          <Field label="Datum *">
            <input type="date" required className={inputCls} value={form.date} onChange={e => set('date', e.target.value)} />
          </Field>
          <Field label="Uren *">
            <input type="number" required step="0.25" min="0" className={inputCls} value={form.hours} onChange={e => set('hours', e.target.value)} placeholder="bijv. 2.5" />
          </Field>
        </div>
        <Field label="Omschrijving">
          <textarea className={inputCls} rows={2} value={form.description} onChange={e => set('description', e.target.value)} placeholder="Wat heb je gedaan?" />
        </Field>
        <div className="grid grid-cols-2 gap-3 items-end">
          <Field label="Uurtarief">
            <input type="number" step="0.01" min="0" className={inputCls} value={form.hourly_rate} onChange={e => set('hourly_rate', e.target.value)} />
          </Field>
          <label className="flex items-center gap-2 pb-2 cursor-pointer">
            <input type="checkbox" className="w-4 h-4 accent-accent" checked={form.billable} onChange={e => set('billable', e.target.checked)} />
            <span className="text-[13px]">Facturabel</span>
          </label>
        </div>
        <div className="flex justify-end gap-2 pt-1">
          <Btn type="button" variant="secondary" onClick={onClose}>Annuleren</Btn>
          <Btn type="submit" loading={saving}>{entry ? 'Opslaan' : 'Toevoegen'}</Btn>
        </div>
      </form>
    </Modal>
  );
}

function InvoiceModal({ open, onClose, clients }) {
  const [form, setForm] = useState({ client_id: '', date_from: '', date_to: '' });
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState(null);
  const [created, setCreated] = useState(null);

  useEffect(() => {
    if (!open) return;
    setForm({ client_id: '', date_from: '', date_to: '' });
    setError(null);
    setCreated(null);
  }, [open]);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  const submit = async (e) => {
    e.preventDefault();
    setSaving(true);
    setError(null);
    try {
      const res = await api.post('/time/create-invoice', {
        client_id: form.client_id,
        date_from: form.date_from || undefined,
        date_to: form.date_to || undefined
      });
      setCreated(res);
    } catch (err) {
      setError(err);
    } finally {
      setSaving(false);
    }
  };

  return (
    <Modal open={open} onClose={onClose} title="Factuur maken uit uren">
      {created ? (
        <div className="space-y-4">
          <div className="bg-green/10 border border-green/30 rounded-lg px-4 py-3 text-[13px] text-green">
            Factuur <span className="font-semibold">{created.number}</span> is aangemaakt uit de facturabele uren.
          </div>
          <div className="flex justify-end gap-2">
            <Btn variant="secondary" onClick={onClose}>Sluiten</Btn>
            <Link to={`/invoices/${created.id}`}>
              <Btn>Bekijk factuur</Btn>
            </Link>
          </div>
        </div>
      ) : (
        <form onSubmit={submit} className="space-y-4">
          <ErrorBox error={error} />
          <Field label="Cliënt *">
            <select required className={inputCls} value={form.client_id} onChange={e => set('client_id', e.target.value)}>
              <option value="">— Kies een cliënt —</option>
              {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
          </Field>
          <div className="grid grid-cols-2 gap-3">
            <Field label="Van datum">
              <input type="date" className={inputCls} value={form.date_from} onChange={e => set('date_from', e.target.value)} />
            </Field>
            <Field label="Tot datum">
              <input type="date" className={inputCls} value={form.date_to} onChange={e => set('date_to', e.target.value)} />
            </Field>
          </div>
          <p className="text-[12px] text-muted">Alle facturabele uren van deze cliënt (binnen de periode) worden op één conceptfactuur gezet.</p>
          <div className="flex justify-end gap-2 pt-1">
            <Btn type="button" variant="secondary" onClick={onClose}>Annuleren</Btn>
            <Btn type="submit" loading={saving}>Factuur maken</Btn>
          </div>
        </form>
      )}
    </Modal>
  );
}

export default function Time() {
  const [data, setData] = useState(null);
  const [clients, setClients] = useState([]);
  const [engagements, setEngagements] = useState([]);
  const [error, setError] = useState(null);
  const [filters, setFilters] = useState({ client_id: '', date_from: '', date_to: '' });
  const [entryModal, setEntryModal] = useState({ open: false, entry: null });
  const [invoiceOpen, setInvoiceOpen] = useState(false);

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

  const load = () => {
    setError(null);
    api.get('/time' + qs(filters)).then(setData).catch(setError);
  };
  useEffect(load, [filters]);

  const estimatedValue = useMemo(() => {
    if (!data) return 0;
    return data.entries
      .filter(e => e.billable)
      .reduce((s, e) => s + e.hours * (e.hourly_rate || 0), 0);
  }, [data]);

  const remove = async (entry) => {
    if (!window.confirm(`${fmt.hours(entry.hours)} op ${fmt.date(entry.date)} verwijderen?`)) return;
    try {
      await api.del(`/time/${entry.id}`);
      load();
    } catch (err) {
      alert(err.message);
    }
  };

  const setFilter = (k, v) => setFilters(f => ({ ...f, [k]: v }));

  return (
    <div className="space-y-5 fade-in">
      <div className="flex items-center justify-between flex-wrap gap-3">
        <div>
          <h1 className="text-xl font-bold tracking-tight">Urenregistratie</h1>
          <p className="text-[13px] text-muted mt-0.5">Registreer en factureer je gewerkte uren</p>
        </div>
        <div className="flex items-center gap-2">
          <Btn variant="secondary" onClick={() => setInvoiceOpen(true)}>
            <FileText className="w-3.5 h-3.5" /> Factuur maken uit uren
          </Btn>
          <Btn onClick={() => setEntryModal({ open: true, entry: null })}>
            <Plus className="w-3.5 h-3.5" /> Uren toevoegen
          </Btn>
        </div>
      </div>

      {error ? (
        <ErrorBox error={error} onRetry={load} />
      ) : !data ? (
        <Spinner />
      ) : (
        <>
          <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
            <KpiCard icon={Clock} label="Totaal uren" value={fmt.hours(data.totalHours)} color="blue" />
            <KpiCard icon={Clock} label="Facturabel" value={fmt.hours(data.billableHours)} color="green" />
            <KpiCard icon={Clock} label="Niet-facturabel" value={fmt.hours(data.totalHours - data.billableHours)} color="yellow" />
            <KpiCard icon={Euro} label="Geschatte waarde" value={fmt.euro(estimatedValue)} sub="facturabele uren × tarief" color="accent" />
          </div>

          <Card>
            <div className="flex items-center gap-2 flex-wrap mb-4">
              <select className={`${inputCls} !w-auto`} value={filters.client_id} onChange={e => setFilter('client_id', e.target.value)}>
                <option value="">Alle cliënten</option>
                {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
              </select>
              <input type="date" className={`${inputCls} !w-auto`} value={filters.date_from} onChange={e => setFilter('date_from', e.target.value)} title="Van datum" />
              <span className="text-muted text-[12px]">t/m</span>
              <input type="date" className={`${inputCls} !w-auto`} value={filters.date_to} onChange={e => setFilter('date_to', e.target.value)} title="Tot datum" />
              {(filters.client_id || filters.date_from || filters.date_to) && (
                <Btn variant="ghost" size="sm" onClick={() => setFilters({ client_id: '', date_from: '', date_to: '' })}>Filters wissen</Btn>
              )}
            </div>

            <Table
              columns={[
                { label: 'Datum', render: r => <span className="text-muted">{fmt.date(r.date)}</span> },
                { label: 'Cliënt', render: r => r.client_name || '-' },
                { label: 'Engagement', render: r => r.engagement_title || '-' },
                { label: 'Omschrijving', render: r => <span className="text-muted">{r.description || '-'}</span> },
                { label: 'Uren', render: r => fmt.hours(r.hours) },
                { label: 'Tarief', render: r => fmt.euro(r.hourly_rate) },
                { label: 'Facturabel', render: r => r.billable ? <Badge color="green">Ja</Badge> : <Badge color="muted">Nee</Badge> },
                { label: 'Gebruiker', render: r => <span className="text-muted">{r.username || '-'}</span> },
                {
                  label: 'Acties', render: r => (
                    <div className="flex items-center gap-1">
                      <button onClick={() => setEntryModal({ open: true, entry: r })} className="p-1.5 rounded-md text-muted hover:text-text hover:bg-bg-soft" title="Bewerken">
                        <Pencil className="w-3.5 h-3.5" />
                      </button>
                      <button onClick={() => remove(r)} className="p-1.5 rounded-md text-muted hover:text-red hover:bg-red/10" title="Verwijderen">
                        <Trash2 className="w-3.5 h-3.5" />
                      </button>
                    </div>
                  )
                }
              ]}
              rows={data.entries}
              keyFn={r => r.id}
              empty={<EmptyState icon={Clock} title="Geen uren gevonden" hint="Voeg je eerste tijdregistratie toe of pas de filters aan." />}
            />
          </Card>
        </>
      )}

      <EntryModal
        open={entryModal.open}
        entry={entryModal.entry}
        clients={clients}
        engagements={engagements}
        onClose={() => setEntryModal({ open: false, entry: null })}
        onSaved={load}
      />
      <InvoiceModal open={invoiceOpen} onClose={() => { setInvoiceOpen(false); load(); }} clients={clients} />
    </div>
  );
}
