'use client';

import { useState, useMemo } from 'react';
import { AlertTriangle, Copy, Check, CheckCircle2 } from 'lucide-react';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useI18n } from '@/lib/i18n';
import type { ApiKeyCreateResponse } from './types';

const MAX_KEY_NAME_LENGTH = 100;
const VALID_KEY_NAME_REGEX = /^[a-zA-Z0-9\s\-_]+$/;

interface GenerateKeyDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onGenerate: (name?: string) => Promise<ApiKeyCreateResponse>;
  isGenerating: boolean;
  maxKeysReached: boolean;
}

interface ValidationResult {
  isValid: boolean;
  error: string | null;
}

export function GenerateKeyDialog({
  open,
  onOpenChange,
  onGenerate,
  isGenerating,
  maxKeysReached,
}: GenerateKeyDialogProps) {
  const { t } = useI18n();
  const [step, setStep] = useState<'name' | 'result'>('name');
  const [keyName, setKeyName] = useState('');
  const [generatedKey, setGeneratedKey] = useState<ApiKeyCreateResponse | null>(null);
  const [copied, setCopied] = useState(false);
  const [touched, setTouched] = useState(false);

  const validation = useMemo<ValidationResult>(() => {
    const trimmedName = keyName.trim();

    if (trimmedName.length > MAX_KEY_NAME_LENGTH) {
      return { isValid: false, error: t('apiKeys.dialog.nameTooLong', { max: MAX_KEY_NAME_LENGTH }) };
    }

    if (trimmedName && !VALID_KEY_NAME_REGEX.test(trimmedName)) {
      return {
        isValid: false,
        error: t('apiKeys.dialog.nameInvalid'),
      };
    }

    return { isValid: true, error: null };
  }, [keyName]); // eslint-disable-line react-hooks/exhaustive-deps

  const handleGenerate = async () => {
    if (!validation.isValid) return;

    try {
      const result = await onGenerate(keyName.trim() || undefined);
      setGeneratedKey(result);
      setStep('result');
      setKeyName('');
      setTouched(false);
    } catch {
      onOpenChange(false);
    }
  };

  const copyKey = () => {
    if (generatedKey?.key) {
      navigator.clipboard.writeText(generatedKey.key);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  };

  const handleClose = () => {
    setStep('name');
    setGeneratedKey(null);
    setCopied(false);
    setKeyName('');
    onOpenChange(false);
  };

  if (maxKeysReached) {
    return (
      <Dialog open={open} onOpenChange={onOpenChange}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{t('apiKeys.dialog.maxTitle')}</DialogTitle>
            <DialogDescription>
              {t('apiKeys.dialog.maxDesc')}
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button onClick={() => onOpenChange(false)}>{t('apiKeys.dialog.close')}</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    );
  }

  if (step === 'result' && generatedKey) {
    return (
      <Dialog open={open} onOpenChange={handleClose}>
        <DialogContent className="sm:max-w-lg">
          <DialogHeader>
            <div className="flex items-center gap-3 mb-2">
              <div className="flex h-10 w-10 items-center justify-center rounded-full bg-accent/10">
                <CheckCircle2 className="h-5 w-5 text-accent" />
              </div>
              <DialogTitle>{t('apiKeys.dialog.generated')}</DialogTitle>
            </div>
            <DialogDescription>
              {t('apiKeys.dialog.generatedDesc')}
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            <div className="rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-900/50 dark:bg-amber-950/20">
              <div className="flex items-start gap-2">
                <AlertTriangle className="h-4 w-4 text-amber-600 dark:text-amber-500 mt-0.5 shrink-0" />
                <p className="text-sm text-amber-800 dark:text-amber-200">
                  <strong>{t('apiKeys.dialog.important')}</strong> {t('apiKeys.dialog.importantDesc')}
                </p>
              </div>
            </div>

            <div className="space-y-2">
              <Label htmlFor="apiKey">{t('apiKeys.dialog.apiKey')}</Label>
              <div className="flex gap-2">
                <Input
                  id="apiKey"
                  readOnly
                  value={generatedKey.key}
                  className="font-mono text-xs"
                />
                <Button onClick={copyKey} variant="outline" size="icon">
                  {copied ? (
                    <Check className="h-4 w-4 text-accent" />
                  ) : (
                    <Copy className="h-4 w-4" />
                  )}
                </Button>
              </div>
            </div>

            <div className="text-sm text-muted-foreground">
              <span className="font-medium">{t('apiKeys.dialog.name')}</span> {generatedKey.name}
            </div>
          </div>

          <DialogFooter>
            <Button onClick={handleClose}>
              {copied ? t('apiKeys.dialog.done') : t('apiKeys.dialog.copied')}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    );
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>{t('apiKeys.dialog.generateTitle')}</DialogTitle>
          <DialogDescription>
            {t('apiKeys.dialog.generateDesc')}
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="keyName">{t('apiKeys.dialog.keyName')}</Label>
            <Input
              id="keyName"
              placeholder={t('apiKeys.dialog.keyNamePlaceholder')}
              value={keyName}
              onChange={(e) => {
                setKeyName(e.target.value);
                setTouched(true);
              }}
              onBlur={() => setTouched(true)}
              maxLength={MAX_KEY_NAME_LENGTH + 10}
              className={touched && validation.error ? 'border-destructive' : ''}
              aria-invalid={touched && validation.error ? 'true' : 'false'}
              aria-describedby={touched && validation.error ? 'keyName-error' : undefined}
            />
            <p className="text-xs text-muted-foreground">
              {t('apiKeys.dialog.keyNameHint')}
              {keyName.length > 0 && (
                <span className="ms-2">({keyName.length}/{MAX_KEY_NAME_LENGTH})</span>
              )}
            </p>
            {touched && validation.error && (
              <p id="keyName-error" className="text-xs text-destructive">
                {validation.error}
              </p>
            )}
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            {t('apiKeys.dialog.cancel')}
          </Button>
          <Button onClick={handleGenerate} disabled={isGenerating || !validation.isValid}>
            {isGenerating ? t('apiKeys.dialog.generating') : t('apiKeys.dialog.generate')}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
