'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { toast } from 'sonner';
import { Globe, Plus, Pencil, Trash2, Languages, Search, X, ChevronLeft, ChevronRight, Check, Wand2, Loader2, Download, Upload } from 'lucide-react';
import { useLanguage } from '@client/contexts/LanguageContext';
import { usePageHeader } from '@client/contexts/PageHeaderContext';

interface Language {
  id: string;
  code: string;
  name: string;
  native_name: string;
  flag_emoji: string;
  is_rtl: boolean;
  is_active: boolean;
  is_default: boolean;
  display_order: number;
  translation_count: number;
}

interface TranslationKey {
  id: string;
  key: string;
  category: string;
  description: string;
  default_value: string;
  value: string;
}

type Modal = 'none' | 'add' | 'edit' | 'delete' | 'translations';

export default function AdminLanguagesPage() {
  const { t, bustCache } = useLanguage();
  usePageHeader(t('admin.languages.title', 'Languages'), t('admin.languages.subtitle', 'Manage platform languages and translations'));

  const [languages, setLanguages] = useState<Language[]>([]);
  const [totalKeys, setTotalKeys] = useState(0);
  const [loading, setLoading] = useState(true);
  const [modal, setModal] = useState<Modal>('none');
  const [selectedLang, setSelectedLang] = useState<Language | null>(null);
  const [aiTranslating, setAiTranslating] = useState<Record<string, boolean>>({});
  const [aiAvailable, setAiAvailable] = useState(false);
  const [exportingLang, setExportingLang] = useState<Record<string, boolean>>({});
  const [importingLang, setImportingLang] = useState<Record<string, boolean>>({});
  const importFileRef = useRef<HTMLInputElement>(null);
  const importTargetRef = useRef<Language | null>(null);

  // Translation editor state
  const [trKeys, setTrKeys] = useState<TranslationKey[]>([]);
  const [trCategories, setTrCategories] = useState<string[]>([]);
  const [trSearch, setTrSearch] = useState('');
  const [trCategory, setTrCategory] = useState('');
  const [trPage, setTrPage] = useState(1);
  const [trTotal, setTrTotal] = useState(0);
  const [trPages, setTrPages] = useState(1);
  const [trLoadingKeys, setTrLoadingKeys] = useState(false);
  const [trEdits, setTrEdits] = useState<Record<string, string>>({});
  const [trSaving, setTrSaving] = useState(false);
  const searchDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  // Add / Edit form
  const [form, setForm] = useState({ code: '', name: '', native_name: '', flag_emoji: '', is_rtl: false, copy_from: 'en' });
  const [formSaving, setFormSaving] = useState(false);

  const fetchLanguages = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch('/api/admin/languages');
      const data = await res.json() as { languages: Language[]; totalKeys: number };
      setLanguages(data.languages || []);
      setTotalKeys(data.totalKeys || 0);
    } catch {
      toast.error(t('admin.languages.errors.loadFailed', 'Failed to load languages'));
    } finally {
      setLoading(false);
    }
  }, [t]);

  async function handleAiTranslate(lang: Language) {
    if (lang.code === 'en') return;
    setAiTranslating(prev => ({ ...prev, [lang.code]: true }));
    try {
      const res = await fetch(`/api/admin/translations/${lang.code}/ai-translate`, { method: 'POST' });
      const data = await res.json() as { ok?: boolean; translated?: number; total?: number; message?: string; error?: string };
      if (!res.ok || !data.ok) {
        toast.error(data.error || t('admin.languages.errors.aiTranslateFailed', 'AI translation failed'));
        return;
      }
      if (data.translated === 0) {
        toast.info(data.message || t('admin.languages.errors.allTranslated', 'All keys are already translated'));
      } else {
        const count = data.translated ?? 0;
        const total = data.total ?? count;
        toast.success(t('admin.languages.success.aiTranslated', 'AI translated {{count}} of {{total}} key(s) into {{lang}}', { count, total, lang: lang.name }));
      }
      void fetchLanguages();
    } catch {
      toast.error(t('admin.languages.errors.aiTranslateServerFailed', 'AI translation failed — check server logs'));
    } finally {
      setAiTranslating(prev => ({ ...prev, [lang.code]: false }));
    }
  }

  async function handleExport(lang: Language) {
    setExportingLang(prev => ({ ...prev, [lang.code]: true }));
    try {
      const res = await fetch(`/api/admin/translations/${lang.code}/export`);
      if (!res.ok) {
        toast.error(t('admin.languages.errors.exportFailed', 'Export failed'));
        return;
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${lang.code}-translations.json`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
      toast.success(t('admin.languages.success.exported', '"{{name}}" translations exported', { name: lang.name }));
    } catch {
      toast.error(t('admin.languages.errors.exportFailed', 'Export failed'));
    } finally {
      setExportingLang(prev => ({ ...prev, [lang.code]: false }));
    }
  }

  function handleImportClick(lang: Language) {
    importTargetRef.current = lang;
    if (importFileRef.current) {
      importFileRef.current.value = '';
      importFileRef.current.click();
    }
  }

  async function handleImportFileChange(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    const lang = importTargetRef.current;
    if (!file || !lang) return;
    setImportingLang(prev => ({ ...prev, [lang.code]: true }));
    try {
      const text = await file.text();
      let payload: unknown;
      try {
        payload = JSON.parse(text);
      } catch {
        toast.error(t('admin.languages.errors.importInvalidJson', 'Import failed: invalid JSON file'));
        return;
      }
      if (typeof payload !== 'object' || payload === null || !('translations' in payload)) {
        toast.error(t('admin.languages.errors.importInvalidFormat', 'Import failed: file does not contain a valid translations export'));
        return;
      }
      const res = await fetch(`/api/admin/translations/${lang.code}/import`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: text,
      });
      const data = await res.json() as { ok?: boolean; imported?: number; error?: string };
      if (!res.ok || !data.ok) {
        toast.error(data.error || t('admin.languages.errors.importFailed', 'Import failed'));
        return;
      }
      toast.success(t('admin.languages.success.imported', 'Imported {{count}} translation(s) into "{{name}}"', { count: data.imported ?? 0, name: lang.name }));
      bustCache(lang.code);
      void fetchLanguages();
    } catch {
      toast.error(t('admin.languages.errors.importFailed', 'Import failed'));
    } finally {
      setImportingLang(prev => ({ ...prev, [lang.code]: false }));
      importTargetRef.current = null;
    }
  }

  useEffect(() => {
    void fetchLanguages();
    fetch('/api/admin/translations/ai-status')
      .then(r => r.json())
      .then((d: { available?: boolean }) => setAiAvailable(Boolean(d.available)))
      .catch(() => setAiAvailable(false));
  }, [fetchLanguages]);

  const fetchTranslationKeys = useCallback(async (lang: Language, page = 1, cat = '', search = '') => {
    setTrLoadingKeys(true);
    try {
      const params = new URLSearchParams({ page: String(page), limit: '50' });
      if (cat) params.set('category', cat);
      if (search) params.set('search', search);
      const res = await fetch(`/api/admin/translations/${lang.code}?${params}`);
      const data = await res.json() as {
        keys: TranslationKey[];
        categories: string[];
        pagination: { page: number; total: number; pages: number };
      };
      setTrKeys(data.keys || []);
      setTrCategories(data.categories || []);
      setTrTotal(data.pagination?.total || 0);
      setTrPages(data.pagination?.pages || 1);
    } catch {
      toast.error(t('admin.languages.errors.translationsLoadFailed', 'Failed to load translations'));
    } finally {
      setTrLoadingKeys(false);
    }
  }, [t]);

  function openAdd() {
    setForm({ code: '', name: '', native_name: '', flag_emoji: '', is_rtl: false, copy_from: 'en' });
    setModal('add');
  }

  function openEdit(lang: Language) {
    setSelectedLang(lang);
    setForm({ code: lang.code, name: lang.name, native_name: lang.native_name, flag_emoji: lang.flag_emoji, is_rtl: lang.is_rtl, copy_from: 'en' });
    setModal('edit');
  }

  function openDelete(lang: Language) {
    setSelectedLang(lang);
    setModal('delete');
  }

  function openTranslations(lang: Language) {
    setSelectedLang(lang);
    setTrEdits({});
    setTrSearch('');
    setTrCategory('');
    setTrPage(1);
    setModal('translations');
    void fetchTranslationKeys(lang, 1, '', '');
  }

  function closeModal() {
    setModal('none');
    setSelectedLang(null);
    setTrEdits({});
  }

  async function handleAdd() {
    if (!form.code.trim() || !form.name.trim() || !form.native_name.trim()) {
      toast.error(t('admin.languages.errors.fieldsRequired', 'Code, name, and native name are required'));
      return;
    }
    setFormSaving(true);
    try {
      const res = await fetch('/api/admin/languages', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(form),
      });
      if (!res.ok) {
        const err = await res.json() as { error?: string };
        toast.error(err.error || t('admin.languages.errors.addFailed', 'Failed to add language'));
        return;
      }
      toast.success(t('admin.languages.success.added', 'Language "{{name}}" added', { name: form.name }));
      closeModal();
      void fetchLanguages();
    } catch {
      toast.error(t('admin.languages.errors.addFailed', 'Failed to add language'));
    } finally {
      setFormSaving(false);
    }
  }

  async function handleEdit() {
    if (!selectedLang) return;
    setFormSaving(true);
    try {
      const res = await fetch(`/api/admin/languages/${selectedLang.code}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: form.name,
          native_name: form.native_name,
          flag_emoji: form.flag_emoji,
          is_rtl: form.is_rtl,
        }),
      });
      if (!res.ok) {
        const err = await res.json() as { error?: string };
        toast.error(err.error || t('admin.languages.errors.updateFailed', 'Failed to update language'));
        return;
      }
      toast.success(t('admin.languages.success.updated', 'Language updated'));
      closeModal();
      void fetchLanguages();
    } catch {
      toast.error(t('admin.languages.errors.updateFailed', 'Failed to update language'));
    } finally {
      setFormSaving(false);
    }
  }

  async function handleDelete() {
    if (!selectedLang) return;
    setFormSaving(true);
    try {
      const res = await fetch(`/api/admin/languages/${selectedLang.code}`, { method: 'DELETE' });
      if (!res.ok) {
        const err = await res.json() as { error?: string };
        toast.error(err.error || t('admin.languages.errors.deleteFailed', 'Failed to delete language'));
        return;
      }
      toast.success(t('admin.languages.success.deleted', 'Language "{{name}}" deleted', { name: selectedLang.name }));
      closeModal();
      void fetchLanguages();
    } catch {
      toast.error(t('admin.languages.errors.deleteFailed', 'Failed to delete language'));
    } finally {
      setFormSaving(false);
    }
  }

  async function handleSetDefault(lang: Language) {
    try {
      const res = await fetch(`/api/admin/languages/${lang.code}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ is_default: true }),
      });
      if (!res.ok) {
        toast.error(t('admin.languages.errors.setDefaultFailed', 'Failed to set default language'));
        return;
      }
      toast.success(t('admin.languages.success.defaultSet', '"{{name}}" is now the default language', { name: lang.name }));
      void fetchLanguages();
    } catch {
      toast.error(t('admin.languages.errors.setDefaultFailed', 'Failed to set default language'));
    }
  }

  async function handleToggleActive(lang: Language) {
    try {
      const res = await fetch(`/api/admin/languages/${lang.code}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ is_active: !lang.is_active }),
      });
      if (!res.ok) {
        toast.error(t('admin.languages.errors.updateFailed', 'Failed to update language'));
        return;
      }
      void fetchLanguages();
    } catch {
      toast.error(t('admin.languages.errors.updateFailed', 'Failed to update language'));
    }
  }

  async function handleSaveTranslations() {
    if (!selectedLang || Object.keys(trEdits).length === 0) {
      toast.info(t('admin.languages.errors.noChanges', 'No changes to save'));
      return;
    }
    setTrSaving(true);
    try {
      const res = await fetch(`/api/admin/translations/${selectedLang.code}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ translations: trEdits }),
      });
      if (!res.ok) {
        toast.error(t('admin.languages.errors.saveTranslationsFailed', 'Failed to save translations'));
        return;
      }
      const data = await res.json() as { updated: number };
      toast.success(t('admin.languages.success.translationsSaved', '{{count}} translation(s) saved', { count: data.updated }));
      setTrEdits({});
      void fetchTranslationKeys(selectedLang, trPage, trCategory, trSearch);
    } catch {
      toast.error(t('admin.languages.errors.saveTranslationsFailed', 'Failed to save translations'));
    } finally {
      setTrSaving(false);
    }
  }

  function handleTrSearch(value: string) {
    setTrSearch(value);
    setTrPage(1);
    if (searchDebounceRef.current) clearTimeout(searchDebounceRef.current);
    searchDebounceRef.current = setTimeout(() => {
      if (selectedLang) void fetchTranslationKeys(selectedLang, 1, trCategory, value);
    }, 300);
  }

  function handleTrCategory(value: string) {
    setTrCategory(value);
    setTrPage(1);
    if (selectedLang) void fetchTranslationKeys(selectedLang, 1, value, trSearch);
  }

  function handleTrPage(p: number) {
    setTrPage(p);
    if (selectedLang) void fetchTranslationKeys(selectedLang, p, trCategory, trSearch);
  }

  return (
    <div className="space-y-6">
      {/* Hidden file input for import */}
      <input
        ref={importFileRef}
        type="file"
        accept=".json,application/json"
        className="hidden"
        onChange={handleImportFileChange}
      />

      <div className="flex items-start justify-between">
        <div>
          <h1 className="text-2xl font-semibold text-[hsl(var(--foreground))] tracking-tight">{t('admin.languages.title', 'Languages')}</h1>
          <p className="text-sm text-[hsl(var(--muted-foreground))] mt-1">{t('admin.languages.subtitle', 'Manage platform languages and translations')}</p>
        </div>
        <button
          onClick={openAdd}
          className="flex items-center gap-2 px-4 py-2 rounded-lg bg-[hsl(var(--primary))] text-white text-sm font-medium hover:opacity-90 transition-opacity"
        >
          <Plus size={16} />
          {t('admin.languages.addLanguage', 'Add Language')}
        </button>
      </div>

      {/* Language list */}
      <div className="bg-white rounded-xl border border-[hsl(var(--border))] overflow-hidden">
        {loading ? (
          <div className="p-12 text-center text-sm text-[hsl(var(--muted-foreground))]">{t('common.loadingDots', 'Loading…')}</div>
        ) : languages.length === 0 ? (
          <div className="p-12 text-center">
            <Globe size={40} className="mx-auto text-[hsl(var(--muted-foreground))] mb-3 opacity-40" />
            <p className="text-sm text-[hsl(var(--muted-foreground))]">{t('admin.languages.noLanguages', 'No languages configured yet.')}</p>
          </div>
        ) : (
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b border-[hsl(var(--border))] bg-[hsl(var(--muted))]">
                <th className="px-5 py-3 text-left font-medium text-[hsl(var(--muted-foreground))]">{t('admin.languages.colLanguage', 'Language')}</th>
                <th className="px-5 py-3 text-left font-medium text-[hsl(var(--muted-foreground))]">{t('admin.languages.colCode', 'Code')}</th>
                <th className="px-5 py-3 text-left font-medium text-[hsl(var(--muted-foreground))]">{t('admin.languages.colTranslations', 'Translations')}</th>
                <th className="px-5 py-3 text-left font-medium text-[hsl(var(--muted-foreground))]">{t('common.status', 'Status')}</th>
                <th className="px-5 py-3 text-right font-medium text-[hsl(var(--muted-foreground))]">{t('common.actions', 'Actions')}</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-[hsl(var(--border))]">
              {languages.map(lang => (
                <tr key={lang.code} className="hover:bg-[hsl(var(--muted)/0.3)] transition-colors">
                  <td className="px-5 py-3.5">
                    <div className="flex items-center gap-3">
                      <span className="text-2xl">{lang.flag_emoji}</span>
                      <div>
                        <div className="font-medium text-[hsl(var(--foreground))]">{lang.name}</div>
                        <div className="text-xs text-[hsl(var(--muted-foreground))]">{lang.native_name}</div>
                      </div>
                      {lang.is_default && (
                        <span className="px-1.5 py-0.5 rounded text-[10px] font-semibold bg-[hsl(var(--primary-light))] text-[hsl(var(--primary))]">{t('admin.languages.badge.default', 'DEFAULT')}</span>
                      )}
                      {lang.is_rtl && (
                        <span className="px-1.5 py-0.5 rounded text-[10px] font-semibold bg-amber-50 text-amber-700">{t('admin.languages.badge.rtl', 'RTL')}</span>
                      )}
                    </div>
                  </td>
                  <td className="px-5 py-3.5 font-mono text-[hsl(var(--muted-foreground))]">{lang.code}</td>
                  <td className="px-5 py-3.5">
                    {(() => {
                      const count = Number(lang.translation_count);
                      const pct = totalKeys > 0 ? Math.round((count / totalKeys) * 100) : 0;
                      const barColor = pct >= 90 ? 'hsl(var(--success))' : pct >= 50 ? 'hsl(var(--warning))' : 'hsl(var(--danger))';
                      return (
                        <div className="flex items-center gap-2 min-w-[120px]">
                          <div className="flex-1 h-1.5 rounded-full bg-[hsl(var(--border))] overflow-hidden">
                            <div className="h-full rounded-full transition-all duration-500" style={{ width: `${pct}%`, backgroundColor: barColor }} />
                          </div>
                          <span className="text-xs font-semibold tabular-nums" style={{ color: barColor, minWidth: '36px' }}>
                            {pct}%
                          </span>
                        </div>
                      );
                    })()}
                  </td>
                  <td className="px-5 py-3.5">
                    <button
                      onClick={() => handleToggleActive(lang)}
                      className={`px-2 py-0.5 rounded-full text-xs font-medium transition-colors ${lang.is_active ? 'bg-[hsl(var(--success-bg))] text-[hsl(var(--success))]' : 'bg-[hsl(var(--muted))] text-[hsl(var(--muted-foreground))]'}`}
                    >
                      {lang.is_active ? t('common.active', 'Active') : t('common.inactive', 'Inactive')}
                    </button>
                  </td>
                  <td className="px-5 py-3.5">
                    <div className="flex items-center justify-end gap-2">
                      {!lang.is_default && (
                        <button
                          onClick={() => handleSetDefault(lang)}
                          title={t("admin.languages.actions.setDefault", "Set as default")}
                          className="p-1.5 rounded-md text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--primary))] hover:bg-[hsl(var(--primary-light))] transition-colors"
                        >
                          <Check size={15} />
                        </button>
                      )}
                      {lang.code !== 'en' && (
                        <button
                          onClick={() => aiAvailable && !aiTranslating[lang.code] && void handleAiTranslate(lang)}
                          disabled={!aiAvailable || aiTranslating[lang.code]}
                          title={aiAvailable ? t('admin.languages.actions.autoTranslate', 'Auto-translate missing strings with AI') : t('admin.languages.actions.autoTranslateUnavailable', 'OPENAI_API_KEY is not configured')}
                          className="p-1.5 rounded-md text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--primary))] hover:bg-[hsl(var(--primary-light))] transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
                        >
                          {aiTranslating[lang.code]
                            ? <Loader2 size={15} className="animate-spin" />
                            : <Wand2 size={15} />}
                        </button>
                      )}
                      <button
                        onClick={() => !exportingLang[lang.code] && void handleExport(lang)}
                        disabled={exportingLang[lang.code]}
                        title={t('admin.languages.actions.exportTranslations', 'Export translations as JSON')}
                        className="p-1.5 rounded-md text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--muted))] transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
                      >
                        {exportingLang[lang.code]
                          ? <Loader2 size={15} className="animate-spin" />
                          : <Download size={15} />}
                      </button>
                      <button
                        onClick={() => !importingLang[lang.code] && handleImportClick(lang)}
                        disabled={importingLang[lang.code]}
                        title={t('admin.languages.actions.importTranslations', 'Import translations from JSON')}
                        className="p-1.5 rounded-md text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--muted))] transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
                      >
                        {importingLang[lang.code]
                          ? <Loader2 size={15} className="animate-spin" />
                          : <Upload size={15} />}
                      </button>
                      <button
                        onClick={() => openTranslations(lang)}
                        title={t("admin.languages.actions.editTranslations", "Edit translations")}
                        className="p-1.5 rounded-md text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--muted))] transition-colors"
                      >
                        <Languages size={15} />
                      </button>
                      <button
                        onClick={() => openEdit(lang)}
                        title={t("admin.languages.actions.editLanguage", "Edit language")}
                        className="p-1.5 rounded-md text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] hover:bg-[hsl(var(--muted))] transition-colors"
                      >
                        <Pencil size={15} />
                      </button>
                      {!lang.is_default && lang.code !== 'en' && (
                        <button
                          onClick={() => openDelete(lang)}
                          title={t("admin.languages.actions.deleteLanguage", "Delete language")}
                          className="p-1.5 rounded-md text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--danger))] hover:bg-[hsl(var(--danger-bg))] transition-colors"
                        >
                          <Trash2 size={15} />
                        </button>
                      )}
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {/* ── Add Modal ── */}
      {modal === 'add' && (
        <ModalWrapper title={t('admin.languages.addLanguage', 'Add Language')} onClose={closeModal}>
          <LanguageForm
            form={form}
            setForm={setForm}
            showCode
            showCopyFrom
            existingLanguages={languages}
            t={t}
          />
          <ModalFooter
            onCancel={closeModal}
            onConfirm={handleAdd}
            confirmLabel={t('admin.languages.addLanguage', 'Add Language')}
            cancelLabel={t('common.cancel', 'Cancel')}
            saving={formSaving}
            savingLabel={t('common.savingDots', 'Saving…')}
          />
        </ModalWrapper>
      )}

      {/* ── Edit Modal ── */}
      {modal === 'edit' && selectedLang && (
        <ModalWrapper title={`${t('admin.languages.edit', 'Edit')} — ${selectedLang.name}`} onClose={closeModal}>
          <LanguageForm form={form} setForm={setForm} showCode={false} showCopyFrom={false} existingLanguages={[]} t={t} />
          <ModalFooter
            onCancel={closeModal}
            onConfirm={handleEdit}
            confirmLabel={t('admin.languages.saveChanges', 'Save Changes')}
            cancelLabel={t('common.cancel', 'Cancel')}
            saving={formSaving}
            savingLabel={t('common.savingDots', 'Saving…')}
          />
        </ModalWrapper>
      )}

      {/* ── Delete Modal ── */}
      {modal === 'delete' && selectedLang && (
        <ModalWrapper title={t('admin.languages.deleteLanguage', 'Delete Language')} onClose={closeModal}>
          <p className="text-sm text-[hsl(var(--foreground-secondary))]">
            {t('admin.languages.deleteConfirm', 'Are you sure you want to delete')} <strong>{selectedLang.name}</strong>? {t('admin.languages.deleteWarning', 'All its translations will be permanently removed.')}
          </p>
          <ModalFooter
            onCancel={closeModal}
            onConfirm={handleDelete}
            confirmLabel={t('admin.languages.deleteLanguage', 'Delete Language')}
            cancelLabel={t('common.cancel', 'Cancel')}
            saving={formSaving}
            savingLabel={t('common.savingDots', 'Saving…')}
            danger
          />
        </ModalWrapper>
      )}

      {/* ── Translations Editor Modal ── */}
      {modal === 'translations' && selectedLang && (
        <div className="fixed inset-0 z-50 flex items-stretch justify-end bg-black/40" onClick={closeModal}>
          <div
            className="w-full max-w-3xl bg-white flex flex-col h-full shadow-2xl"
            onClick={e => e.stopPropagation()}
          >
            {/* Header */}
            <div className="flex items-center justify-between px-6 py-4 border-b border-[hsl(var(--border))]">
              <div className="flex items-center gap-3">
                <span className="text-2xl">{selectedLang.flag_emoji}</span>
                <div>
                  <h2 className="font-semibold text-[hsl(var(--foreground))]">{t('admin.languages.translationsFor', 'Translations')} — {selectedLang.name}</h2>
                  <p className="text-xs text-[hsl(var(--muted-foreground))]">{trTotal} {t('admin.languages.keysTotal', 'keys total')}</p>
                </div>
              </div>
              <button onClick={closeModal} className="p-2 rounded-lg hover:bg-[hsl(var(--muted))] transition-colors">
                <X size={18} />
              </button>
            </div>

            {/* Filters */}
            <div className="px-6 py-3 border-b border-[hsl(var(--border))] flex gap-3">
              <div className="relative flex-1">
                <Search size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-[hsl(var(--muted-foreground))]" />
                <input
                  value={trSearch}
                  onChange={e => handleTrSearch(e.target.value)}
                  placeholder={t('admin.languages.searchKeys', 'Search keys…')}
                  className="w-full pl-9 pr-3 py-2 rounded-lg border border-[hsl(var(--border))] text-sm focus:outline-none focus:ring-2 focus:ring-[hsl(var(--primary)/0.3)]"
                />
              </div>
              <select
                value={trCategory}
                onChange={e => handleTrCategory(e.target.value)}
                className="px-3 py-2 rounded-lg border border-[hsl(var(--border))] text-sm focus:outline-none focus:ring-2 focus:ring-[hsl(var(--primary)/0.3)] bg-white"
              >
                <option value="">{t('admin.languages.allCategories', 'All Categories')}</option>
                {trCategories.map(c => (
                  <option key={c} value={c}>{c}</option>
                ))}
              </select>
            </div>

            {/* Unsaved changes banner */}
            {Object.keys(trEdits).length > 0 && (
              <div className="px-6 py-2 bg-amber-50 border-b border-amber-200 flex items-center justify-between">
                <span className="text-xs text-amber-700 font-medium">{Object.keys(trEdits).length} {t('admin.languages.unsavedChanges', 'unsaved change(s)')}</span>
                <button
                  onClick={handleSaveTranslations}
                  disabled={trSaving}
                  className="px-3 py-1 rounded-md bg-amber-600 text-white text-xs font-medium hover:bg-amber-700 transition-colors disabled:opacity-50"
                >
                  {trSaving ? t('common.savingDots', 'Saving…') : t('common.saveNow', 'Save Now')}
                </button>
              </div>
            )}

            {/* Keys list */}
            <div className="flex-1 overflow-y-auto">
              {trLoadingKeys ? (
                <div className="p-8 text-center text-sm text-[hsl(var(--muted-foreground))]">Loading…</div>
              ) : trKeys.length === 0 ? (
                <div className="p-8 text-center text-sm text-[hsl(var(--muted-foreground))]">No translation keys found.</div>
              ) : (
                <div className="divide-y divide-[hsl(var(--border))]">
                  {trKeys.map(k => {
                    const editedValue = trEdits[k.key];
                    const displayValue = editedValue !== undefined ? editedValue : k.value;
                    const isEdited = editedValue !== undefined && editedValue !== k.value;
                    return (
                      <div key={k.id} className={`px-6 py-3 ${isEdited ? 'bg-amber-50/60' : ''}`}>
                        <div className="flex items-baseline justify-between mb-1.5">
                          <div className="flex items-center gap-2">
                            <span className="font-mono text-xs text-[hsl(var(--muted-foreground))]">{k.key}</span>
                            <span className="px-1.5 py-0.5 rounded text-[10px] bg-[hsl(var(--muted))] text-[hsl(var(--muted-foreground))]">{k.category}</span>
                          </div>
                          {isEdited && (
                            <span className="text-[10px] font-medium text-amber-600">edited</span>
                          )}
                        </div>
                        <div className="text-xs text-[hsl(var(--muted-foreground))] mb-1.5 italic">{k.default_value}</div>
                        <input
                          value={displayValue}
                          onChange={e => setTrEdits(prev => ({ ...prev, [k.key]: e.target.value }))}
                          className="w-full px-3 py-2 rounded-lg border border-[hsl(var(--border))] text-sm focus:outline-none focus:ring-2 focus:ring-[hsl(var(--primary)/0.3)] bg-white"
                          dir={selectedLang.is_rtl ? 'rtl' : 'ltr'}
                        />
                      </div>
                    );
                  })}
                </div>
              )}
            </div>

            {/* Pagination + save */}
            <div className="px-6 py-3 border-t border-[hsl(var(--border))] flex items-center justify-between">
              <div className="flex items-center gap-2">
                <button
                  onClick={() => handleTrPage(Math.max(1, trPage - 1))}
                  disabled={trPage <= 1}
                  className="p-1.5 rounded-md border border-[hsl(var(--border))] disabled:opacity-40 hover:bg-[hsl(var(--muted))] transition-colors"
                >
                  <ChevronLeft size={14} />
                </button>
                <span className="text-xs text-[hsl(var(--muted-foreground))]">{t('common.page', 'Page')} {trPage} {t('common.of', 'of')} {trPages}</span>
                <button
                  onClick={() => handleTrPage(Math.min(trPages, trPage + 1))}
                  disabled={trPage >= trPages}
                  className="p-1.5 rounded-md border border-[hsl(var(--border))] disabled:opacity-40 hover:bg-[hsl(var(--muted))] transition-colors"
                >
                  <ChevronRight size={14} />
                </button>
              </div>
              <button
                onClick={handleSaveTranslations}
                disabled={trSaving || Object.keys(trEdits).length === 0}
                className="flex items-center gap-2 px-4 py-2 rounded-lg bg-[hsl(var(--primary))] text-white text-sm font-medium hover:opacity-90 transition-opacity disabled:opacity-40"
              >
                {trSaving ? t('common.savingDots', 'Saving…') : t('admin.languages.saveTranslations', 'Save Translations')}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── Helpers ──────────────────────────────────────────────────────────────────

function ModalWrapper({ title, onClose, children }: { title: string; onClose: () => void; children: React.ReactNode }) {
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40" onClick={onClose}>
      <div
        className="w-full max-w-md bg-white rounded-2xl shadow-2xl p-6 space-y-5"
        onClick={e => e.stopPropagation()}
      >
        <div className="flex items-center justify-between">
          <h2 className="font-semibold text-[hsl(var(--foreground))] text-lg">{title}</h2>
          <button onClick={onClose} className="p-1.5 rounded-lg hover:bg-[hsl(var(--muted))] transition-colors">
            <X size={16} />
          </button>
        </div>
        {children}
      </div>
    </div>
  );
}

type TFn = (key: string, fallback: string) => string;

function LanguageForm({
  form,
  setForm,
  showCode,
  showCopyFrom,
  existingLanguages,
  t,
}: {
  form: { code: string; name: string; native_name: string; flag_emoji: string; is_rtl: boolean; copy_from: string };
  setForm: (f: typeof form) => void;
  showCode: boolean;
  showCopyFrom: boolean;
  existingLanguages: Language[];
  t: TFn;
}) {
  return (
    <div className="space-y-4">
      {showCode && (
        <Field label={t('admin.languages.form.code', 'Language Code')} hint={t('admin.languages.form.codeHint', '2-5 lowercase letters, e.g. en, fr, zh')}>
          <input
            value={form.code}
            onChange={e => setForm({ ...form, code: e.target.value.toLowerCase() })}
            placeholder={t("admin.languages.form.codePlaceholder", "e.g. fr")}
            className="input-field"
          />
        </Field>
      )}
      <Field label={t('admin.languages.form.name', 'Language Name')}>
        <input value={form.name} onChange={e => setForm({ ...form, name: e.target.value })} placeholder={t("admin.languages.form.namePlaceholder", "e.g. French")} className="input-field" />
      </Field>
      <Field label={t('admin.languages.form.nativeName', 'Native Name')}>
        <input value={form.native_name} onChange={e => setForm({ ...form, native_name: e.target.value })} placeholder={t("admin.languages.form.nativeNamePlaceholder", "e.g. Français")} className="input-field" />
      </Field>
      <Field label={t('admin.languages.form.flag', 'Flag Emoji')}>
        <input value={form.flag_emoji} onChange={e => setForm({ ...form, flag_emoji: e.target.value })} placeholder={t("admin.languages.form.flagPlaceholder", "e.g. 🇫🇷")} className="input-field" />
      </Field>
      <div className="flex items-center gap-3">
        <label className="flex items-center gap-2 cursor-pointer select-none">
          <div
            onClick={() => setForm({ ...form, is_rtl: !form.is_rtl })}
            className={`w-9 h-5 rounded-full transition-colors ${form.is_rtl ? 'bg-[hsl(var(--primary))]' : 'bg-[hsl(var(--border-strong))]'} relative`}
          >
            <div className={`absolute top-0.5 h-4 w-4 rounded-full bg-white shadow transition-transform ${form.is_rtl ? 'translate-x-4' : 'translate-x-0.5'}`} />
          </div>
          <span className="text-sm text-[hsl(var(--foreground-secondary))]">{t('admin.languages.form.rtl', 'Right-to-Left (RTL)')}</span>
        </label>
      </div>
      {showCopyFrom && (
        <Field label={t('admin.languages.form.copyFrom', 'Copy translations from')}>
          <select
            value={form.copy_from}
            onChange={e => setForm({ ...form, copy_from: e.target.value })}
            className="input-field"
          >
            {existingLanguages.map(l => (
              <option key={l.code} value={l.code}>{l.flag_emoji} {l.name} ({l.code})</option>
            ))}
          </select>
        </Field>
      )}
    </div>
  );
}

function Field({ label, hint, children }: { label: string; hint?: string; children: React.ReactNode }) {
  return (
    <div className="space-y-1.5">
      <label className="block text-sm font-medium text-[hsl(var(--foreground-secondary))]">{label}{hint && <span className="ml-1.5 font-normal text-[hsl(var(--muted-foreground))]">({hint})</span>}</label>
      {children}
    </div>
  );
}

function ModalFooter({
  onCancel,
  onConfirm,
  confirmLabel,
  cancelLabel = 'Cancel',
  savingLabel = 'Saving…',
  saving,
  danger = false,
}: {
  onCancel: () => void;
  onConfirm: () => void;
  confirmLabel: string;
  cancelLabel?: string;
  savingLabel?: string;
  saving: boolean;
  danger?: boolean;
}) {
  return (
    <div className="flex items-center justify-end gap-3 pt-2">
      <button onClick={onCancel} className="px-4 py-2 rounded-lg border border-[hsl(var(--border))] text-sm font-medium hover:bg-[hsl(var(--muted))] transition-colors">
        {cancelLabel}
      </button>
      <button
        onClick={onConfirm}
        disabled={saving}
        className={`px-4 py-2 rounded-lg text-white text-sm font-medium transition-opacity disabled:opacity-50 ${danger ? 'bg-[hsl(var(--danger))]' : 'bg-[hsl(var(--primary))]'} hover:opacity-90`}
      >
        {saving ? savingLabel : confirmLabel}
      </button>
    </div>
  );
}
