'use client';
import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import type { PayrollExport, PayrollExportInput } from '@alqove/api-client';
import { formatPrice } from '@alqove/shared';
import { api } from '@/lib/api';
import { captureCommandGeneration, requireCommandGeneration, useSelectedMembership } from '@/lib/stores/store-context';
import { useStableCommand, useTimekeepingGuard, timekeepingError } from '@/hooks/use-timekeeping';
import { useScheduleSettings } from '@/lib/queries/use-scheduling';
import { addDays } from '../schedule/schedule-time';
const button = 'rounded border px-4 py-3 disabled:opacity-50';

export function PayrollClient() {
  const member = useSelectedMembership();
  if (!member?.capabilities.includes('payroll.export')) return <p>You do not have access to payroll exports for this store.</p>;
  return <StorePayroll key={member.store_id} store={member.store_id} />;
}
function StorePayroll({ store }: { store: string }) {
  const guard = useTimekeepingGuard(store, 'payroll.export');
  const settings = useScheduleSettings(store);
  const history = useQuery({ queryKey: ['timekeeping', store, 'exports'], queryFn: () => api.timekeeping.payroll.list(store) });
  const [first, setFirst] = useState('');
  const [last, setLast] = useState('');
  const [localError, setLocalError] = useState('');
  const [submitted, setSubmitted] = useState<PayrollExportInput | null>(null);
  const [acknowledge, setAcknowledge] = useState(false);
  const [downloading, setDownloading] = useState<string | null>(null);
  const command = useStableCommand<PayrollExportInput>((input, key) => api.timekeeping.payroll.create(store, input, key), () => history.refetch(), guard);
  const needsAcknowledgement = !!(command.error && typeof command.error === 'object' && 'errors' in command.error && (command.error.errors as Record<string, unknown>)?.oversized_sessions);
  async function download(item: PayrollExport) {
    if (!guard.current()) return;
    const generation = captureCommandGeneration();
    setDownloading(item.id); setLocalError('');
    let url: string | undefined;
    const anchor = document.createElement('a');
    try {
      const blob = await api.timekeeping.payroll.download(store, item.id);
      requireCommandGeneration(generation);
      if (!guard.current()) return;
      url = URL.createObjectURL(blob); anchor.href = url; anchor.download = item.filename;
      document.body.appendChild(anchor); anchor.click();
    } catch (e) { if (guard.current()) setLocalError(timekeepingError(e)); }
    finally { anchor.remove(); if (url) URL.revokeObjectURL(url); if (guard.current()) setDownloading(null); }
  }
  function submit() {
    try {
      guard.assert();
      if (!first || !last || first > last) throw new Error('Choose a first and last week in chronological order.');
      const startDay = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'].indexOf(settings.data!.data.work_week_start_day);
      if (new Date(`${first}T12:00:00Z`).getUTCDay() !== startDay || new Date(`${last}T12:00:00Z`).getUTCDay() !== startDay) throw new Error(`Week starts must be ${settings.data!.data.work_week_start_day}.`);
      const weeks = []; for (let date = first; date <= last; date = addDays(date, 7)) { if (weeks.length >= 26) throw new Error('Choose no more than 26 weeks per export.'); weeks.push(date); }
      const input = { week_starts: weeks, acknowledge_oversized_sessions: false };
      setLocalError(''); setAcknowledge(false); setSubmitted(input); void command.run(input);
    } catch (e) { setLocalError(timekeepingError(e)); }
  }
  return <section className="space-y-5 p-4"><h1 className="text-2xl font-semibold">Payroll</h1>
    <p>Create an immutable CSV snapshot of approved timesheets. Download previous exports without exporting again.</p>
    {settings.data && <p>Weeks begin {settings.data.data.work_week_start_day} at {settings.data.data.work_week_start_time} · {settings.data.data.timezone}</p>}
    <form className="flex flex-wrap items-end gap-4" onSubmit={e => { e.preventDefault(); submit(); }}>
      <label>First week start <input type="date" className={button} required value={first} disabled={command.busy || command.retryable || needsAcknowledgement} onChange={e => setFirst(e.target.value)} /></label>
      <label>Last week start <input type="date" className={button} required value={last} disabled={command.busy || command.retryable || needsAcknowledgement} onChange={e => setLast(e.target.value)} /></label>
      <button className={button} disabled={command.busy || command.retryable || needsAcknowledgement || !settings.data}>Create CSV export</button>
    </form>
    {(localError || command.error != null || settings.error || history.error) && <p role="alert">{localError || timekeepingError(command.error ?? settings.error ?? history.error)}</p>}
    {needsAcknowledgement && <div className="space-y-3 rounded border p-4"><label className="block"><input type="checkbox" checked={acknowledge} onChange={e => setAcknowledge(e.target.checked)} /> I reviewed the oversized sessions and acknowledge them.</label><button className={button} disabled={command.busy || !acknowledge || !submitted} onClick={() => { if (submitted) { const input = { ...submitted, acknowledge_oversized_sessions: true }; setSubmitted(input); void command.run(input); } }}>Acknowledge and export</button></div>}
    {command.retryable && !needsAcknowledgement && <button className={button} disabled={command.busy} onClick={() => command.run()}>Retry same export</button>}
    <h2 className="text-xl font-semibold">Export history</h2>
    {history.isPending && <p role="status">Loading export history…</p>}
    {history.data?.data.length === 0 && <p>No exports yet.</p>}
    <div className="overflow-x-auto"><table className="w-full text-left"><caption className="sr-only">Payroll export history</caption><thead><tr><th>File</th><th>Weeks</th><th>Total minutes</th><th>Total pay</th><th>Download</th></tr></thead><tbody>{history.data?.data.map(item => <tr key={item.id} className="border-t"><td className="py-3">{item.filename}</td><td>{item.week_starts.join(', ')}</td><td>{item.total_minutes}</td><td>{item.total_pay_cents == null ? 'Unavailable — missing pay rate' : formatPrice(item.total_pay_cents)}</td><td><button className={button} disabled={downloading !== null} onClick={() => download(item)}>Download {item.filename}</button></td></tr>)}</tbody></table></div>
    <button className={button} onClick={() => history.refetch()} disabled={history.isFetching}>Refresh export history</button>
  </section>;
}
