'use client';
import { ErrorState } from '@/components/ui/feedback/ErrorState';

import { useMemo, useState } from 'react';
import { useUrlFilterState } from '@/lib/url/useUrlFilterState';
import { makeSettlementsCodec } from '@/lib/url/codecs/settlementsCodec';
import { HISTORY } from '@/lib/url/historyPolicy';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Card } from '@/components/ui/layout/Card';
import { Button } from '@/components/ui/primitives/Button';
import { Badge } from '@/components/ui/primitives/Badge';
import { Label } from '@/components/ui/primitives/Label';
import { Textarea } from '@/components/ui/primitives/Textarea';
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/overlays/Dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/primitives/Select';
import { useT, useLocale } from '@/lib/i18n/react';
import { interpolate } from '@/lib/i18n/interpolate';
import { formatAgorotGrouped } from '@/lib/money';
import { formatDate } from '@/lib/format';
import { getCsrfToken } from '@/lib/csrf';
import { captureCaught } from '@/lib/observability';
import { HydratedIsland } from '@/components/HydratedIsland';
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from '@/components/ui/overlays/Tooltip';

type Release = {
  id: string;
  vendorId: string;
  vendorBusinessName?: string | null;
  netAmountAgorot: number;
  status: string;
  releaseAt: string;
  heldAt: string;
  lastError?: string | null;
};

const STATUSES = ['held', 'enqueued', 'releasing', 'released', 'refunded', 'cancelled'] as const;

type ReleaseStatus = (typeof STATUSES)[number];

function statusKey(s: string): `releases_status_${ReleaseStatus}` {
  const norm = s as ReleaseStatus;
  return STATUSES.includes(norm) ? `releases_status_${norm}` : 'releases_status_held';
}

function releaseStatusTooltipKey(
  status: string,
): 'tooltip_releases_status_held' | 'tooltip_releases_status_refunded' | null {
  if (status === 'held') return 'tooltip_releases_status_held';
  if (status === 'refunded') return 'tooltip_releases_status_refunded';
  return null;
}

function ReleaseStatusBadge({ status }: { status: string }) {
  const t = useT('admin_settlements');
  const label = t(statusKey(status));
  const badge = <Badge tone="neutral">{label}</Badge>;
  const tooltipKey = releaseStatusTooltipKey(status);
  if (!tooltipKey) return badge;
  return (
    <Tooltip>
      <TooltipTrigger asChild>
        <span className="inline-flex cursor-help">{badge}</span>
      </TooltipTrigger>
      <TooltipContent side="top" className="max-w-xs text-wrap">
        {t(tooltipKey)}
      </TooltipContent>
    </Tooltip>
  );
}

function SettlementsTableInner() {
  const t = useT('admin_settlements');
  const tCommon = useT('common');
  const { locale } = useLocale();
  const qc = useQueryClient();
  const codec = useMemo(() => makeSettlementsCodec('/admin/settlements'), []);
  const { state: urlState, setUrlState } = useUrlFilterState({
    initial: { filter: 'held' },
    codec,
  });
  const filter = urlState.filter;
  const [cancelTarget, setCancelTarget] = useState<Release | null>(null);
  const [cancelReason, setCancelReason] = useState('');
  const [cancelError, setCancelError] = useState<string | null>(null);

  const {
    data: rows = [],
    isError,
    refetch,
  } = useQuery<Release[]>({
    queryKey: ['admin-settlements', filter],
    queryFn: async () => {
      const res = await fetch(`/api/admin/settlements/releases?status=${filter}&limit=50`);
      const json = (await res.json()) as unknown;
      const j = json as Record<string, unknown>;
      if (j?.ok && j.data && typeof j.data === 'object') {
        const d = j.data as Record<string, unknown>;
        if (Array.isArray(d.releases)) return d.releases as Release[];
      }
      if (Array.isArray(json)) return json as Release[];
      return [];
    },
  });

  const cancelMutation = useMutation({
    mutationFn: async ({ id, reason }: { id: string; reason: string }) => {
      const res = await fetch(`/api/admin/settlements/${id}/cancel`, {
        method: 'POST',
        headers: { 'content-type': 'application/json', 'x-csrf-token': getCsrfToken() },
        body: JSON.stringify({ reason }),
      });
      if (!res.ok) {
        const json = (await res.json().catch((err) => {
          captureCaught(err, { scope: 'SettlementsTable.cancel.parse' });
          return {};
        })) as Record<string, unknown>;
        throw new Error((json.error as string) || `HTTP ${res.status}`);
      }
    },
    onSuccess: () => {
      setCancelTarget(null);
      setCancelReason('');
      setCancelError(null);
    },
    onError: (err: Error) => {
      setCancelError(err.message);
    },
    onSettled: () => {
      void qc.invalidateQueries({ queryKey: ['admin-settlements', filter] });
    },
  });

  const filterStatusLabel = t(statusKey(filter));

  if (isError) {
    return (
      <ErrorState
        title={tCommon('error_loading')}
        action={
          <Button variant="secondary" size="sm" onClick={() => refetch()}>
            {tCommon('retry')}
          </Button>
        }
      />
    );
  }

  return (
    <TooltipProvider delayDuration={200}>
      <Card>
        <div className="mb-4 flex flex-row items-center justify-between gap-4">
          <h2 className="text-lg font-semibold">{t('releases_title')}</h2>
          <div className="flex items-center gap-2">
            <Label htmlFor="releases-status-filter" className="text-text-secondary text-xs">
              {t('releases_filter_visible_label')}
            </Label>
            <Select
              value={filter}
              onValueChange={(v: string) => setUrlState({ filter: v }, HISTORY.tweak)}
            >
              <SelectTrigger
                id="releases-status-filter"
                className="w-36"
                aria-label={t('releases_filter_label')}
              >
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {STATUSES.map((s) => (
                  <SelectItem key={s} value={s}>
                    {t(statusKey(s))}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>
        <div role="list" aria-label={t('releases_table_aria')} className="flex flex-col gap-2">
          {rows.map((r) => {
            const vendorLabel = r.vendorBusinessName?.trim() || r.vendorId.slice(0, 8);
            return (
              <div
                key={r.id}
                role="listitem"
                className="flex items-center justify-between gap-4 border-b py-3"
              >
                <div className="flex min-w-0 flex-col gap-1">
                  <span className="text-text-muted font-mono text-xs">{r.id.slice(0, 8)}</span>
                  <span className="truncate text-sm">
                    <a
                      href={`/admin/vendors/${r.vendorId}`}
                      className="font-medium text-[var(--color-text-primary)] hover:underline"
                    >
                      {vendorLabel}
                    </a>
                    <span className="text-text-muted ms-2 font-mono text-xs">
                      {t('releases_col_vendor_id')}: {r.vendorId.slice(0, 8)}
                    </span>
                  </span>
                  <span className="text-sm font-medium">
                    {formatAgorotGrouped(r.netAmountAgorot)}
                  </span>
                  <span className="text-text-secondary text-xs">
                    {t('releases_release_at_label')}: {formatDate(r.releaseAt, locale)}
                  </span>
                  {r.lastError && (
                    <span className="text-danger-700 max-w-xs truncate text-xs" title={r.lastError}>
                      {t('releases_col_error')}: {r.lastError}
                    </span>
                  )}
                </div>
                <div className="flex shrink-0 items-center gap-3">
                  <ReleaseStatusBadge status={r.status} />
                  {(r.status === 'held' || r.status === 'enqueued') && (
                    <Tooltip>
                      <TooltipTrigger asChild>
                        <Button
                          size="sm"
                          variant="danger"
                          onClick={() => {
                            setCancelError(null);
                            setCancelReason('');
                            setCancelTarget(r);
                          }}
                          aria-label={t('releases_cancel_aria').replace('{{id}}', r.id.slice(0, 8))}
                        >
                          {t('releases_cancel')}
                        </Button>
                      </TooltipTrigger>
                      <TooltipContent side="top" className="max-w-xs text-wrap">
                        {t('tooltip_releases_cancel')}
                      </TooltipContent>
                    </Tooltip>
                  )}
                </div>
              </div>
            );
          })}
          {rows.length === 0 && (
            <p className="text-text-muted py-8 text-center">
              {interpolate(t('releases_empty'), { status: filterStatusLabel })}
            </p>
          )}
        </div>
      </Card>

      <Dialog
        open={!!cancelTarget}
        onOpenChange={(open) => {
          if (!open) {
            setCancelTarget(null);
            setCancelReason('');
            setCancelError(null);
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{t('releases_cancel_dialog_title')}</DialogTitle>
          </DialogHeader>
          {cancelTarget && (
            <div className="flex flex-col gap-3 py-2">
              <p className="text-sm">
                {interpolate(t('releases_cancel_dialog_body'), {
                  amount: formatAgorotGrouped(cancelTarget.netAmountAgorot),
                  vendor:
                    cancelTarget.vendorBusinessName?.trim() || cancelTarget.vendorId.slice(0, 8),
                })}
              </p>
              <div className="flex flex-col gap-1">
                <Label htmlFor="cancel-reason">{t('releases_cancel_reason_label')}</Label>
                <Textarea
                  id="cancel-reason"
                  rows={3}
                  value={cancelReason}
                  onChange={(e) => setCancelReason(e.target.value)}
                />
              </div>
              {cancelError ? (
                <p role="alert" className="text-danger-600 text-sm">
                  {cancelError}
                </p>
              ) : null}
            </div>
          )}
          <DialogFooter>
            <Button variant="ghost" onClick={() => setCancelTarget(null)}>
              {tCommon('cancel')}
            </Button>
            <Button
              variant="danger"
              loading={cancelMutation.isPending}
              disabled={!cancelTarget}
              onClick={() => {
                if (!cancelTarget) return;
                cancelMutation.mutate({
                  id: cancelTarget.id,
                  reason: cancelReason.trim() || t('releases_cancel_reason_default'),
                });
              }}
            >
              {t('releases_cancel')}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </TooltipProvider>
  );
}

export function SettlementsTable() {
  return (
    <HydratedIsland>
      <SettlementsTableInner />
    </HydratedIsland>
  );
}
