import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { ErrorState } from '@/components/ui/feedback/ErrorState';
import { useT } from '@/lib/i18n/react';
import { useLocale } from '@/lib/i18n/react';
import { Button } from '@/components/ui/primitives/Button';
import { Table } from '@/components/ui/primitives/Table';
import { LabelWithTooltip } from '@/components/ui/primitives/LabelWithTooltip';
import { ToastProvider, ToastViewport, Toast, ToastTitle } from '@/components/ui/overlays/Toast';
import { PageShellSkeleton, TableSkeleton } from '@/components/ui/feedback/Skeleton';
import { EmptyState } from '@/components/ui/feedback/EmptyState';
import { AffiliateKycBanner } from './AffiliateKycBanner';
import { AffiliateStatsWindow } from './AffiliateStatsWindow';
import { AffiliateWithdrawPanel } from './AffiliateWithdrawPanel';
import { type AffiliateConnectStatusOrNull } from '@/lib/enums/affiliate-connect-status';
import { enumLabel } from '@/lib/enums/enum-labels';
import {
  agorotToShekels,
  formatAgorotDisplay,
  formatAgorotPlain,
  formatAgorotSigned,
} from '@/lib/money.js';
import { formatDate } from '@/lib/format';
import { captureCaught } from '@/lib/observability';
import type { Locale } from '@/lib/i18n';
import { QueryBoundary } from '@platform-modules/ui-primitives';
import { MetricTile } from '@/components/ui/domain/MetricTile';
import { SegmentedControl } from '@/components/ui/primitives/SegmentedControl';
import { useDashboardDensity } from '@/features/dashboards/useDashboardDensity';
import { localizeCommandPath } from '@/components/ui/overlays/CommandPalette/CommandPalette';

type WalletData = {
  enrolled: boolean;
  pending_agorot: number;
  matured_agorot: number;
  matured_agorot_is_debt?: boolean;
  affiliate_connect_status: AffiliateConnectStatusOrNull;
  enrollment_status: 'active' | 'suspended' | 'revoked' | null;
  min_withdrawal_agorot: number;
  referral_link: string | null;
};

type ActivityRow = {
  id: string;
  entry_type: string;
  amount_agorot: number;
  status: string;
  created_at: string;
};

export function affiliateProgramHref(locale: Locale): string {
  return localizeCommandPath('/affiliate-program', locale);
}

export function AffiliateDashboard() {
  const t = useT('affiliate');
  const tCommon = useT('common');
  const tNav = useT('nav');
  const { locale } = useLocale();
  const [linkCopied, setLinkCopied] = useState(false);
  const { density, setDensity } = useDashboardDensity('dashboard-density:affiliate');

  const walletQuery = useQuery<WalletData>({
    queryKey: ['affiliate-wallet'],
    queryFn: async () => {
      const res = await fetch('/api/affiliate/stats?window=overview');
      if (!res.ok) throw new Error(await res.text());
      const json = (await res.json()) as { data?: WalletData } & WalletData;
      return json.data ?? json;
    },
  });

  const activityQuery = useQuery<{ rows: ActivityRow[] }>({
    queryKey: ['affiliate-activity'],
    queryFn: async () => {
      const res = await fetch('/api/affiliate/activity');
      if (!res.ok) throw new Error(await res.text());
      const raw = (await res.json()) as { rows: ActivityRow[] } | { data: { rows: ActivityRow[] } };
      return 'data' in raw ? raw.data : raw;
    },
  });

  const handleCopyLink = async (link: string) => {
    try {
      await navigator.clipboard.writeText(link);
      setLinkCopied(true);
    } catch (err) {
      captureCaught(err, {
        scope: 'features.affiliate.AffiliateDashboard.copy',
        severity: 'warning',
      });
      setLinkCopied(false);
    }
  };

  return (
    <ToastProvider swipeDirection="right">
      <QueryBoundary
        query={walletQuery}
        skeleton={<PageShellSkeleton />}
        errorFallback={(retry) => (
          <ErrorState
            title={tCommon('error_loading')}
            action={
              <Button variant="secondary" size="sm" onClick={() => retry()}>
                {tCommon('retry')}
              </Button>
            }
          />
        )}
      >
        {(walletData) => {
          if (!walletData.enrolled) {
            return (
              <div className="p-8 text-center">
                <p className="mb-4 text-(--color-text-muted)">{t('not_enrolled')}</p>
                <a href={affiliateProgramHref(locale)} className="text-(--color-primary) underline">
                  {t('enroll_cta')}
                </a>
              </div>
            );
          }

          const maturedDisplay = formatAgorotDisplay(walletData.matured_agorot);
          const maturedIsDebt =
            walletData.matured_agorot_is_debt === true || walletData.matured_agorot < 0;
          const maturedValue =
            typeof maturedDisplay === 'object' ? (
              <span className="text-text-muted">
                {t('balance_debt_label')}
                <span className="mt-0.5 block text-xs">
                  {t('balance_debt_detail').replace(
                    '{{amount}}',
                    formatAgorotPlain(maturedDisplay.debtAgorot),
                  )}
                </span>
              </span>
            ) : (
              maturedDisplay
            );

          return (
            <div className="space-y-8">
              <section className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_16rem]">
                <div className="space-y-2">
                  <h1 className="text-2xl font-bold">{t('dashboard_heading')}</h1>
                  <p className="text-text-muted text-sm">{t('hero_period_current_balance')}</p>
                </div>
                <MetricTile
                  label={t('hero_available_now')}
                  value={maturedValue}
                  countUpValue={
                    maturedIsDebt ? undefined : agorotToShekels(walletData.matured_agorot)
                  }
                  formatCountUpValue={(value) => {
                    const display = formatAgorotDisplay(Math.round(value * 100));
                    return typeof display === 'string'
                      ? display
                      : formatAgorotPlain(display.debtAgorot);
                  }}
                  periodLabel={t('hero_period_current_balance')}
                />
              </section>

              <AffiliateKycBanner connectStatus={walletData.affiliate_connect_status} />

              {walletData.referral_link && (
                <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
                  <p className="text-sm font-medium">{t('your_link')}</p>
                  <code className="flex-1 truncate rounded border border-(--color-border) bg-(--color-surface) px-3 py-1.5 text-sm">
                    {walletData.referral_link}
                  </code>
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => void handleCopyLink(walletData.referral_link ?? '')}
                  >
                    {t('copy_link')}
                  </Button>
                </div>
              )}

              <AffiliateStatsWindow />

              <QueryBoundary
                query={activityQuery}
                skeleton={<TableSkeleton rows={4} cols={4} />}
                errorFallback={(retry) => (
                  <ErrorState
                    title={tCommon('error_loading')}
                    action={
                      <Button variant="secondary" size="sm" onClick={() => retry()}>
                        {tCommon('retry')}
                      </Button>
                    }
                  />
                )}
              >
                {(activityData) => (
                  <section aria-labelledby="activity-heading">
                    <div className="mb-3 flex flex-wrap items-center justify-between gap-3">
                      <h2 id="activity-heading" className="text-lg font-semibold">
                        {t('activity_heading')}
                      </h2>
                      <SegmentedControl
                        aria-label={t('density_label')}
                        size="sm"
                        value={density}
                        onChange={(value) => setDensity(value as 'comfortable' | 'dense')}
                        options={[
                          { value: 'comfortable', label: t('density_comfortable') },
                          { value: 'dense', label: t('density_dense') },
                        ]}
                      />
                    </div>
                    {!activityData.rows.length ? (
                      <EmptyState
                        title={t('activity_empty_title')}
                        description={t('activity_empty')}
                        action={
                          walletData.referral_link ? (
                            <Button
                              variant="secondary"
                              size="sm"
                              onClick={() => void handleCopyLink(walletData.referral_link ?? '')}
                            >
                              {t('copy_link')}
                            </Button>
                          ) : undefined
                        }
                      />
                    ) : (
                      <Table className={density === 'dense' ? 'text-sm' : undefined}>
                        <Table.Head>
                          <Table.Row>
                            <Table.HeadCell className="pe-4 pb-2">
                              {t('activity_col_date')}
                            </Table.HeadCell>
                            <Table.HeadCell className="pe-4 pb-2">
                              {t('activity_col_type')}
                            </Table.HeadCell>
                            <Table.HeadCell className="pe-4 pb-2 text-end">
                              {t('activity_col_amount')}
                            </Table.HeadCell>
                            <Table.HeadCell className="pb-2">
                              <LabelWithTooltip
                                label={t('activity_col_status')}
                                tooltip={t('tooltip_activity_status')}
                              />
                            </Table.HeadCell>
                          </Table.Row>
                        </Table.Head>
                        <Table.Body>
                          {activityData.rows.map((row) => {
                            const statusLabel = enumLabel(
                              'affiliate_activity_status',
                              row.status,
                              locale as Locale,
                              'affiliate',
                            );
                            return (
                              <Table.Row key={row.id}>
                                <Table.Cell
                                  className={density === 'dense' ? 'py-1.5 pe-4' : 'py-2 pe-4'}
                                >
                                  {formatDate(row.created_at, locale)}
                                </Table.Cell>
                                <Table.Cell
                                  className={density === 'dense' ? 'py-1.5 pe-4' : 'py-2 pe-4'}
                                >
                                  {t(
                                    `activity_type_${row.entry_type}` as Parameters<typeof t>[0],
                                  ) || row.entry_type}
                                </Table.Cell>
                                <Table.Cell
                                  className={
                                    density === 'dense'
                                      ? 'py-1.5 pe-4 text-end tabular-nums'
                                      : 'py-2 pe-4 text-end tabular-nums'
                                  }
                                >
                                  {formatAgorotSigned(row.amount_agorot)}
                                </Table.Cell>
                                <Table.Cell className={density === 'dense' ? 'py-1.5' : 'py-2'}>
                                  {row.status === 'swept' ? (
                                    <LabelWithTooltip
                                      label={statusLabel}
                                      tooltip={t('tooltip_status_swept')}
                                    />
                                  ) : (
                                    statusLabel
                                  )}
                                </Table.Cell>
                              </Table.Row>
                            );
                          })}
                        </Table.Body>
                      </Table>
                    )}
                  </section>
                )}
              </QueryBoundary>

              <AffiliateWithdrawPanel
                pendingAgorot={walletData.pending_agorot}
                maturedAgorot={walletData.matured_agorot}
                minWithdrawalAgorot={walletData.min_withdrawal_agorot}
                connectStatus={walletData.affiliate_connect_status}
              />

              <section aria-label={tNav('support_center')}>
                <Button variant="ghost" size="sm" asChild>
                  <a href="/support/tickets/new?agentDef=affiliate-support">
                    {tNav('support_center')}
                  </a>
                </Button>
              </section>
            </div>
          );
        }}
      </QueryBoundary>

      <Toast tone="success" open={linkCopied} onOpenChange={setLinkCopied} duration={3000}>
        <ToastTitle>{t('link_copied')}</ToastTitle>
      </Toast>
      <ToastViewport />
    </ToastProvider>
  );
}
