import { useCallback, useEffect, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import {
  adminLegalPagesApi,
  type FaqPageItem,
  type FaqSettingItem,
  type LegalDisplayMode,
} from '../api/adminLegalPages';
import { AdminBackButton } from '../components/admin';
import { Toggle } from '../components/admin/Toggle';
import { useHapticFeedback } from '../platform/hooks/useHaptic';
import { useDestructiveConfirm } from '../platform/hooks/useNativeDialog';
import { cn } from '../lib/utils';
import { ChevronDownIcon, ChevronUpIcon, PlusIcon, TrashIcon } from '@/components/icons';

type LegalTab = 'privacy' | 'offer' | 'recurrent' | 'rules' | 'faq';

const DISPLAY_MODES: LegalDisplayMode[] = ['bot', 'web', 'both'];

type DocumentKind = 'privacy-policy' | 'public-offer' | 'recurrent-payments';

// Bot chunk/page size (split_telegram_text max_length): longer texts are
// delivered by the bot in several messages / paginated pages
const TELEGRAM_SPLIT_THRESHOLD = 3500;

// Mirrors the bot's split_telegram_text greedy paragraph packing to estimate
// how many messages/pages the bot will produce for this text
function estimateTelegramParts(text: string): number {
  const normalized = text.replace(/\r\n/g, '\n').trim();
  if (!normalized) return 0;
  if (normalized.length <= TELEGRAM_SPLIT_THRESHOLD) return 1;
  const paragraphs = normalized.split('\n\n').filter((p) => p.trim());
  let parts = 0;
  let current = '';
  for (const paragraph of paragraphs) {
    const candidate = current ? `${current}\n\n${paragraph}` : paragraph;
    if (candidate.length <= TELEGRAM_SPLIT_THRESHOLD) {
      current = candidate;
      continue;
    }
    if (current) {
      parts += 1;
      current = '';
    }
    if (paragraph.length <= TELEGRAM_SPLIT_THRESHOLD) {
      current = paragraph;
    } else {
      parts += Math.ceil(paragraph.length / TELEGRAM_SPLIT_THRESHOLD);
    }
  }
  if (current) parts += 1;
  return parts;
}

function ContentLengthMeta({ text, botVisible }: { text: string; botVisible: boolean }) {
  const { t } = useTranslation();
  const parts = botVisible ? estimateTelegramParts(text) : 0;
  return (
    <div className="mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs">
      <span className="text-dark-500">
        {t('admin.legalPages.charCount', {
          count: text.length,
          defaultValue: 'Characters: {{count}}',
        })}
      </span>
      {parts > 1 && (
        <span className="text-warning-400">
          {t('admin.legalPages.botSplitEstimate', {
            count: parts,
            defaultValue: '⚠️ The bot will show it split into ~{{count}} messages',
          })}
        </span>
      )}
    </div>
  );
}

const DOCUMENT_API: Record<
  DocumentKind,
  {
    get: () => ReturnType<typeof adminLegalPagesApi.getPrivacyPolicy>;
    update: (
      data: Parameters<typeof adminLegalPagesApi.updatePrivacyPolicy>[0],
    ) => ReturnType<typeof adminLegalPagesApi.updatePrivacyPolicy>;
  }
> = {
  'privacy-policy': {
    get: adminLegalPagesApi.getPrivacyPolicy,
    update: adminLegalPagesApi.updatePrivacyPolicy,
  },
  'public-offer': {
    get: adminLegalPagesApi.getPublicOffer,
    update: adminLegalPagesApi.updatePublicOffer,
  },
  'recurrent-payments': {
    get: adminLegalPagesApi.getRecurrentPayments,
    update: adminLegalPagesApi.updateRecurrentPayments,
  },
};

function extractErrorDetail(err: unknown): string | null {
  const error = err as { response?: { data?: { detail?: unknown } } };
  const detail = error.response?.data?.detail;
  return typeof detail === 'string' ? detail : null;
}

function DisplayModeSelector({
  value,
  onChange,
  disabled,
}: {
  value: LegalDisplayMode;
  onChange: (mode: LegalDisplayMode) => void;
  disabled?: boolean;
}) {
  const { t } = useTranslation();
  return (
    <div>
      <label className="label">{t('admin.legalPages.displayMode')}</label>
      <div className="flex gap-1" role="radiogroup">
        {DISPLAY_MODES.map((mode) => (
          <button
            key={mode}
            type="button"
            role="radio"
            aria-checked={value === mode}
            disabled={disabled}
            onClick={() => onChange(mode)}
            className={cn(
              'min-h-[44px] rounded-lg px-4 py-2.5 text-sm font-medium transition-colors',
              value === mode
                ? 'bg-accent-500 text-on-accent'
                : 'bg-dark-700 text-dark-300 hover:bg-dark-600 hover:text-dark-100',
              disabled && 'cursor-not-allowed opacity-50',
            )}
          >
            {t(`admin.legalPages.displayModes.${mode}`)}
          </button>
        ))}
      </div>
      {disabled && (
        <p className="mt-1.5 text-xs text-dark-500">{t('admin.legalPages.displayModeLocked')}</p>
      )}
    </div>
  );
}

function LanguageTabs({
  languages,
  active,
  onChange,
}: {
  languages: string[];
  active: string;
  onChange: (lang: string) => void;
}) {
  const { t } = useTranslation();
  return (
    <div>
      <label className="label">{t('admin.legalPages.language')}</label>
      <div className="flex flex-wrap gap-1">
        {languages.map((lang) => (
          <button
            key={lang}
            type="button"
            onClick={() => onChange(lang)}
            className={cn(
              'min-h-[44px] rounded-lg px-4 py-2.5 text-sm font-medium uppercase transition-colors',
              active === lang
                ? 'bg-accent-500 text-on-accent'
                : 'bg-dark-700 text-dark-300 hover:bg-dark-600 hover:text-dark-100',
            )}
          >
            {lang}
          </button>
        ))}
      </div>
    </div>
  );
}

function DocumentEditor({
  kind,
  onDirtyChange,
}: {
  kind: DocumentKind;
  onDirtyChange: (dirty: boolean) => void;
}) {
  const { t } = useTranslation();
  const queryClient = useQueryClient();
  const haptic = useHapticFeedback();
  const [displayMode, setDisplayMode] = useState<LegalDisplayMode>('both');
  const [contents, setContents] = useState<Record<string, string>>({});
  const [enabled, setEnabled] = useState<Record<string, boolean>>({});
  const [activeLang, setActiveLang] = useState('ru');
  const [populated, setPopulated] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);

  const { data, isLoading, isFetching } = useQuery({
    queryKey: ['admin', 'legal-pages', kind],
    queryFn: () => DOCUMENT_API[kind].get(),
    staleTime: 0,
    gcTime: 0,
  });

  useEffect(() => {
    if (!data || isFetching || populated) return;
    setDisplayMode(data.display_mode);
    const nextContents: Record<string, string> = {};
    const nextEnabled: Record<string, boolean> = {};
    for (const item of data.items) {
      nextContents[item.language] = item.content;
      nextEnabled[item.language] = item.is_enabled;
    }
    setContents(nextContents);
    setEnabled(nextEnabled);
    if (data.items.length > 0 && !data.items.some((item) => item.language === 'ru')) {
      setActiveLang(data.items[0].language);
    }
    setPopulated(true);
  }, [data, isFetching, populated]);

  const isDirty =
    populated &&
    !!data &&
    (displayMode !== data.display_mode ||
      data.items.some(
        (item) =>
          (contents[item.language] ?? '') !== item.content ||
          (enabled[item.language] ?? false) !== item.is_enabled,
      ));

  useEffect(() => {
    onDirtyChange(isDirty);
  }, [isDirty, onDirtyChange]);

  const saveMutation = useMutation({
    mutationFn: () => {
      const payload = {
        ...(data?.display_mode_env_locked ? {} : { display_mode: displayMode }),
        items: Object.keys(contents).map((language) => ({
          language,
          content: contents[language] ?? '',
          is_enabled: enabled[language] ?? false,
        })),
      };
      return DOCUMENT_API[kind].update(payload);
    },
    onSuccess: () => {
      haptic.success();
      setSaveError(null);
      queryClient.invalidateQueries({ queryKey: ['admin', 'legal-pages', kind] });
    },
    onError: (err) => {
      haptic.error();
      setSaveError(extractErrorDetail(err) ?? t('admin.legalPages.saveError'));
    },
  });

  if (isLoading || !data) {
    return <div className="skeleton h-64 w-full rounded-xl" />;
  }

  const languages = data.items.map((item) => item.language);

  return (
    <div className="space-y-5">
      <DisplayModeSelector
        value={displayMode}
        onChange={setDisplayMode}
        disabled={data.display_mode_env_locked}
      />
      <LanguageTabs languages={languages} active={activeLang} onChange={setActiveLang} />
      <div className="flex items-center gap-3">
        <Toggle
          checked={enabled[activeLang] ?? false}
          onChange={() => setEnabled((prev) => ({ ...prev, [activeLang]: !prev[activeLang] }))}
          aria-label={t('admin.legalPages.enabled')}
        />
        <span className="text-sm text-dark-300">{t('admin.legalPages.enabled')}</span>
      </div>
      <div>
        <label className="label">{t('admin.legalPages.content')}</label>
        <textarea
          value={contents[activeLang] ?? ''}
          onChange={(e) => {
            setSaveError(null);
            setContents((prev) => ({ ...prev, [activeLang]: e.target.value }));
          }}
          rows={16}
          className="input min-h-[320px] w-full font-mono text-sm"
          placeholder={t('admin.legalPages.contentPlaceholder')}
        />
        <ContentLengthMeta
          text={contents[activeLang] ?? ''}
          botVisible={kind !== 'recurrent-payments' && displayMode !== 'web'}
        />
      </div>
      {saveError && <p className="text-sm text-error-400">{saveError}</p>}
      <button
        onClick={() => saveMutation.mutate()}
        disabled={saveMutation.isPending}
        className="min-h-[44px] rounded-lg bg-accent-500 px-6 py-2.5 text-sm font-medium text-on-accent transition-colors hover:bg-accent-600 disabled:opacity-50"
      >
        {saveMutation.isPending ? t('admin.legalPages.saving') : t('admin.legalPages.save')}
      </button>
    </div>
  );
}

function RulesEditor({ onDirtyChange }: { onDirtyChange: (dirty: boolean) => void }) {
  const { t } = useTranslation();
  const queryClient = useQueryClient();
  const haptic = useHapticFeedback();
  const [displayMode, setDisplayMode] = useState<LegalDisplayMode>('both');
  const [contents, setContents] = useState<Record<string, string>>({});
  const [activeLang, setActiveLang] = useState('ru');
  const [populated, setPopulated] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);

  const { data, isLoading, isFetching } = useQuery({
    queryKey: ['admin', 'legal-pages', 'rules'],
    queryFn: adminLegalPagesApi.getRules,
    staleTime: 0,
    gcTime: 0,
  });

  useEffect(() => {
    if (!data || isFetching || populated) return;
    setDisplayMode(data.display_mode);
    const nextContents: Record<string, string> = {};
    for (const item of data.items) {
      nextContents[item.language] = item.content;
    }
    setContents(nextContents);
    if (data.items.length > 0 && !data.items.some((item) => item.language === 'ru')) {
      setActiveLang(data.items[0].language);
    }
    setPopulated(true);
  }, [data, isFetching, populated]);

  const isDirty =
    populated &&
    !!data &&
    (displayMode !== data.display_mode ||
      data.items.some((item) => (contents[item.language] ?? '') !== item.content));

  useEffect(() => {
    onDirtyChange(isDirty);
  }, [isDirty, onDirtyChange]);

  const saveMutation = useMutation({
    mutationFn: () =>
      adminLegalPagesApi.updateRules({
        ...(data?.display_mode_env_locked ? {} : { display_mode: displayMode }),
        items: Object.keys(contents).map((language) => ({
          language,
          content: contents[language] ?? '',
        })),
      }),
    onSuccess: () => {
      haptic.success();
      setSaveError(null);
      queryClient.invalidateQueries({ queryKey: ['admin', 'legal-pages', 'rules'] });
    },
    onError: (err) => {
      haptic.error();
      setSaveError(extractErrorDetail(err) ?? t('admin.legalPages.saveError'));
    },
  });

  if (isLoading || !data) {
    return <div className="skeleton h-64 w-full rounded-xl" />;
  }

  const languages = data.items.map((item) => item.language);

  return (
    <div className="space-y-5">
      <DisplayModeSelector
        value={displayMode}
        onChange={setDisplayMode}
        disabled={data.display_mode_env_locked}
      />
      <LanguageTabs languages={languages} active={activeLang} onChange={setActiveLang} />
      <div>
        <label className="label">{t('admin.legalPages.content')}</label>
        <textarea
          value={contents[activeLang] ?? ''}
          onChange={(e) => {
            setSaveError(null);
            setContents((prev) => ({ ...prev, [activeLang]: e.target.value }));
          }}
          rows={16}
          className="input min-h-[320px] w-full font-mono text-sm"
          placeholder={t('admin.legalPages.contentPlaceholder')}
        />
        <ContentLengthMeta text={contents[activeLang] ?? ''} botVisible={displayMode !== 'web'} />
      </div>
      {saveError && <p className="text-sm text-error-400">{saveError}</p>}
      <button
        onClick={() => saveMutation.mutate()}
        disabled={saveMutation.isPending}
        className="min-h-[44px] rounded-lg bg-accent-500 px-6 py-2.5 text-sm font-medium text-on-accent transition-colors hover:bg-accent-600 disabled:opacity-50"
      >
        {saveMutation.isPending ? t('admin.legalPages.saving') : t('admin.legalPages.save')}
      </button>
    </div>
  );
}

function FaqQuestionRow({
  page,
  canMoveUp,
  canMoveDown,
  onMoveUp,
  onMoveDown,
  onDelete,
  onSaved,
  onDirtyChange,
}: {
  page: FaqPageItem;
  canMoveUp: boolean;
  canMoveDown: boolean;
  onMoveUp: () => void;
  onMoveDown: () => void;
  onDelete: () => void;
  onSaved: () => void;
  onDirtyChange: (id: number, dirty: boolean) => void;
}) {
  const { t } = useTranslation();
  const haptic = useHapticFeedback();
  const [title, setTitle] = useState(page.title);
  const [content, setContent] = useState(page.content);
  const [isActive, setIsActive] = useState(page.is_active);
  const [saveError, setSaveError] = useState<string | null>(null);

  const isDirty = title !== page.title || content !== page.content || isActive !== page.is_active;

  useEffect(() => {
    onDirtyChange(page.id, isDirty);
    return () => onDirtyChange(page.id, false);
  }, [page.id, isDirty, onDirtyChange]);

  const saveMutation = useMutation({
    mutationFn: () =>
      adminLegalPagesApi.updateFaqPage(page.id, { title, content, is_active: isActive }),
    onSuccess: () => {
      haptic.success();
      setSaveError(null);
      onSaved();
    },
    onError: (err) => {
      haptic.error();
      setSaveError(extractErrorDetail(err) ?? t('admin.legalPages.saveError'));
    },
  });

  return (
    <div className="space-y-3 rounded-xl border border-dark-700 bg-dark-800/50 p-4">
      <div className="flex items-center gap-2">
        <input
          value={title}
          onChange={(e) => {
            setSaveError(null);
            setTitle(e.target.value);
          }}
          className="input flex-1"
          placeholder={t('admin.legalPages.questionTitle')}
        />
        <Toggle
          checked={isActive}
          onChange={() => setIsActive((v) => !v)}
          aria-label={t('admin.legalPages.active')}
        />
        <button
          type="button"
          onClick={onMoveUp}
          disabled={!canMoveUp}
          className="min-h-[44px] min-w-[44px] rounded-lg p-2.5 text-dark-400 transition-colors hover:bg-dark-700 hover:text-dark-200 disabled:opacity-30"
          aria-label={t('admin.legalPages.moveUp')}
        >
          <ChevronUpIcon className="h-4 w-4" />
        </button>
        <button
          type="button"
          onClick={onMoveDown}
          disabled={!canMoveDown}
          className="min-h-[44px] min-w-[44px] rounded-lg p-2.5 text-dark-400 transition-colors hover:bg-dark-700 hover:text-dark-200 disabled:opacity-30"
          aria-label={t('admin.legalPages.moveDown')}
        >
          <ChevronDownIcon className="h-4 w-4" />
        </button>
        <button
          type="button"
          onClick={onDelete}
          className="min-h-[44px] min-w-[44px] rounded-lg p-2.5 text-dark-400 transition-colors hover:bg-error-500/10 hover:text-error-400"
          aria-label={t('admin.legalPages.delete')}
        >
          <TrashIcon className="h-4 w-4" />
        </button>
      </div>
      <textarea
        value={content}
        onChange={(e) => {
          setSaveError(null);
          setContent(e.target.value);
        }}
        rows={4}
        className="input w-full font-mono text-sm"
        placeholder={t('admin.legalPages.questionContent')}
      />
      {saveError && <p className="text-sm text-error-400">{saveError}</p>}
      <button
        onClick={() => saveMutation.mutate()}
        disabled={saveMutation.isPending}
        className="min-h-[44px] rounded-lg bg-dark-700 px-5 py-2 text-sm font-medium text-dark-100 transition-colors hover:bg-dark-600 disabled:opacity-50"
      >
        {saveMutation.isPending ? t('admin.legalPages.saving') : t('admin.legalPages.save')}
      </button>
    </div>
  );
}

function FaqEditor({ onDirtyChange }: { onDirtyChange: (dirty: boolean) => void }) {
  const { t } = useTranslation();
  const queryClient = useQueryClient();
  const haptic = useHapticFeedback();
  const confirm = useDestructiveConfirm();
  const [displayMode, setDisplayMode] = useState<LegalDisplayMode>('both');
  const [activeLang, setActiveLang] = useState('ru');
  const [populated, setPopulated] = useState(false);
  const [saveError, setSaveError] = useState<string | null>(null);
  const [dirtyRows, setDirtyRows] = useState<number[]>([]);

  const { data, isLoading, isFetching } = useQuery({
    queryKey: ['admin', 'legal-pages', 'faq'],
    queryFn: adminLegalPagesApi.getFaq,
    staleTime: 0,
    gcTime: 0,
  });

  useEffect(() => {
    if (!data || isFetching || populated) return;
    setDisplayMode(data.display_mode);
    if (data.settings.length > 0 && !data.settings.some((s) => s.language === 'ru')) {
      setActiveLang(data.settings[0].language);
    }
    setPopulated(true);
  }, [data, isFetching, populated]);

  const handleRowDirtyChange = useCallback((id: number, dirty: boolean) => {
    setDirtyRows((prev) => {
      if (dirty) return prev.includes(id) ? prev : [...prev, id];
      return prev.includes(id) ? prev.filter((rowId) => rowId !== id) : prev;
    });
  }, []);

  const hasDirtyRows = dirtyRows.length > 0;

  useEffect(() => {
    onDirtyChange(hasDirtyRows);
  }, [hasDirtyRows, onDirtyChange]);

  const invalidate = () =>
    queryClient.invalidateQueries({ queryKey: ['admin', 'legal-pages', 'faq'] });

  const settingsMutation = useMutation({
    mutationFn: (payload: { display_mode?: LegalDisplayMode; settings?: FaqSettingItem[] }) =>
      adminLegalPagesApi.updateFaq(payload),
    onSuccess: (resp) => {
      haptic.success();
      setSaveError(null);
      queryClient.setQueryData(['admin', 'legal-pages', 'faq'], resp);
    },
    onError: (err) => {
      haptic.error();
      setSaveError(extractErrorDetail(err) ?? t('admin.legalPages.saveError'));
      if (data) setDisplayMode(data.display_mode);
    },
  });

  const createMutation = useMutation({
    mutationFn: () =>
      adminLegalPagesApi.createFaqPage({
        language: activeLang,
        title: t('admin.legalPages.newQuestion'),
        content: '',
      }),
    onSuccess: () => {
      haptic.success();
      setSaveError(null);
      invalidate();
    },
    onError: (err) => {
      haptic.error();
      setSaveError(extractErrorDetail(err) ?? t('admin.legalPages.saveError'));
    },
  });

  const reorderMutation = useMutation({
    mutationFn: async ({ a, b }: { a: FaqPageItem; b: FaqPageItem }) => {
      await adminLegalPagesApi.updateFaqPage(a.id, { display_order: b.display_order });
      try {
        await adminLegalPagesApi.updateFaqPage(b.id, { display_order: a.display_order });
      } catch (err) {
        await adminLegalPagesApi
          .updateFaqPage(a.id, { display_order: a.display_order })
          .catch(() => {});
        throw err;
      }
    },
    onSuccess: () => {
      haptic.success();
      setSaveError(null);
    },
    onError: (err) => {
      haptic.error();
      setSaveError(extractErrorDetail(err) ?? t('admin.legalPages.saveError'));
    },
    onSettled: () => {
      invalidate();
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: number) => adminLegalPagesApi.deleteFaqPage(id),
    onSuccess: () => {
      haptic.success();
      setSaveError(null);
      invalidate();
    },
    onError: (err) => {
      haptic.error();
      setSaveError(extractErrorDetail(err) ?? t('admin.legalPages.saveError'));
    },
  });

  if (isLoading || !data) {
    return <div className="skeleton h-64 w-full rounded-xl" />;
  }

  const languages = data.settings.map((s) => s.language);
  const langEnabled = data.settings.find((s) => s.language === activeLang)?.is_enabled ?? false;
  const pages = data.pages.filter((p) => p.language === activeLang);

  return (
    <div className="space-y-5">
      <DisplayModeSelector
        value={displayMode}
        onChange={(mode) => {
          setDisplayMode(mode);
          settingsMutation.mutate({ display_mode: mode });
        }}
        disabled={data.display_mode_env_locked}
      />
      <LanguageTabs
        languages={languages}
        active={activeLang}
        onChange={async (lang) => {
          if (lang === activeLang) return;
          if (hasDirtyRows && !(await confirm(t('admin.legalPages.unsavedWarning')))) return;
          setActiveLang(lang);
        }}
      />
      <div className="flex items-center gap-3">
        <Toggle
          checked={langEnabled}
          onChange={() =>
            settingsMutation.mutate({
              settings: [{ language: activeLang, is_enabled: !langEnabled }],
            })
          }
          disabled={settingsMutation.isPending}
          aria-label={t('admin.legalPages.enabled')}
        />
        <span className="text-sm text-dark-300">{t('admin.legalPages.enabled')}</span>
      </div>
      {saveError && <p className="text-sm text-error-400">{saveError}</p>}

      <div className="space-y-3">
        <div className="flex items-center justify-between">
          <h2 className="text-sm font-semibold text-dark-200">{t('admin.legalPages.faqPages')}</h2>
          <button
            onClick={() => createMutation.mutate()}
            disabled={createMutation.isPending}
            className="flex min-h-[44px] items-center gap-2 rounded-lg bg-accent-500 px-4 py-2.5 text-sm font-medium text-on-accent transition-colors hover:bg-accent-600 disabled:opacity-50"
          >
            <PlusIcon />
            <span className="hidden sm:inline">{t('admin.legalPages.addQuestion')}</span>
          </button>
        </div>
        {pages.length === 0 ? (
          <p className="rounded-xl border border-dark-700 bg-dark-800/50 p-6 text-center text-sm text-dark-400">
            {t('admin.legalPages.noQuestions')}
          </p>
        ) : (
          pages.map((page, index) => (
            <FaqQuestionRow
              key={page.id}
              page={page}
              canMoveUp={index > 0 && !reorderMutation.isPending}
              canMoveDown={index < pages.length - 1 && !reorderMutation.isPending}
              onMoveUp={() => reorderMutation.mutate({ a: page, b: pages[index - 1] })}
              onMoveDown={() => reorderMutation.mutate({ a: page, b: pages[index + 1] })}
              onDelete={async () => {
                const confirmed = await confirm(t('admin.legalPages.confirmDeleteQuestion'));
                if (confirmed) deleteMutation.mutate(page.id);
              }}
              onSaved={invalidate}
              onDirtyChange={handleRowDirtyChange}
            />
          ))
        )}
      </div>
    </div>
  );
}

export default function AdminLegalPages() {
  const { t } = useTranslation();
  const confirm = useDestructiveConfirm();
  const [activeTab, setActiveTab] = useState<LegalTab>('privacy');
  const [dirty, setDirty] = useState(false);

  const handleTabChange = async (tab: LegalTab) => {
    if (tab === activeTab) return;
    if (dirty && !(await confirm(t('admin.legalPages.unsavedWarning')))) return;
    setDirty(false);
    setActiveTab(tab);
  };

  return (
    <div className="space-y-6">
      <div className="flex items-center gap-3">
        <AdminBackButton to="/admin/info-pages" />
        <div>
          <h1 className="text-xl font-bold text-dark-100">{t('admin.legalPages.title')}</h1>
          <p className="text-sm text-dark-400">{t('admin.legalPages.subtitle')}</p>
        </div>
      </div>

      <div className="flex flex-wrap gap-1">
        {(['privacy', 'offer', 'recurrent', 'rules', 'faq'] as const).map((tab) => (
          <button
            key={tab}
            type="button"
            onClick={() => handleTabChange(tab)}
            className={cn(
              'min-h-[44px] rounded-lg px-4 py-2.5 text-sm font-medium transition-colors',
              activeTab === tab
                ? 'bg-accent-500 text-on-accent'
                : 'bg-dark-700 text-dark-300 hover:bg-dark-600 hover:text-dark-100',
            )}
          >
            {t(`admin.legalPages.tabs.${tab}`)}
          </button>
        ))}
      </div>

      {activeTab === 'privacy' && (
        <DocumentEditor key="privacy" kind="privacy-policy" onDirtyChange={setDirty} />
      )}
      {activeTab === 'offer' && (
        <DocumentEditor key="offer" kind="public-offer" onDirtyChange={setDirty} />
      )}
      {activeTab === 'recurrent' && (
        <DocumentEditor key="recurrent" kind="recurrent-payments" onDirtyChange={setDirty} />
      )}
      {activeTab === 'rules' && <RulesEditor onDirtyChange={setDirty} />}
      {activeTab === 'faq' && <FaqEditor onDirtyChange={setDirty} />}
    </div>
  );
}
