'use client';
import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import Link from 'next/link';
import { api } from '@/lib/api';
import { useAuth } from '@/lib/auth-context';
import { EmployeePicker, CategoryPicker, DepartmentPicker } from '@/components/pickers';
import { Importer } from '@/components/importer';
import { StatusBadge, STATUSES, IconTrash, IconEdit, IconClose, CopyButton } from '@/components/ui';
import { DataTable, Pagination } from '@/components/data-table';
import { FloatInput, FloatSelect, FloatArea } from '@/components/float';
import { DatePicker } from '@/components/date-picker';
import { formatDate } from '@/lib/format';
import { validate, v, Errors } from '@/lib/validation';
import { useDialog } from '@/components/dialog';
import { AttachmentComposer, useStagedAttachments, uploadStaged, linkRowErrors } from '@/components/attachments';
import { useCan } from '@/lib/permissions';

const PAGE_SIZE = 10;

export default function ActionsPage() {
  const { user } = useAuth();
  const { confirmDialog, notify } = useDialog();
  const canDelete = useCan('deviation', 'delete');
  const [search, setSearch] = useState('');
  const [status, setStatus] = useState('');
  const [dept, setDept] = useState<number | null>(null);
  const [assignee, setAssignee] = useState<number | null>(null);
  const [from, setFrom] = useState('');
  const [to, setTo] = useState('');
  const [page, setPage] = useState(1);
  const [showForm, setShowForm] = useState(false);
  const [showImport, setShowImport] = useState(false);
  const resetFilters = () => { setStatus(''); setDept(null); setAssignee(null); setFrom(''); setTo(''); setSearch(''); setPage(1); };
  const q = useQuery({
    queryKey: ['actions', search, status, dept, assignee, from, to, page],
    queryFn: () => api.get(`/api/v1/actions?search=${encodeURIComponent(search)}${status ? `&status=${status}` : ''}${dept ? `&department_id=${dept}` : ''}${assignee ? `&employee_id=${assignee}` : ''}${from ? `&from=${from}` : ''}${to ? `&to=${to}` : ''}&page=${page}&limit=${PAGE_SIZE}`),
  });
  const canCreate = useCan('deviation', 'create');
  const rows: any[] = q.data?.data ?? [];
  const total: number = q.data?.total ?? 0;
  return (
    <div className="space-y-3">
      <div className="flex flex-wrap gap-2 items-center">
        <h1 className="page-title mr-auto">Deviations</h1>
        {canCreate && <button className="btn-ghost text-sm" onClick={() => { setShowImport(v => !v); setShowForm(false); }}>Bulk import</button>}
        {canCreate && (showForm
          ? <button className="btn-ghost btn-icon" aria-label="Close deviation form" title="Close" onClick={() => setShowForm(false)}><IconClose /></button>
          : <button className="btn-primary" onClick={() => setShowForm(true)}>+ New Deviation</button>)}
      </div>
      {showForm && <ActionForm onDone={() => { setShowForm(false); q.refetch(); }} />}
      {canCreate && showImport && !showForm && <Importer kind="actions" label="deviations" onDone={() => q.refetch()} />}
      <div className="grid grid-cols-2 md:grid-cols-4 xl:grid-cols-8 gap-2 items-start">
        <FloatSelect label="Status" id="af-fstatus" value={status} onChange={(e) => { setStatus(e.target.value); setPage(1); }}>
          <option value="">All statuses</option>
          {STATUSES.map(s => <option key={s}>{s}</option>)}
        </FloatSelect>
        <DepartmentPicker value={dept} noneLabel="All departments" onChange={(v) => { setDept(v); setPage(1); }} />
        <EmployeePicker value={assignee} onChange={(v) => { setAssignee(v); setPage(1); }} label="Employee" />
        <DatePicker label="Target from" id="af-from" value={from} onChange={(v) => { setFrom(v); setPage(1); }} />
        <DatePicker label="Target to" id="af-to" value={to} onChange={(v) => { setTo(v); setPage(1); }} />
        <input
          className="input h-14 text-sm w-full md:col-span-2 xl:col-span-2"
          type="search"
          placeholder="Search reference / name"
          aria-label="Search reference / name"
          value={search}
          onChange={(e) => { setSearch(e.target.value); setPage(1); }}
        />
        <button className="btn-ghost text-sm btn-tall w-full" onClick={resetFilters}>Clear</button>
      </div>
      <DataTable
        caption="Deviations"
        rows={rows}
        keyOf={(a) => a.id}
        searchValue={search}
        onSearchChange={(v) => { setSearch(v); setPage(1); }}
        searchPlaceholder="Search reference / name"
        hideSearch
        empty={q.isLoading ? 'Loading…' : 'No deviations found.'}
        columns={[
          { header: 'Reference', render: (a: any) => <Link className="font-mono text-xs no-underline hover:underline whitespace-nowrap" href={`/actions/${a.id}`}>{a.reference_number}</Link> },
          { header: 'Title', render: (a: any) => <Link className="font-medium hover:underline" href={`/actions/${a.id}`}>{a.title}</Link> },
          { header: 'Status', render: (a: any) => <StatusBadge status={a.computed_overdue ? 'Overdue' : a.status} /> },
          { header: 'Priority', render: (a: any) => <span className="badge bg-slate-100 whitespace-nowrap">{a.priority}</span> },
          { header: 'Due', render: (a: any) => <span className="whitespace-nowrap">{formatDate(a.target_date)}</span> },
          { header: 'CAPAs', render: (a: any) => <span className="whitespace-nowrap">{a.sub_done}/{a.sub_total}</span> },
          { header: 'Assignee', render: (a: any) => a.assignee_name ?? 'Unassigned' },
          { header: 'Department', render: (a: any) => a.department_name ?? '—' },
          {
            header: 'Actions', render: (a: any) => (
              <span className="flex gap-1">
                <Link className="btn-plain" aria-label={`Edit ${a.reference_number}`} title="Open deviation" href={`/actions/${a.id}`}><IconEdit /></Link>
                <CopyButton url={typeof window !== 'undefined' ? `${window.location.origin}/actions/${a.id}` : `/actions/${a.id}`} label={a.reference_number} />
                {canDelete && (
                  <button type="button" className="btn-plain" aria-label={`Delete ${a.reference_number}`} title="Delete deviation" onClick={async () => {
                    if (!await confirmDialog(`Delete deviation ${a.reference_number}? Its CAPAs go with it.`, { title: 'Delete deviation', confirmLabel: 'Delete' })) return;
                    try { await api.del(`/api/v1/actions/${a.id}`); notify('Deviation deleted.', { tone: 'success' }); q.refetch(); }
                    catch (e: any) { notify(e.message, { tone: 'error' }); }
                  }}><IconTrash /></button>
                )}
              </span>
            ),
          },
        ]}
      />
      <Pagination page={page} total={total} limit={PAGE_SIZE} onPage={setPage} />
    </div>
  );
}

function ActionForm({ onDone }: { onDone: () => void }) {
  const { notify } = useDialog();
  const [form, setForm] = useState({ title: '', description: '', requirement: '', target_date: '', priority: 'Low', reminder_lead_days: '2' });
  const [assignee, setAssignee] = useState<number | null>(null);
  const [category, setCategory] = useState<number | null>(null);
  const [errs, setErrs] = useState<Errors>({});
  // Staged attachments: chosen now, uploaded automatically once the deviation exists.
  const staged = useStagedAttachments();
  const [busy, setBusy] = useState(false);
  const set = (k: string, v: string) => setForm(f => ({ ...f, [k]: v }));
  return (
    <form className="card space-y-2 !mt-6" noValidate onSubmit={async (e) => {
      e.preventDefault();
      const fe = validate({
        title: () => v.minLen(form.title, 3, 'Deviation title'),
        target_date: () => v.todayOrFuture(form.target_date, 'Target date'),
        category: () => (!category ? 'Category is required' : null),
        assignee: () => (!assignee ? 'Assignee is required' : null),
        reminder_lead_days: () => v.intRange(form.reminder_lead_days, 0, 90, 'Remind days', false),
      });
      setErrs(fe);
      if (Object.keys(fe).length) return;
      const linkErrs = linkRowErrors(staged.links);
      if (linkErrs.length) { notify(linkErrs.join('\n'), { tone: 'error' }); return; }
      setBusy(true);
      try {
        const created: any = await api.post('/api/v1/actions', {
          title: form.title, description: form.description, requirement: form.requirement || null,
          target_date: form.target_date,
          priority: form.priority, assigned_employee_id: assignee,
          category_id: category,
          reminder_lead_days: form.reminder_lead_days === '' ? null : Number(form.reminder_lead_days),
        });
        const failed = await uploadStaged({ action_id: created.id }, staged.files, staged.complete);
        if (failed.length) notify(`Deviation created, but some attachments failed:\n${failed.join('\n')}`, { title: 'Created with warnings', tone: 'error' });
        else notify(`Deviation created${staged.count ? ` with ${staged.count} attachment${staged.count === 1 ? '' : 's'}` : ''}.`, { tone: 'success' });
        onDone();
      } catch (ex: any) { notify(ex.message, { tone: 'error' }); }
      finally { setBusy(false); }
    }}>
      <FloatInput label="Deviation Name" id="af-title" required error={errs.title} value={form.title} onChange={(e) => set('title', e.target.value)} />
      <FloatArea label="Description" id="af-desc" rows={2} value={form.description} onChange={(e) => set('description', e.target.value)} />
      <FloatArea label="Requirement / Additional Notes" id="af-req" rows={2} value={form.requirement} onChange={(e) => set('requirement', e.target.value)} />
      <div className="grid grid-cols-2 md:grid-cols-4 gap-2">
        <DatePicker label="Target Date" id="af-target" required error={errs.target_date} value={form.target_date} onChange={(val) => set('target_date', val)} min={new Date().toISOString().slice(0, 10)} />
        <FloatSelect label="Priority" id="af-priority" value={form.priority} onChange={(e) => set('priority', e.target.value)}>
          <option>Low</option><option>Medium</option><option>High</option><option>Critical</option>
        </FloatSelect>
        <FloatInput label="Reminds before nᵗʰ days" id="af-remind" type="number" min={0} max={90} title="Remind employee N days before target" error={errs.reminder_lead_days} value={form.reminder_lead_days} onChange={(e) => set('reminder_lead_days', e.target.value)} />
        <EmployeePicker value={assignee} onChange={setAssignee} />
        <CategoryPicker type="action" value={category} onChange={setCategory} />
      </div>
      {(errs.category || errs.assignee) && <p role="alert" className="field-error">{errs.category ?? errs.assignee}</p>}
      <div className="border rounded-xl p-3 space-y-2">
        <p className="font-medium text-sm">Attachments (Optional)</p>
        <AttachmentComposer idPrefix="af" files={staged.files} setFiles={staged.setFiles} links={staged.links} setLinks={staged.setLinks} />
      </div>
      <button className="btn-primary btn-tall" disabled={busy}>{busy ? 'Creating…' : 'Create Deviation'}</button>
    </form>
  );
}
