'use client';

import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useT } from '@/lib/i18n/react';
import { getCsrfToken } from '@/lib/csrf';
import { Button } from '@/components/ui/primitives/Button';
import { Badge } from '@/components/ui/primitives/Badge/Badge';
import { Input } from '@/components/ui/primitives/Input';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { Table } from '@/components/ui/primitives/Table';
import { TableSkeleton } from '@/components/ui/feedback/Skeleton';
import { toIsraelDateString } from '@/lib/datetime';
import { formatDate } from '@/lib/format';
import { captureCaught } from '@/lib/observability';
import { HydratedIsland } from '@/components/HydratedIsland';
import type { core } from 'zod';
import { QueryBoundary } from '@platform-modules/ui-primitives';

type VatScheduleEntry = {
  effectiveDateIl: string;
  ratePercent: number;
  addedBy: string;
  addedAt: string;
};

type PostVatError = {
  errorCode?: string;
  issues?: core.$ZodIssue[];
  duplicateDate?: string;
};

async function fetchSchedule() {
  const res = await fetch('/api/admin/vat-rates');
  if (!res.ok) throw new Error('fetch failed');
  const json = (await res.json()) as { data: { schedule: VatScheduleEntry[] } };
  return json.data.schedule;
}

async function postVatEntry(body: { effectiveDateIl: string; ratePercent: number }) {
  const res = await fetch('/api/admin/vat-rates', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-csrf-token': getCsrfToken(),
    },
    body: JSON.stringify(body),
  });
  const json = (await res.json().catch((err) => {
    captureCaught(err, { scope: 'VatRatesAdmin.post.parse-error' });
    return {};
  })) as {
    data?: { schedule: VatScheduleEntry[] };
    code?: string;
    issues?: core.$ZodIssue[];
    error?: string;
  };

  if (!res.ok) {
    const err = new Error('post failed') as Error & PostVatError;
    if (res.status === 422 && json.issues?.length) {
      err.errorCode = 'validation';
      err.issues = json.issues;
    } else if (json.code === 'DUPLICATE_DATE') {
      err.errorCode = 'duplicate_date';
      err.duplicateDate = body.effectiveDateIl;
    }
    throw err;
  }

  return json.data!;
}

function VatRatesAdminInner() {
  const t = useT('admin_vat_rates');
  const tCommon = useT('common');
  const qc = useQueryClient();
  const [dateInput, setDateInput] = useState('');
  const [rateInput, setRateInput] = useState<number | ''>('');
  const [dateError, setDateError] = useState<string | null>(null);
  const [rateError, setRateError] = useState<string | null>(null);
  const [formError, setFormError] = useState<string | null>(null);

  const vatRatesQuery = useQuery({
    queryKey: ['admin', 'vat-rates'],
    queryFn: fetchSchedule,
  });

  const addMutation = useMutation({
    mutationFn: postVatEntry,
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['admin', 'vat-rates'] });
      setDateInput('');
      setRateInput('');
      setDateError(null);
      setRateError(null);
      setFormError(null);
    },
    onError: (err: unknown) => {
      const e = err as PostVatError;
      setDateError(null);
      setRateError(null);
      setFormError(null);

      if (e.errorCode === 'validation' && e.issues?.length) {
        for (const issue of e.issues) {
          const field = issue.path[0];
          if (field === 'ratePercent') {
            setRateError(t('error_validation'));
          } else if (field === 'effectiveDateIl') {
            setDateError(t('error_validation'));
          }
        }
        if (
          !e.issues.some(
            (issue) => issue.path[0] === 'ratePercent' || issue.path[0] === 'effectiveDateIl',
          )
        ) {
          setFormError(t('error_validation'));
        }
        return;
      }

      if (e.errorCode === 'duplicate_date') {
        setDateError(t('error_duplicate').replace('{date}', e.duplicateDate ?? dateInput));
        return;
      }

      setFormError(t('error_generic'));
    },
  });

  const todayIl = toIsraelDateString(new Date());

  function handleSubmit(e: React.SyntheticEvent<HTMLFormElement>) {
    e.preventDefault();
    setDateError(null);
    setRateError(null);
    setFormError(null);
    if (rateInput === '') {
      setRateError(t('error_validation'));
      return;
    }
    addMutation.mutate({
      effectiveDateIl: dateInput,
      ratePercent: rateInput,
    });
  }

  return (
    <div className="space-y-8">
      {/* History table */}
      <section>
        <h2 className="mb-4 text-lg font-semibold">{t('history_heading')}</h2>
        <QueryBoundary
          query={vatRatesQuery}
          skeleton={<TableSkeleton rows={4} cols={4} />}
          errorFallback={(retry) => (
            <ErrorState
              title={tCommon('error_loading')}
              action={
                <Button variant="secondary" size="sm" onClick={() => void retry()}>
                  {tCommon('retry')}
                </Button>
              }
            />
          )}
        >
          {(resolvedSchedule) => {
            const resolvedSortedAsc = [...resolvedSchedule].sort((a, b) =>
              a.effectiveDateIl.localeCompare(b.effectiveDateIl),
            );
            const resolvedCurrentEntry = resolvedSortedAsc
              .filter((entry) => entry.effectiveDateIl <= todayIl)
              .at(-1);
            const resolvedSortedDesc = [...resolvedSortedAsc].reverse();

            return resolvedSortedDesc.length === 0 ? (
              <p className="text-text-muted text-sm">{t('empty_state')}</p>
            ) : (
              <Table>
                <Table.Head>
                  <Table.Row className="border-b">
                    <Table.HeadCell className="text-text-muted py-2 pe-4 font-medium">
                      {t('col_date')}
                    </Table.HeadCell>
                    <Table.HeadCell className="text-text-muted py-2 pe-4 font-medium">
                      {t('col_rate')}
                    </Table.HeadCell>
                    <Table.HeadCell className="text-text-muted py-2 pe-4 font-medium">
                      {t('col_added_by')}
                    </Table.HeadCell>
                    <Table.HeadCell className="text-text-muted py-2 font-medium">
                      {t('col_added_at')}
                    </Table.HeadCell>
                  </Table.Row>
                </Table.Head>
                <Table.Body>
                  {resolvedSortedDesc.map((entry) => {
                    const isCurrent =
                      resolvedCurrentEntry?.effectiveDateIl === entry.effectiveDateIl;
                    return (
                      <Table.Row key={entry.effectiveDateIl} className="border-b last:border-0">
                        <Table.Cell className="py-2 pe-4 font-mono text-xs">
                          {entry.effectiveDateIl}
                        </Table.Cell>
                        <Table.Cell className="py-2 pe-4">
                          <span className="me-2 tabular-nums">{entry.ratePercent}%</span>
                          {isCurrent && <Badge tone="success">{t('badge_current')}</Badge>}
                        </Table.Cell>
                        <Table.Cell className="py-2 pe-4">
                          {entry.addedBy === 'system' ? t('added_by_system') : entry.addedBy}
                        </Table.Cell>
                        <Table.Cell className="py-2">{formatDate(entry.addedAt, 'he')}</Table.Cell>
                      </Table.Row>
                    );
                  })}
                </Table.Body>
              </Table>
            );
          }}
        </QueryBoundary>
      </section>

      {/* Add form */}
      <section>
        <h2 className="mb-4 text-lg font-semibold">{t('add_heading')}</h2>
        <p className="text-text-muted mb-4 text-sm">{t('form_permanence_note')}</p>
        <form onSubmit={handleSubmit} className="max-w-sm space-y-4">
          <div className="space-y-1">
            <label className="text-sm font-medium" htmlFor="vat-date">
              {t('form_date_label')}
            </label>
            <Input
              id="vat-date"
              type="text"
              placeholder="YYYY-MM-DD"
              pattern="\d{4}-\d{2}-\d{2}"
              value={dateInput}
              onChange={(e) => setDateInput(e.target.value)}
              required
              aria-invalid={dateError ? true : undefined}
            />
            {dateError && (
              <p role="alert" className="text-destructive text-sm">
                {dateError}
              </p>
            )}
          </div>
          <div className="space-y-1">
            <label className="text-sm font-medium" htmlFor="vat-rate">
              {t('form_rate_label')}
            </label>
            <Input
              id="vat-rate"
              type="number"
              min={1}
              max={99}
              step={1}
              value={rateInput === '' ? '' : String(rateInput)}
              onChange={(e) => {
                const raw = e.target.value;
                setRateInput(raw === '' ? '' : Number.parseInt(raw, 10));
              }}
              required
              aria-invalid={rateError ? true : undefined}
            />
            {rateError && (
              <p role="alert" className="text-destructive text-sm">
                {rateError}
              </p>
            )}
          </div>
          {formError && (
            <p role="alert" className="text-destructive text-sm">
              {formError}
            </p>
          )}
          <Button type="submit" disabled={addMutation.isPending}>
            {addMutation.isPending ? t('saving') : t('form_submit')}
          </Button>
        </form>
      </section>
    </div>
  );
}

export function VatRatesAdmin() {
  return (
    <HydratedIsland>
      <VatRatesAdminInner />
    </HydratedIsland>
  );
}
