/**
 * VendorGroupDealDetail — vendor management panel for a single group deal.
 *
 * Fetches /api/vendor/group-deals/[id]/dashboard and exposes:
 *   - Dashboard KPIs (participants, fill rate, revenue)
 *   - Honor button  (PARTIAL_PENDING state)
 *   - Extend Deadline form (COLLECTING state)
 *   - Relaunch button (FAILED state)
 *
 * @design-system VendorGroupDealDetail
 */

'use client';

import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { QueryBoundary } from '@platform-modules/ui-primitives';
import { HydratedIsland } from '@/components/HydratedIsland';
import { VendorShell } from '@/components/ui/layout/VendorShell';
import { Button } from '@/components/ui/primitives/Button';
import {
  AlertDialog,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogAction,
  AlertDialogCancel,
} from '@/components/ui/overlays/AlertDialog';
import { Input } from '@/components/ui/primitives/Input';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { MetricTile } from '@/components/ui/domain/MetricTile';
import { Icon } from '@/components/ui/icons/Icon';
import { useT, useLocale } from '@/lib/i18n/react';
import { getCsrfToken } from '@/lib/csrf';
import { formatDate, formatDateTime } from '@/lib/format';
import { interpolate } from '@/lib/i18n/interpolate';
import { Table } from '@/components/ui/primitives/Table';
import { formatShekelFloat } from '@/lib/money.js';
import { Skeleton, TableSkeleton } from '@/components/ui/feedback/Skeleton';

// ─── Types ────────────────────────────────────────────────────────────────────

interface DashboardData {
  groupDealId: string;
  dealTitle: string;
  participantCount: number;
  fillRate: number;
  revenueProjection: string;
  confirmedRevenue: string;
  pendingRevenue: string;
  currentReservationCount: number;
  minGroupSize: number;
  maxGroupSize: number;
  groupState: string;
  deadline: string | null;
  tiers: Array<{ minParticipants: number; pricePerUnit: string }>;
}

export interface VendorGroupDealDetailProps {
  groupDealId: string;
}

// ─── Hook ─────────────────────────────────────────────────────────────────────

function useDashboard(groupDealId: string) {
  return useQuery<DashboardData>({
    queryKey: ['vendor-group-deal-dashboard', groupDealId],
    queryFn: async () => {
      const res = await fetch(`/api/vendor/group-deals/${groupDealId}/dashboard`);
      if (!res.ok) throw new Error('Failed to load dashboard');
      const json = (await res.json()) as { ok: boolean; data: DashboardData; error?: string };
      if (!json.ok) throw new Error(json.error ?? 'Failed to load dashboard');
      return json.data;
    },
    staleTime: 30_000,
  });
}

function VendorGroupDealDetailSkeleton() {
  return (
    <div
      className="flex flex-col gap-6 p-4 lg:p-6"
      aria-hidden="true"
      data-testid="instant-skeleton:vendor-group-deal-detail"
    >
      <Skeleton className="h-5 w-28" />
      <Skeleton className="h-8 w-72 max-w-full" />
      <Skeleton className="h-7 w-32 rounded-full" />
      <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
        {Array.from({ length: 5 }).map((_, index) => (
          <Skeleton key={index} className="h-24 w-full rounded-xl" />
        ))}
      </div>
      <Skeleton className="h-6 w-52" />
      <div className="space-y-3">
        <Skeleton className="h-5 w-28" />
        <TableSkeleton rows={4} cols={2} />
      </div>
      <div className="border-border bg-surface rounded-lg border p-4">
        <Skeleton className="mb-3 h-6 w-40" />
        <Skeleton className="mb-4 h-4 w-full max-w-md" />
        <div className="flex flex-wrap gap-3">
          <Skeleton className="h-10 w-40" />
          <Skeleton className="h-10 w-48" />
        </div>
      </div>
    </div>
  );
}

// ─── Inner component ──────────────────────────────────────────────────────────

function VendorGroupDealDetailInner({ groupDealId }: VendorGroupDealDetailProps) {
  const t = useT('group_deal');
  const tCommon = useT('common');
  const { locale } = useLocale();
  const queryClient = useQueryClient();

  const dashboardQuery = useDashboard(groupDealId);

  const [extendDate, setExtendDate] = useState('');
  const [actionError, setActionError] = useState<string | null>(null);
  const [pendingConfirm, setPendingConfirm] = useState<'honor' | 'extend' | 'relaunch' | null>(
    null,
  );

  const honorMutation = useMutation({
    mutationFn: async () => {
      const res = await fetch(`/api/vendor/group-deals/${groupDealId}/honor`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': getCsrfToken(),
        },
        body: JSON.stringify({}),
      });
      const json = (await res.json()) as { ok: boolean; error?: string };
      if (!json.ok) throw new Error(json.error ?? 'Error');
    },
    onSuccess: () => {
      setActionError(null);
      void queryClient.invalidateQueries({
        queryKey: ['vendor-group-deal-dashboard', groupDealId],
      });
    },
    onError: (err: Error) => setActionError(err.message),
  });

  const extendMutation = useMutation({
    mutationFn: async (newDeadline: string) => {
      const res = await fetch(`/api/vendor/group-deals/${groupDealId}/extend`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': getCsrfToken(),
        },
        body: JSON.stringify({ newDeadline }),
      });
      const json = (await res.json()) as { ok: boolean; error?: string };
      if (!json.ok) throw new Error(json.error ?? 'Error');
    },
    onSuccess: () => {
      setActionError(null);
      setExtendDate('');
      void queryClient.invalidateQueries({
        queryKey: ['vendor-group-deal-dashboard', groupDealId],
      });
    },
    onError: (err: Error) => setActionError(err.message),
  });

  const relaunchMutation = useMutation({
    mutationFn: async () => {
      const res = await fetch(`/api/vendor/group-deals/${groupDealId}/relaunch`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'x-csrf-token': getCsrfToken(),
        },
        body: JSON.stringify({}),
      });
      const json = (await res.json()) as {
        ok: boolean;
        data?: { newGroupDealId: string };
        error?: string;
      };
      if (!json.ok) throw new Error(json.error ?? 'Error');
      return json.data;
    },
    onSuccess: (result) => {
      setActionError(null);
      if (result?.newGroupDealId) {
        window.location.href = `/vendor/group-deals/${result.newGroupDealId}`;
      } else {
        void dashboardQuery.refetch();
      }
    },
    onError: (err: Error) => setActionError(err.message),
  });

  return (
    <VendorShell variant="dashboard" currentPath="/vendor/deals">
      <QueryBoundary
        query={dashboardQuery}
        skeleton={<VendorGroupDealDetailSkeleton />}
        errorFallback={() => (
          <ErrorState
            title={tCommon('error_loading')}
            action={
              <Button variant="secondary" size="sm" onClick={() => void dashboardQuery.refetch()}>
                {tCommon('retry')}
              </Button>
            }
          />
        )}
      >
        {(data) => {
          const isPartialPending = data.groupState === 'PARTIAL_PENDING';
          const isCollecting =
            data.groupState === 'COLLECTING' || data.groupState === 'THRESHOLD_MET';
          const isFailed = data.groupState === 'FAILED';
          const isTerminal = ['SUCCEEDED', 'VENDOR_HONORED', 'FAILED'].includes(data.groupState);

          const isPending =
            honorMutation.isPending || extendMutation.isPending || relaunchMutation.isPending;

          const activeTierMin =
            [...data.tiers]
              .sort((a, b) => b.minParticipants - a.minParticipants)
              .find((tier) => data.participantCount >= tier.minParticipants)?.minParticipants ??
            null;

          return (
            <div
              className="flex flex-col gap-6 p-4 lg:p-6"
              data-testid="instant-content:vendor-group-deal-detail"
            >
              {/* Back link */}
              <a
                href="/vendor/deals"
                className="text-text-secondary hover:text-text-primary flex items-center gap-1 text-sm"
              >
                <Icon name="ChevronRight" size="sm" aria-hidden />
                <span>{t('vendor_dashboard_back')}</span>
              </a>

              <h1 className="text-text-primary text-xl font-semibold">{data.dealTitle}</h1>

              {/* State badge */}
              <div>
                <span className="inline-flex items-center rounded-full bg-[var(--color-surface-accent)] px-3 py-1 text-sm font-medium text-[var(--color-accent)]">
                  {t(`state_${data.groupState.toLowerCase()}` as Parameters<typeof t>[0])}
                </span>
              </div>

              {/* KPI grid */}
              <section aria-label={t('vendor_dashboard_title')}>
                <div className="grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-5">
                  <div className="bg-surface-raised flex flex-col items-center justify-center gap-1 rounded-xl p-4 text-center">
                    <span className="text-3xl leading-tight font-bold">
                      {data.participantCount} / {data.minGroupSize}
                    </span>
                    <span className="text-xs font-medium opacity-80">
                      {t('vendor_dashboard_participants')}
                    </span>
                    <span className="text-text-muted text-2xs">
                      {interpolate(t('vendor_dashboard_participants_max'), {
                        max: String(data.maxGroupSize),
                      })}
                    </span>
                  </div>
                  <MetricTile
                    label={t('vendor_dashboard_fill_rate')}
                    value={`${Math.round(data.fillRate * 100)}%`}
                  />
                  <MetricTile
                    label={t('vendor_dashboard_revenue')}
                    value={formatShekelFloat(data.confirmedRevenue)}
                  />
                  <MetricTile
                    label={t('vendor_dashboard_held_revenue')}
                    value={formatShekelFloat(data.pendingRevenue)}
                  />
                  <MetricTile
                    label={t('vendor_dashboard_projected_revenue')}
                    value={formatShekelFloat(data.revenueProjection)}
                  />
                </div>
              </section>

              {/* Deadline */}
              {data.deadline && (
                <p className="text-text-secondary text-sm">
                  {t('deadline_label')}: <strong>{formatDate(data.deadline, locale)}</strong>
                </p>
              )}

              {/* Price tiers */}
              {data.tiers.length > 0 && (
                <section aria-labelledby="tiers-heading">
                  <h2 id="tiers-heading" className="text-text-primary mb-3 text-sm font-semibold">
                    {t('vendor_tiers_title')}
                  </h2>
                  <Table>
                    <Table.Head className="bg-surface-inset">
                      <Table.Row>
                        <Table.HeadCell className="text-text-secondary px-4 py-2 font-medium">
                          {t('vendor_tiers_participants')}
                        </Table.HeadCell>
                        <Table.HeadCell className="text-text-secondary px-4 py-2 text-end font-medium">
                          {t('vendor_tiers_price')}
                        </Table.HeadCell>
                      </Table.Row>
                    </Table.Head>
                    <Table.Body>
                      {[...data.tiers]
                        .sort((a, b) => a.minParticipants - b.minParticipants)
                        .map((tier) => {
                          const isActive = tier.minParticipants === activeTierMin;
                          return (
                            <Table.Row
                              key={tier.minParticipants}
                              className={isActive ? 'bg-mode-vendor-50' : undefined}
                              aria-current={isActive ? 'true' : undefined}
                            >
                              <Table.Cell className="text-text-primary px-4 py-2">
                                {tier.minParticipants}+
                                {isActive && (
                                  <span className="text-text-muted ms-2 text-xs">
                                    ({t('vendor_tiers_active')})
                                  </span>
                                )}
                              </Table.Cell>
                              <Table.Cell className="text-text-primary px-4 py-2 text-end tabular-nums">
                                {formatShekelFloat(tier.pricePerUnit)}
                              </Table.Cell>
                            </Table.Row>
                          );
                        })}
                    </Table.Body>
                  </Table>
                </section>
              )}

              {/* Error notice */}
              {actionError && (
                <div
                  role="alert"
                  className="rounded border border-red-300 bg-red-50 p-3 text-sm text-red-700"
                >
                  {actionError}
                </div>
              )}

              {/* ── Actions ── */}

              {/* Honor (PARTIAL_PENDING) */}
              {isPartialPending && (
                <section className="border-border bg-surface rounded-lg border p-4">
                  <h2 className="text-text-primary mb-2 text-base font-semibold">
                    {t('vendor_honor_prompt')}
                  </h2>
                  <p className="text-text-secondary mb-4 text-sm">{t('vendor_honor_deadline')}</p>
                  <div className="flex flex-wrap gap-3">
                    <Button
                      variant="primary"
                      disabled={isPending}
                      aria-busy={honorMutation.isPending}
                      onClick={() => setPendingConfirm('honor')}
                    >
                      {t('vendor_honor_accept')}
                    </Button>
                  </div>
                </section>
              )}

              {/* Extend deadline (COLLECTING / THRESHOLD_MET) */}
              {isCollecting && !isTerminal && (
                <section className="border-border bg-surface rounded-lg border p-4">
                  <h2 className="text-text-primary mb-2 text-base font-semibold">
                    {t('vendor_extend_prompt')}
                  </h2>
                  <div className="flex flex-wrap items-end gap-3">
                    <div className="flex flex-col gap-1">
                      <label htmlFor="extend-date" className="text-text-secondary text-sm">
                        {t('deadline_label')}
                      </label>
                      <Input
                        id="extend-date"
                        type="datetime-local"
                        value={extendDate}
                        onChange={(e) => setExtendDate(e.target.value)}
                        className="text-sm"
                        min={new Date().toISOString().slice(0, 16)}
                        aria-required={true}
                      />
                    </div>
                    <Button
                      variant="secondary"
                      disabled={!extendDate || isPending}
                      aria-busy={extendMutation.isPending}
                      onClick={() => setPendingConfirm('extend')}
                    >
                      {t('vendor_extend_confirm')}
                    </Button>
                  </div>
                </section>
              )}

              {/* Relaunch (FAILED) */}
              {isFailed && (
                <section className="border-border bg-surface rounded-lg border p-4">
                  <h2 className="text-text-primary mb-2 text-base font-semibold">
                    {t('vendor_relaunch')}
                  </h2>
                  <Button
                    variant="secondary"
                    disabled={isPending}
                    aria-busy={relaunchMutation.isPending}
                    onClick={() => setPendingConfirm('relaunch')}
                  >
                    {t('vendor_relaunch')}
                  </Button>
                </section>
              )}

              <AlertDialog
                open={!!pendingConfirm}
                onOpenChange={(open) => {
                  if (!open) setPendingConfirm(null);
                }}
              >
                <AlertDialogContent>
                  <AlertDialogHeader>
                    <AlertDialogTitle>
                      {pendingConfirm === 'honor'
                        ? t('vendor_honor_accept')
                        : pendingConfirm === 'extend'
                          ? t('vendor_extend_confirm')
                          : t('vendor_relaunch')}
                    </AlertDialogTitle>
                    <AlertDialogDescription>
                      {pendingConfirm === 'honor'
                        ? t('vendor_honor_confirm_desc')
                        : pendingConfirm === 'extend'
                          ? interpolate(t('vendor_extend_confirm_desc'), {
                              date: extendDate ? formatDateTime(extendDate, locale) : '',
                            })
                          : t('vendor_relaunch_confirm')}
                    </AlertDialogDescription>
                  </AlertDialogHeader>
                  <AlertDialogFooter>
                    <AlertDialogCancel>{tCommon('cancel')}</AlertDialogCancel>
                    <AlertDialogAction
                      onClick={() => {
                        if (pendingConfirm === 'honor') {
                          honorMutation.mutate();
                        } else if (pendingConfirm === 'extend' && extendDate) {
                          extendMutation.mutate(new Date(extendDate).toISOString());
                        } else if (pendingConfirm === 'relaunch') {
                          relaunchMutation.mutate();
                        }
                        setPendingConfirm(null);
                      }}
                    >
                      {pendingConfirm === 'honor'
                        ? t('vendor_honor_accept')
                        : pendingConfirm === 'extend'
                          ? t('vendor_extend_confirm')
                          : t('vendor_relaunch')}
                    </AlertDialogAction>
                  </AlertDialogFooter>
                </AlertDialogContent>
              </AlertDialog>
            </div>
          );
        }}
      </QueryBoundary>
    </VendorShell>
  );
}

// ─── Export ───────────────────────────────────────────────────────────────────

export function VendorGroupDealDetail({ groupDealId }: VendorGroupDealDetailProps) {
  return (
    <HydratedIsland>
      <VendorGroupDealDetailInner groupDealId={groupDealId} />
    </HydratedIsland>
  );
}
