'use client';
import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { api } from '@/lib/api';
import { useAuth } from '@/lib/auth-context';
import { IconEdit, IconBan, IconActivate } from '@/components/ui';
import { FloatInput, FloatSelect } from '@/components/float';
import { DataTable, Pagination } from '@/components/data-table';
import { validate, v, Errors } from '@/lib/validation';
import { useDialog } from '@/components/dialog';

const EMPTY = {
  name: '', contact_email: '', status: 'active',
  max_stakeholders: '', max_employees: '', max_tickets: '', max_sub_tickets: '',
  smtp_host: '', smtp_port: '', smtp_user: '', smtp_pass: '', smtp_from_email: '', smtp_from_name: '',
  smtp_secure: false,
};

function useOrgForm(initial: any, onDone: () => void) {
  const { notify } = useDialog();
  const [form, setForm] = useState<any>(initial);
  const [errs, setErrs] = useState<Errors>({});
  const set = (k: string, v: any) => setForm((f: any) => ({ ...f, [k]: v }));
  const numOrNull = (v: string) => (v === '' ? null : Number(v));
  const submit = async (id?: number) => {
    const numOrNull = (vv: string) => (vv === '' ? null : Number(vv));
    const fe = validate({
      name: () => v.minLen(String(form.name ?? ''), 2, 'Name'),
      contact_email: () => v.optionalEmail(String(form.contact_email ?? ''), 'Contact email'),
      smtp_port: () => form.smtp_port === '' || form.smtp_port == null ? null
        : v.intRange(String(form.smtp_port), 1, 65535, 'SMTP port'),
      smtp_from_email: () => v.optionalEmail(String(form.smtp_from_email ?? ''), 'From email'),
    });
    setErrs(fe);
    if (Object.keys(fe).length) return;
    const payload = {
      name: form.name, contact_email: form.contact_email || null,
      status: form.status,
      limits: {
        max_stakeholders: numOrNull(form.max_stakeholders), max_employees: numOrNull(form.max_employees),
        max_tickets: numOrNull(form.max_tickets), max_sub_tickets: numOrNull(form.max_sub_tickets),
      },
      smtp: {
        smtp_host: form.smtp_host || null, smtp_port: form.smtp_port === '' ? null : Number(form.smtp_port),
        smtp_user: form.smtp_user || null,
        // empty password on edit = keep existing
        ...(form.smtp_pass ? { smtp_pass: form.smtp_pass } : {}),
        smtp_from_email: form.smtp_from_email || null, smtp_from_name: form.smtp_from_name || null,
        smtp_secure: !!form.smtp_secure,
      },
    };
    try {
      if (id) await api.patch(`/api/v1/super/organisations/${id}`, payload);
      else await api.post('/api/v1/super/organisations', payload);
      notify(id ? 'Organisation updated.' : 'Organisation created.', { tone: 'success' });
      onDone();
    } catch (e: any) { notify(e.message, { tone: 'error' }); }
  };
  return { form, set, submit, errs };
}

function OrgForm({ initial, submitLabel, onDone }: { initial: any; submitLabel: string; onDone: () => void }) {
  const { form, set, submit, errs } = useOrgForm(initial, onDone);
  const inp = (k: string, label: string, props: any = {}) => (
    <FloatInput label={label} id={`org-${k}`} value={form[k] ?? ''} onChange={(e) => set(k, e.target.value)} {...props} />
  );
  return (
    <div className="space-y-2">
      <div className="grid md:grid-cols-3 gap-2">
        {inp('name', 'Name', { required: true })}
        {inp('contact_email', 'Contact email', { capitalize: false })}
        <FloatSelect label="Status" id="org-status" value={form.status} onChange={(e) => set('status', e.target.value)}>
          <option value="active">Active</option><option value="suspended">Suspended</option>
        </FloatSelect>
      </div>
      <div className="grid md:grid-cols-4 gap-2">
        {inp('max_stakeholders', 'Stakeholders max', { type: 'number', min: 0 })}
        {inp('max_employees', 'Employees max', { type: 'number', min: 0 })}
        {inp('max_tickets', 'Deviations max', { type: 'number', min: 0 })}
        {inp('max_sub_tickets', 'CAPAs max', { type: 'number', min: 0 })}
      </div>
      <h3 className="font-medium text-sm pt-1">Organisation SMTP (blank = use super-admin global SMTP)</h3>
      <div className="grid md:grid-cols-3 gap-2">
        {inp('smtp_host', 'Host', { capitalize: false })}
        {inp('smtp_port', 'Port', { type: 'number' })}
        {inp('smtp_user', 'User', { capitalize: false })}
        <FloatInput label={`Password${initial?.id ? ' (blank = keep)' : ''}`} id="org-smtp-pass" type="password" autoComplete="new-password" value={form.smtp_pass ?? ''} onChange={(e) => set('smtp_pass', e.target.value)} />
        {inp('smtp_from_email', 'From email', { capitalize: false })}
        {inp('smtp_from_name', 'From name')}
      </div>
      <label className="text-sm flex gap-2 items-center">
        <input type="checkbox" checked={!!form.smtp_secure} onChange={(e) => set('smtp_secure', e.target.checked)} /> SMTP secure (TLS)
      </label>
      {Object.keys(errs).length > 0 && (
        <div role="alert" className="alert-error">
          {Object.entries(errs).map(([k, m]) => <p key={k} className="text-xs">{k}: {m as string}</p>)}
        </div>
      )}
      <button className="btn-primary text-sm btn-tall" onClick={() => submit(initial?.id)}>{submitLabel}</button>
    </div>
  );
}

function OrgLogo({ orgId, onDone }: { orgId: number; onDone: () => void }) {
  const { notify } = useDialog();
  const API = process.env.NEXT_PUBLIC_API_URL ?? '';
  return (
    <div className="flex flex-wrap gap-2 items-center border rounded-xl p-2">
      <img src={`${API}/api/v1/branding/logo/${orgId}`} alt="Organisation logo"
        className="max-h-12 max-w-[160px] object-contain rounded"
        onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }} />
      <label className="btn-ghost btn-sm cursor-pointer">Upload logo
        <input type="file" className="hidden" accept=".png,.jpg,.jpeg,.webp" onChange={async (e) => {
          const f = e.target.files?.[0]; if (!f) return;
          const fd = new FormData(); fd.append('file', f);
          try { await api.upload(`/api/v1/super/organisations/${orgId}/logo`, fd); notify('Logo uploaded.', { tone: 'success' }); }
          catch (ex: any) { notify(ex.message, { tone: 'error' }); }
          e.target.value = ''; onDone();
        }} />
      </label>
      <button className="btn-danger btn-sm" onClick={async () => {
        try { await api.del(`/api/v1/super/organisations/${orgId}/logo`); notify('Logo removed.', { tone: 'success' }); onDone(); }
        catch (ex: any) { notify(ex.message, { tone: 'error' }); }
      }}>Remove</button>
    </div>
  );
}

const PAGE_SIZE = 10;

export default function OrganisationsPage() {
  const { user } = useAuth();
  const { confirmDialog, notify } = useDialog();
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState('');
  const q = useQuery({
    queryKey: ['orgs', page, search],
    queryFn: () => api.get(`/api/v1/super/organisations?search=${encodeURIComponent(search)}&page=${page}&limit=${PAGE_SIZE}`),
    enabled: user?.role === 'super_admin',
  });
  const [showCreate, setShowCreate] = useState(false);
  const [editing, setEditing] = useState<any | null>(null);
  if (user?.role !== 'super_admin') return <p>Super admin only.</p>;
  const usage = (o: any, used: number, max: number | null) => `${used}${max != null ? ` / ${max}` : ' / ∞'}`;
  const rows: any[] = q.data?.data ?? [];
  return (
    <div className="space-y-3">
      <div className="flex items-center">
        <h1 className="page-title mr-auto">Organisations</h1>
        <button className="btn-primary text-sm" onClick={() => setShowCreate(v => !v)}>+ New Organisation</button>
      </div>
      {showCreate && <div className="card"><OrgForm initial={EMPTY} submitLabel="Create organisation" onDone={() => { setShowCreate(false); q.refetch(); }} /></div>}
      <DataTable
        caption="Organisations"
        rows={rows}
        keyOf={(o) => o.id}
        searchValue={search}
        onSearchChange={(v) => { setSearch(v); setPage(1); }}
        searchPlaceholder="Search organisations"
        empty={q.isLoading ? 'Loading…' : 'No organisations found.'}
        columns={[
          { header: 'Name', render: (o: any) => <b>{o.name}</b> },
          { header: 'Contact', render: (o: any) => <span className="whitespace-nowrap">{o.contact_email ?? '—'}</span> },
          { header: 'Status', render: (o: any) => <span className={`badge ${o.status === 'active' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'}`}>{o.status}</span> },
          {
            header: 'Usage', render: (o: any) => (
              <span className="text-xs whitespace-nowrap">
                Users {usage(o, o.used_stakeholders + o.used_employees, (o.max_stakeholders ?? 0) + (o.max_employees ?? 0))} ·
                Deviations {usage(o, o.used_tickets, o.max_tickets)} · CAPAs {usage(o, o.used_sub_tickets, o.max_sub_tickets)}
              </span>
            ),
          },
          { header: 'SMTP', render: (o: any) => <span className="text-xs">{o.smtp_host || 'global'}</span> },
          {
            header: 'Actions', render: (o: any) => (
              <span className="flex gap-1">
                <button type="button" className="btn-plain" aria-label={editing?.id === o.id ? 'Close editor' : `Edit ${o.name}`} title={editing?.id === o.id ? 'Close editor' : 'Edit'} onClick={() => setEditing(editing?.id === o.id ? null : o)}><IconEdit /></button>
                <button type="button" className="btn-plain" aria-label={o.status === 'active' ? `Suspend ${o.name}` : `Activate ${o.name}`} title={o.status === 'active' ? 'Suspend' : 'Activate'} onClick={async () => {
                  const to = o.status === 'active' ? 'suspended' : 'active';
                  if (!await confirmDialog(`${to === 'suspended' ? 'Suspend' : 'Activate'} ${o.name}?`, { title: `${to === 'suspended' ? 'Suspend' : 'Activate'} organisation`, confirmLabel: to === 'suspended' ? 'Suspend' : 'Activate' })) return;
                  try { await api.patch(`/api/v1/super/organisations/${o.id}`, { status: to }); q.refetch(); }
                  catch (e: any) { notify(e.message, { tone: 'error' }); }
                }}>{o.status === 'active' ? <IconBan /> : <IconActivate />}</button>
              </span>
            ),
          },
        ]}
      />
      <Pagination page={page} total={q.data?.total ?? 0} limit={PAGE_SIZE} onPage={setPage} />
      {editing && (
        <div className="card space-y-2">
          <h2 className="font-medium">Edit {editing.name}</h2>
          <OrgLogo orgId={editing.id} onDone={() => q.refetch()} />
          <OrgForm initial={{
            ...EMPTY, name: editing.name, contact_email: editing.contact_email ?? '', status: editing.status,
            max_stakeholders: editing.max_stakeholders ?? '', max_employees: editing.max_employees ?? '',
            max_tickets: editing.max_tickets ?? '', max_sub_tickets: editing.max_sub_tickets ?? '',
            smtp_host: editing.smtp_host ?? '', smtp_port: editing.smtp_port ?? '', smtp_user: editing.smtp_user ?? '', smtp_pass: '',
            smtp_from_email: editing.smtp_from_email ?? '', smtp_from_name: editing.smtp_from_name ?? '', smtp_secure: !!editing.smtp_secure,
            id: editing.id,
          }} submitLabel="Save changes" onDone={() => { setEditing(null); q.refetch(); }} />
        </div>
      )}
    </div>
  );
}
