// @design-system: overlays/FreezeDialog
// Shared admin freeze dialog — consistent DOM for E2E selectors across all admin pages.
// Satisfies: getByRole('dialog'), getByRole('textbox', {name:/reason/i}),
//            getByRole('button', {name:/freeze/i}), role="alert" on error.

'use client';

import { useState } from 'react';
import { getCsrfToken } from '@/lib/csrf';
import { captureCaught } from '@/lib/observability';
import { fetchWithRefresh } from '@/lib/api/refresh-on-401';
import { useT } from '@/lib/i18n/react';
import { Button } from '@/components/ui/primitives/Button';
import { Label } from '@/components/ui/primitives/Label';
import { Textarea } from '@/components/ui/primitives/Textarea';
import { Input } from '@/components/ui/primitives/Input';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/overlays/Dialog';

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

export interface FreezeDialogProps {
  /** API entity segment — posts to /api/admin/${entityType}s/${entityId}/freeze */
  entityType: 'user' | 'vendor';
  entityId: string;
  isOpen: boolean;
  onClose: () => void;
  onSuccess?: () => void;
  /** Override dialog title (defaults to admin namespace 'freeze') */
  title?: string;
  /** Optional descriptive text rendered below title */
  description?: string;
  /** Show the optional duration-in-days field (vendor freeze uses this) */
  showDuration?: boolean;
}

// ─── Component ────────────────────────────────────────────────────────────────

export function FreezeDialog({
  entityType,
  entityId,
  isOpen,
  onClose,
  onSuccess,
  title,
  description,
  showDuration = false,
}: FreezeDialogProps) {
  const tAdmin = useT('admin');

  const [reason, setReason] = useState('');
  const [durationDays, setDurationDays] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  function handleClose() {
    setReason('');
    setDurationDays('');
    setError(null);
    onClose();
  }

  async function handleSubmit() {
    if (!reason.trim()) return;
    setLoading(true);
    setError(null);
    try {
      const parsedDuration = durationDays ? parseInt(durationDays, 10) : undefined;
      const body: Record<string, unknown> = { reason: reason.trim() };
      if (showDuration && parsedDuration !== undefined && !isNaN(parsedDuration)) {
        body.durationDays = parsedDuration;
      }
      const res = await fetchWithRefresh(`/api/admin/${entityType}s/${entityId}/freeze`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'x-csrf-token': getCsrfToken() },
        body: JSON.stringify(body),
      });
      if (!res.ok) {
        const json = (await res.json().catch((err) => {
          captureCaught(err, { scope: 'FreezeDialog.submit' });
          return {};
        })) as Record<string, unknown>;
        throw new Error((json.error as string) || `HTTP ${res.status}`);
      }
      handleClose();
      onSuccess?.();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setLoading(false);
    }
  }

  const resolvedTitle = title ?? tAdmin('freeze');
  const reasonId = `freeze-dialog-reason-${entityType}-${entityId}`;
  const durationId = `freeze-dialog-duration-${entityType}-${entityId}`;

  return (
    <Dialog
      open={isOpen}
      onOpenChange={(open) => {
        if (!open) handleClose();
      }}
    >
      <DialogContent>
        <DialogHeader>
          <DialogTitle>{resolvedTitle}</DialogTitle>
          {description && <DialogDescription>{description}</DialogDescription>}
        </DialogHeader>

        <div className="flex flex-col gap-4">
          {/* Reason — must match getByRole('textbox', {name:/reason/i}) */}
          <div className="flex flex-col gap-1">
            <Label htmlFor={reasonId}>{tAdmin('freeze_reason_label')}</Label>
            <Textarea
              id={reasonId}
              rows={3}
              value={reason}
              onChange={(e) => setReason(e.target.value)}
              placeholder={tAdmin('freeze_reason_placeholder')}
            />
          </div>

          {/* Optional duration field */}
          {showDuration && (
            <div className="flex flex-col gap-1">
              <Label htmlFor={durationId}>{tAdmin('freeze_duration_label')}</Label>
              <Input
                id={durationId}
                type="number"
                min={1}
                max={3650}
                value={durationDays}
                onChange={(e) => setDurationDays(e.target.value)}
                placeholder={tAdmin('freeze_duration_placeholder')}
              />
            </div>
          )}

          {/* Error region — role="alert" for axe + E2E */}
          {error && (
            <p role="alert" className="text-danger-600 text-sm">
              {error}
            </p>
          )}
        </div>

        <DialogFooter>
          {/* Button text contains "Freeze" — satisfies getByRole('button', {name:/freeze/i}) */}
          <Button
            variant="danger"
            loading={loading}
            disabled={!reason.trim()}
            onClick={handleSubmit}
          >
            {tAdmin('freeze')}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
