'use client';
// @design-system: admin/BackfillModal/BackfillModal

/**
 * BackfillModal — admin component to start / monitor translation backfill.
 *
 * On open: fetches cost estimate. Shows deal count × chars × price estimate.
 * Start → POST backfill. Modal switches to progress bar polling every 5s.
 */

import { useState, useEffect, useRef, useCallback } from 'react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
  DialogClose,
} from '@/components/ui/overlays/Dialog';
import { Button } from '@/components/ui/primitives/Button';
import { FormField } from '@/components/ui/primitives/FormField';
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from '@/components/ui/primitives/Select';
import { useT, useLocale } from '@/lib/i18n/react';
import { interpolate } from '@/lib/i18n/interpolate';
import { formatInteger } from '@/lib/format';
import { getCsrfToken } from '@/lib/csrf';
import { fetchWithRefresh } from '@/lib/api/refresh-on-401';
import { captureCaught } from '@/lib/observability';
import type { StringBundle } from '@/lib/i18n/types';

export interface BackfillModalProps {
  open: boolean;
  locales: string[];
  onClose: () => void;
}

interface CostEstimate {
  dealCount: number;
  estimatedKchars: number;
  estimatedCostUsd: number;
  estimatedMinutes: number;
  pricePerKchar: number;
  ratePerMin: number;
}

interface Progress {
  locale: string;
  total: number;
  done: number;
  failed: number;
  pending: number;
  running: number;
  etaSeconds: number;
}

type AdminTranslationsT = ReturnType<typeof useT<keyof StringBundle & 'admin_translations'>>;

function localeLabel(t: AdminTranslationsT, code: string): string {
  const langKey = `lang_${code}` as Parameters<AdminTranslationsT>[0];
  const name = t(langKey);
  return name !== langKey ? `${name} (${code})` : code;
}

export function BackfillModal({ open, locales, onClose }: BackfillModalProps) {
  const t = useT('admin_translations');
  const { locale: uiLocale } = useLocale();
  const [locale, setLocale] = useState(locales[0] ?? 'en');
  const [ratePerMin, setRatePerMin] = useState(60);
  const [estimate, setEstimate] = useState<CostEstimate | null>(null);
  const [loadingEstimate, setLoadingEstimate] = useState(false);
  const [started, setStarted] = useState(false);
  const [starting, setStarting] = useState(false);
  const [progress, setProgress] = useState<Progress | null>(null);
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const loadEstimate = useCallback(
    async (signal: AbortSignal) => {
      setLoadingEstimate(true);
      try {
        const res = await fetchWithRefresh(
          `/api/admin/translations/backfill?locale=${locale}&estimate=1&ratePerMin=${ratePerMin}`,
          { signal },
        );
        const json = (await res.json()) as { ok: boolean; estimate?: CostEstimate };
        if (json.ok && json.estimate && !signal.aborted) setEstimate(json.estimate);
      } catch (err) {
        if (!signal.aborted) {
          captureCaught(err, { scope: 'BackfillModal.loadEstimate', severity: 'warning' });
        }
      } finally {
        if (!signal.aborted) setLoadingEstimate(false);
      }
    },
    [locale, ratePerMin],
  );

  useEffect(() => {
    if (!open) return;

    const controller = new AbortController();
    queueMicrotask(() => {
      if (controller.signal.aborted) return;
      setStarted(false);
      setProgress(null);
      void loadEstimate(controller.signal);
    });
    return () => controller.abort();
  }, [open, loadEstimate]);

  useEffect(() => {
    return () => {
      if (pollRef.current) clearInterval(pollRef.current);
    };
  }, []);

  async function handleStart() {
    setStarting(true);
    try {
      await fetchWithRefresh('/api/admin/translations/backfill', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': getCsrfToken() },
        body: JSON.stringify({ locale, ratePerMin }),
      });
      setStarted(true);
      pollRef.current = setInterval(async () => {
        try {
          const res = await fetchWithRefresh(`/api/admin/translations/backfill?locale=${locale}`);
          const json = (await res.json()) as { ok: boolean; progress?: Progress };
          if (json.ok && json.progress) setProgress(json.progress);
        } catch (err) {
          captureCaught(err, { scope: 'BackfillModal.pollProgress', severity: 'warning' });
        }
      }, 5000);
    } catch (err) {
      captureCaught(err, { scope: 'BackfillModal.handleStart', severity: 'warning' });
    } finally {
      setStarting(false);
    }
  }

  async function handlePause() {
    try {
      await fetchWithRefresh('/api/admin/translations/backfill', {
        method: 'DELETE',
        headers: { 'x-csrf-token': getCsrfToken() },
      });
      if (pollRef.current) clearInterval(pollRef.current);
    } catch (err) {
      captureCaught(err, { scope: 'BackfillModal.handlePause', severity: 'warning' });
    }
  }

  const pct = progress
    ? Math.round(((progress.done + progress.failed) / Math.max(progress.total, 1)) * 100)
    : 0;

  return (
    <Dialog
      open={open}
      onOpenChange={(v) => {
        if (!v) onClose();
      }}
    >
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{t('backfill_title')}</DialogTitle>
          {!started && <p className="text-text-muted text-sm">{t('backfill_description')}</p>}
        </DialogHeader>

        {!started ? (
          <div className="flex flex-col gap-4">
            <FormField label={t('backfill_locale')} htmlFor="backfill-locale">
              <Select value={locale} onValueChange={setLocale}>
                <SelectTrigger id="backfill-locale">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {locales.map((l) => (
                    <SelectItem key={l} value={l}>
                      {localeLabel(t, l)}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </FormField>

            <FormField
              label={t('backfill_rate')}
              tooltip={t('rate_tooltip')}
              htmlFor="backfill-rate"
            >
              <Select
                value={String(ratePerMin)}
                onValueChange={(v) => setRatePerMin(parseInt(v, 10))}
              >
                <SelectTrigger id="backfill-rate">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {[10, 30, 60, 120, 300].map((r) => (
                    <SelectItem key={r} value={String(r)}>
                      {r} {t('per_min')}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </FormField>

            {loadingEstimate && <p className="text-text-muted text-sm">{t('loading_estimate')}</p>}
            {estimate && !loadingEstimate && (
              <div className="bg-surface-subtle rounded-lg p-4 text-sm">
                <p>
                  {interpolate(t('estimate_line'), {
                    cost: estimate.estimatedCostUsd.toFixed(2),
                    deals: estimate.dealCount,
                    chars: formatInteger(Math.round(estimate.estimatedKchars * 1000), uiLocale),
                  })}
                </p>
                <p>
                  {t('estimated_time')}: ~{estimate.estimatedMinutes.toFixed(1)} {t('minutes')}
                </p>
              </div>
            )}
          </div>
        ) : (
          <div className="flex flex-col gap-4">
            <p className="text-text-muted text-sm">
              {t('backfill_running')} {localeLabel(t, locale)}…
            </p>
            {progress && (
              <>
                <div
                  role="progressbar"
                  aria-valuenow={pct}
                  aria-valuemin={0}
                  aria-valuemax={100}
                  aria-label={t('backfill_progress_aria')}
                  className="bg-surface-subtle h-3 w-full overflow-hidden rounded-full"
                >
                  <div
                    className="bg-brand-primary-600 h-full transition-all"
                    style={{ width: `${pct}%` }}
                  />
                </div>
                <p className="text-text-muted text-sm">
                  {interpolate(t('progress_line'), {
                    done: progress.done,
                    total: progress.total,
                    failed: progress.failed,
                    minutes: Math.ceil(progress.etaSeconds / 60),
                  })}
                </p>
              </>
            )}
            <Button variant="secondary" onClick={handlePause}>
              {t('pause')}
            </Button>
          </div>
        )}

        <DialogFooter>
          <DialogClose asChild>
            <Button variant="ghost">{started ? t('close_keep_running') : t('cancel')}</Button>
          </DialogClose>
          {!started && (
            <Button variant="primary" disabled={starting || loadingEstimate} onClick={handleStart}>
              {starting ? t('starting') : t('start_backfill')}
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
