'use client';

import { useState } from 'react';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { formatPrice } from '@alqove/shared';
import { useAdminPayouts } from '@/lib/queries/use-admin-financials';
import { PayoutStateBadge } from '@/components/payouts/payout-state-badge';
import {
  AdminPayoutActionDialog,
  type PayoutActionKind,
} from '@/components/admin/admin-payout-action-dialog';
import type { PayoutState } from '@alqove/api-client';

type FilterKey = PayoutState | 'all';

// "Failed" is the default — this page is principally an exception queue.
const FILTER_CHIPS: { value: FilterKey; label: string }[] = [
  { value: 'failed', label: 'Failed' },
  { value: 'scheduled', label: 'Scheduled' },
  { value: 'in_flight', label: 'In flight' },
  { value: 'succeeded', label: 'Succeeded' },
  { value: 'void', label: 'Void' },
  { value: 'all', label: 'All' },
];

const FILTER_VALUES: ReadonlySet<string> = new Set(
  FILTER_CHIPS.map((c) => c.value),
);

const PER_PAGE = 20;

const CYCLE_DATE_FORMATTER = new Intl.DateTimeFormat('en-US', {
  month: 'short',
  day: 'numeric',
  year: 'numeric',
  timeZone: 'UTC',
});

function formatCycleDate(iso: string): string {
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) return '';
  return CYCLE_DATE_FORMATTER.format(date);
}

interface ActionTarget {
  payoutId: string;
  kind: PayoutActionKind;
  failureReason: string | null;
}

export function AdminPayoutsClient() {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();

  const rawState = searchParams.get('state') ?? 'failed';
  const activeFilter: FilterKey = FILTER_VALUES.has(rawState)
    ? (rawState as FilterKey)
    : 'failed';
  const page = Math.max(1, Number(searchParams.get('page') ?? '1'));

  const writeParams = (mut: (p: URLSearchParams) => void) => {
    const params = new URLSearchParams(searchParams.toString());
    mut(params);
    const qs = params.toString();
    router.replace(qs ? `${pathname}?${qs}` : pathname);
  };

  const setFilter = (next: FilterKey) => {
    writeParams((p) => {
      // Default filter is "failed" — drop the param when it matches default.
      if (next === 'failed') p.delete('state');
      else p.set('state', next);
      p.delete('page');
    });
  };

  const setPage = (next: number) => {
    writeParams((p) => {
      if (next <= 1) p.delete('page');
      else p.set('page', String(next));
    });
  };

  const queryState: PayoutState | 'all' = activeFilter;
  const { data, isLoading, isError } = useAdminPayouts({
    state: queryState,
    page,
    per_page: PER_PAGE,
  });
  const payouts = data?.data ?? [];
  const meta = data?.meta;

  const [actionTarget, setActionTarget] = useState<ActionTarget | null>(null);

  return (
    <div>
      <h1 className="text-2xl font-bold text-slate-900">Failed payouts</h1>
      <p className="mt-1 text-sm text-slate-500">
        Retry or void payouts that didn&apos;t clear automatically.
      </p>

      <div className="mt-4 flex flex-wrap gap-2">
        {FILTER_CHIPS.map((c) => (
          <button
            key={c.value}
            type="button"
            onClick={() => setFilter(c.value)}
            data-testid={`admin-payouts-filter-${c.value}`}
            className={`rounded-md px-3 py-1 text-xs font-medium ${
              activeFilter === c.value
                ? 'bg-slate-900 text-white'
                : 'border border-slate-300 text-slate-600 hover:bg-slate-50'
            }`}
          >
            {c.label}
          </button>
        ))}
      </div>

      {isError && (
        <p
          className="mt-4 rounded bg-red-50 p-3 text-sm text-red-700"
          data-testid="admin-payouts-error"
        >
          Couldn&apos;t load payouts.
        </p>
      )}

      <div className="mt-4 overflow-hidden rounded border border-slate-200 bg-white">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-slate-200">
              <th scope="col" className="px-4 py-3 text-left font-medium text-slate-500">
                State
              </th>
              <th scope="col" className="px-4 py-3 text-left font-medium text-slate-500">
                Store
              </th>
              <th scope="col" className="px-4 py-3 text-left font-medium text-slate-500">
                Period end
              </th>
              <th scope="col" className="px-4 py-3 text-right font-medium text-slate-500">
                Gross
              </th>
              <th scope="col" className="px-4 py-3 text-right font-medium text-slate-500">
                Debits
              </th>
              <th scope="col" className="px-4 py-3 text-right font-medium text-slate-500">
                Net
              </th>
              <th scope="col" className="px-4 py-3 text-right font-medium text-slate-500">
                Retries
              </th>
              <th scope="col" className="px-4 py-3 text-left font-medium text-slate-500">
                Failure reason
              </th>
              <th scope="col" className="px-4 py-3 text-right font-medium text-slate-500" />
            </tr>
          </thead>
          <tbody>
            {isLoading && (
              <tr>
                <td
                  colSpan={9}
                  className="px-4 py-6 text-center text-sm text-slate-400"
                  data-testid="admin-payouts-loading"
                >
                  Loading…
                </td>
              </tr>
            )}
            {!isLoading && payouts.length === 0 && (
              <tr>
                <td
                  colSpan={9}
                  className="px-4 py-6 text-center text-sm text-slate-400"
                  data-testid="admin-payouts-empty"
                >
                  No payouts in this view.
                </td>
              </tr>
            )}
            {payouts.map((p) => {
              const canRetry = p.state === 'failed';
              const canVoid = p.state === 'failed' || p.state === 'scheduled';
              return (
                <tr
                  key={p.id}
                  data-testid={`admin-payouts-row-${p.id}`}
                  className="border-b border-slate-100 last:border-0 hover:bg-slate-50"
                >
                  <td className="px-4 py-3">
                    <PayoutStateBadge state={p.state} />
                  </td>
                  <td className="px-4 py-3 text-slate-700">
                    {p.store_name ?? (
                      <span className="font-mono text-xs">
                        {p.store_id.slice(0, 8)}
                      </span>
                    )}
                  </td>
                  <td className="px-4 py-3 text-xs text-slate-600">
                    {formatCycleDate(p.period_end)}
                  </td>
                  <td className="px-4 py-3 text-right text-slate-700">
                    {formatPrice(p.gross_cents)}
                  </td>
                  <td className="px-4 py-3 text-right text-slate-700">
                    {formatPrice(p.debits_cents)}
                  </td>
                  <td className="px-4 py-3 text-right font-medium text-slate-900">
                    {formatPrice(p.net_cents)}
                  </td>
                  <td className="px-4 py-3 text-right text-xs text-slate-500">
                    {p.retries}
                  </td>
                  <td
                    className="px-4 py-3 text-xs text-rose-700"
                    title={p.failure_reason ?? undefined}
                  >
                    {p.failure_reason ? (
                      <span className="line-clamp-2">{p.failure_reason}</span>
                    ) : (
                      <span className="text-slate-400">—</span>
                    )}
                  </td>
                  <td className="px-4 py-3 text-right">
                    <div className="flex justify-end gap-1">
                      {canRetry && (
                        <button
                          type="button"
                          onClick={() =>
                            setActionTarget({
                              payoutId: p.id,
                              kind: 'retry',
                              failureReason: p.failure_reason,
                            })
                          }
                          data-testid={`admin-payouts-retry-${p.id}`}
                          className="rounded-md border border-slate-300 px-2 py-1 text-xs text-slate-700 hover:bg-slate-50"
                        >
                          Retry
                        </button>
                      )}
                      {canVoid && (
                        <button
                          type="button"
                          onClick={() =>
                            setActionTarget({
                              payoutId: p.id,
                              kind: 'void',
                              failureReason: p.failure_reason,
                            })
                          }
                          data-testid={`admin-payouts-void-${p.id}`}
                          className="rounded-md border border-rose-300 bg-rose-50 px-2 py-1 text-xs text-rose-700 hover:bg-rose-100"
                        >
                          Void
                        </button>
                      )}
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {meta && meta.last_page > 1 && (
        <div className="mt-4 flex items-center justify-between text-xs text-slate-600">
          <span>
            Page {meta.current_page} of {meta.last_page} · {meta.total} total
          </span>
          <div className="flex gap-2">
            <button
              type="button"
              onClick={() => setPage(page - 1)}
              disabled={page <= 1}
              className="rounded border border-slate-300 px-3 py-1 disabled:cursor-not-allowed disabled:opacity-50 hover:bg-slate-50"
            >
              Previous
            </button>
            <button
              type="button"
              onClick={() => setPage(page + 1)}
              disabled={page >= meta.last_page}
              className="rounded border border-slate-300 px-3 py-1 disabled:cursor-not-allowed disabled:opacity-50 hover:bg-slate-50"
            >
              Next
            </button>
          </div>
        </div>
      )}

      {actionTarget && (
        <AdminPayoutActionDialog
          open
          kind={actionTarget.kind}
          payoutId={actionTarget.payoutId}
          failureReason={actionTarget.failureReason}
          onClose={() => setActionTarget(null)}
        />
      )}
    </div>
  );
}
