'use client';

import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { formatPrice } from '@alqove/shared';
import { useStorePayouts } from '@/lib/queries/use-payouts';
import { useSelectedStoreId } from '@/lib/stores/store-context';
import { PayoutStateBadge } from '@/components/payouts/payout-state-badge';
import { ConnectHealthBanner } from '@/components/seller/connect-health-banner';
import type { PayoutState } from '@alqove/api-client';

type FilterKey = PayoutState | 'all';

const FILTER_CHIPS: { value: FilterKey; label: string }[] = [
  { value: 'scheduled', label: 'Scheduled' },
  { value: 'in_flight', label: 'In flight' },
  { value: 'succeeded', label: 'Cleared' },
  { value: 'failed', label: 'Failed' },
  { value: 'all', label: 'All' },
];

const VALID_STATES: ReadonlySet<string> = new Set([
  'scheduled',
  'in_flight',
  'succeeded',
  'failed',
  'void',
]);

const PER_PAGE = 20;

// SSR-safe: pin locale + UTC so server and client render the same string.
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);
}

function stripeTransferUrl(transferId: string): string {
  // Hard-coded test mode for now; production toggling lands when prod launches.
  return `https://dashboard.stripe.com/test/connect/transfers/${transferId}`;
}

export function SellerPayoutsClient() {
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const storeId = useSelectedStoreId();

  const rawState = searchParams.get('state') ?? 'all';
  const activeFilter: FilterKey =
    rawState === 'all' || VALID_STATES.has(rawState)
      ? (rawState as FilterKey)
      : 'all';
  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) => {
      if (next === 'all') 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 | undefined =
    activeFilter === 'all' ? undefined : (activeFilter as PayoutState);

  const { data, isLoading, isError } = useStorePayouts(storeId, {
    state: queryState,
    page,
    per_page: PER_PAGE,
  });

  const payouts = data?.data ?? [];
  const meta = data?.meta;

  return (
    <div>
      {storeId ? (
        <div className="mb-4">
          <ConnectHealthBanner storeId={storeId} />
        </div>
      ) : null}

      <div>
        <h1 className="text-2xl font-bold text-ink">Payouts</h1>
        <p className="mt-1 text-sm text-ink/60">
          Transfers from your store balance to your Stripe payout account.
        </p>
      </div>

      <div className="mt-6 flex flex-wrap items-center gap-2">
        {FILTER_CHIPS.map((c) => (
          <button
            key={c.value}
            type="button"
            onClick={() => setFilter(c.value)}
            data-testid={`payouts-filter-${c.value}`}
            className={`rounded-full px-3 py-1 text-sm ${
              activeFilter === c.value
                ? 'bg-forest text-white'
                : 'bg-bone text-ink hover:bg-forest/10'
            }`}
          >
            {c.label}
          </button>
        ))}
      </div>

      <div className="mt-4 overflow-hidden rounded-md border border-forest/20 bg-white">
        {isLoading && (
          <table className="w-full text-sm" data-testid="payouts-loading">
            <thead className="bg-bone/60">
              <tr>
                <Th>Cycle</Th>
                <Th>State</Th>
                <Th>Gross</Th>
                <Th>Debits</Th>
                <Th>Net</Th>
                <Th>Stripe transfer</Th>
                <Th>Scheduled for</Th>
              </tr>
            </thead>
            <tbody>
              {Array.from({ length: 3 }).map((_, i) => (
                <tr key={i} className="border-t border-forest/10">
                  {Array.from({ length: 7 }).map((__, j) => (
                    <td key={j} className="px-4 py-3">
                      <div className="h-4 w-20 animate-pulse rounded bg-forest/10" />
                    </td>
                  ))}
                </tr>
              ))}
            </tbody>
          </table>
        )}

        {isError && (
          <div
            className="p-8 text-center text-sm text-terracotta"
            data-testid="payouts-error"
          >
            Failed to load payouts.
          </div>
        )}

        {!isLoading && !isError && payouts.length === 0 && (
          <div
            className="p-8 text-center text-sm text-ink/60"
            data-testid="payouts-empty"
          >
            No payouts yet.
          </div>
        )}

        {!isLoading && !isError && payouts.length > 0 && (
          <table className="w-full text-sm">
            <thead className="bg-bone/60">
              <tr>
                <Th>Cycle</Th>
                <Th>State</Th>
                <Th>Gross</Th>
                <Th>Debits</Th>
                <Th>Net</Th>
                <Th>Stripe transfer</Th>
                <Th>Scheduled for</Th>
              </tr>
            </thead>
            <tbody>
              {payouts.map((p) => (
                <tr
                  key={p.id}
                  data-testid={`payouts-row-${p.id}`}
                  className="border-t border-forest/10"
                >
                  <td className="px-4 py-3 text-ink">
                    {formatCycleDate(p.period_end)}
                  </td>
                  <td className="px-4 py-3">
                    <PayoutStateBadge state={p.state} />
                  </td>
                  <td className="px-4 py-3 text-ink">
                    {formatPrice(p.gross_cents)}
                  </td>
                  <td className="px-4 py-3 text-ink">
                    {formatPrice(p.debits_cents)}
                  </td>
                  <td className="px-4 py-3 font-medium text-ink">
                    {formatPrice(p.net_cents)}
                  </td>
                  <td className="px-4 py-3 text-xs">
                    {p.stripe_transfer_id ? (
                      <a
                        href={stripeTransferUrl(p.stripe_transfer_id)}
                        target="_blank"
                        rel="noreferrer noopener"
                        className="font-mono text-terracotta hover:underline"
                        data-testid={`payouts-transfer-link-${p.id}`}
                      >
                        {p.stripe_transfer_id}
                      </a>
                    ) : (
                      <span className="text-ink/40">—</span>
                    )}
                  </td>
                  <td className="px-4 py-3 text-xs text-ink/60">
                    {formatCycleDate(p.scheduled_for)}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {meta && meta.last_page > 1 && (
        <div className="mt-4 flex items-center justify-between text-xs text-ink/60">
          <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-forest/30 px-3 py-1 disabled:cursor-not-allowed disabled:opacity-50 hover:bg-bone/50"
            >
              Previous
            </button>
            <button
              type="button"
              onClick={() => setPage(page + 1)}
              disabled={page >= meta.last_page}
              className="rounded border border-forest/30 px-3 py-1 disabled:cursor-not-allowed disabled:opacity-50 hover:bg-bone/50"
            >
              Next
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function Th({ children }: { children: React.ReactNode }) {
  return (
    <th
      scope="col"
      className="px-4 py-2 text-left text-xs font-semibold uppercase tracking-wide text-ink/60"
    >
      {children}
    </th>
  );
}
