import React, { useState, useEffect } from 'react';
import { ChevronDown, ChevronRight, AlertTriangle, CheckCircle2, Shield, List, Ban, BarChart3, Loader2, RefreshCw, Plus, Trash2 } from 'lucide-react';
import { backendApi } from '../../services/apiClient';

type BlockId = 'A' | 'B' | 'C' | 'D' | 'E' | 'F';

const BLOCKS: Array<{ id: BlockId; title: string; steps: Array<{ id: string; action: string; responsible: string; result: string }> }> = [
  { id: 'A', title: 'Организация (152-ФЗ)', steps: [
    { id: 'A1', action: 'Назначить ответственного за обработку ПДн (приказ руководителя, круг обязанностей)', responsible: 'Руководство', result: 'Приказ, ФИО ответственного' },
    { id: 'A2', action: 'Разработать политику обработки персональных данных (цели, основания, состав ПДн, сроки хранения, права субъектов, меры защиты)', responsible: 'Ответственный + юрист/внешний консультант', result: 'Документ «Политика обработки ПДн»' },
    { id: 'A3', action: 'Опубликовать политику (сайт, личный кабинет, приложение)', responsible: 'Ответственный / админ', result: 'Ссылка на политику доступна пользователям' },
    { id: 'A4', action: 'Подготовить формы согласия на обработку ПДн (для сотрудников, жильцов, контактов в заявках; при спецкатегориях — отдельное согласие)', responsible: 'Ответственный + юрист', result: 'Формы согласий, чекбоксы в формах сбора данных' },
    { id: 'A5', action: 'Внедрить сбор согласий при регистрации/добавлении сотрудников и контактов', responsible: 'Разработка', result: 'Согласие фиксируется при вводе ПДн' },
    { id: 'A6', action: 'Подать уведомление в РКН о обработке ПДн (до начала обработки; цели, категории данных, меры защиты)', responsible: 'Ответственный', result: 'Подтверждение приёма уведомления РКН' },
    { id: 'A7', action: 'Принять локальные акты: положение об обработке и защите ПДн, регламент доступа к БД и файлам, инструкция для администраторов', responsible: 'Ответственный', result: 'Приказы/положения в организации' },
  ]},
  { id: 'B', title: 'HTTPS и секреты (защита при передаче)', steps: [
    { id: 'B1', action: 'Определить домен и поддомены; проверить доступ к DNS для DNS-01', responsible: 'Инфраструктура', result: 'Список доменов, доступ к DNS' },
    { id: 'B2', action: 'Выпустить wildcard-сертификат (Let\'s Encrypt, DNS-01) или отдельные сертификаты; сохранить в volume/каталог для прокси', responsible: 'Инфраструктура', result: 'Сертификаты на диске/volume' },
    { id: 'B3', action: 'Добавить reverse proxy (Traefik / Caddy / Nginx) в docker-compose: 443 и 80, редирект 80→443, проксирование на приложение по HTTP', responsible: 'Разработка / DevOps', result: 'Работающий прокси в Docker' },
    { id: 'B4', action: 'Настроить HSTS (Strict-Transport-Security) в прокси', responsible: 'Разработка / DevOps', result: 'HSTS включён' },
    { id: 'B5', action: 'В проде задать VITE_API_BASE_URL с https; собирать фронт при деплое с этим значением', responsible: 'Разработка / DevOps', result: 'Все запросы к API идут по HTTPS' },
    { id: 'B6', action: 'Убрать дефолтный JWT_SECRET из кода: при отсутствии process.env.JWT_SECRET не запускать сервер; хранить секрет в env/секретах', responsible: 'Разработка', result: 'JWT_SECRET только из env' },
    { id: 'B7', action: 'Настроить автообновление сертификатов и перезагрузку прокси после обновления', responsible: 'Инфраструктура', result: 'Сертификаты продлеваются автоматически' },
  ]},
  { id: 'C', title: 'Хранение и доступ', steps: [
    { id: 'C1', action: 'Проверить, что пароли нигде не логируются; при создании/обновлении пользователя всегда bcrypt-хеш', responsible: 'Разработка', result: 'Аудит логов и кода auth' },
    { id: 'C2', action: 'Ограничить доступ ОС к папке backend/uploads (только процесс приложения); при необходимости шифрование тома', responsible: 'Инфраструктура', result: 'Права на uploads проверены' },
    { id: 'C3', action: 'Зафиксировать в регламенте доступ ролей к полям с ПДн; при необходимости не отдавать в API чувствительные поля', responsible: 'Ответственный + разработка', result: 'Регламент, при необходимости доработка API' },
    { id: 'C4', action: 'Логирование доступа к критичным операциям (изменение сотрудника, экспорт, смена пароля) — без паролей и паспортных данных', responsible: 'Разработка', result: 'Аудит-логи на критические действия' },
    { id: 'C5', action: 'Зафиксировать в политике ПДн сроки хранения; при необходимости удаление/обезличивание по истечении срока', responsible: 'Ответственный + разработка', result: 'Сроки в документе, при необходимости автоматизация' },
    { id: 'C6', action: '(Опционально) Убрать хранение пароля Doma AI в localStorage: токен или proxy авторизации через бэкенд', responsible: 'Разработка', result: 'Пароль не в localStorage' },
    { id: 'C7', action: '(Опционально) Шифрование чувствительных полей в БД (паспорт, СНИЛС, реквизиты); ключ вне БД', responsible: 'Разработка', result: 'Принято решение и при необходимости реализовано' },
  ]},
  { id: 'D', title: 'Реагирование и обучение', steps: [
    { id: 'D1', action: 'Разработать порядок реагирования на инциденты (обнаружение, фиксация, уведомление РКН и субъектов ПДн, устранение причин)', responsible: 'Ответственный + юрист', result: 'Документ «Порядок реагирования на утечки ПДн»' },
    { id: 'D2', action: 'Провести инструктаж сотрудников по работе с ПДн (запрет передачи паролей вне регламента, только HTTPS)', responsible: 'Ответственный', result: 'Журнал инструктажей / запись о проведении' },
  ]},
  { id: 'E', title: 'Защита от взлома', steps: [
    { id: 'E1', action: 'Rate limit на /api/auth/login (блокировка или задержка после N неудачных попыток с одного IP/логина)', responsible: 'Разработка', result: 'Защита от брутфорса входа' },
    { id: 'E2', action: 'Валидация ввода; параметризованные запросы к БД; защита от XSS (CSP) и CSRF (токены при необходимости)', responsible: 'Разработка', result: 'Снижение риска SQL-инъекций, XSS, CSRF' },
    { id: 'E3', action: 'Защитные заголовки HTTP: X-Content-Type-Options, X-Frame-Options, Referrer-Policy, при необходимости CSP', responsible: 'Разработка / DevOps', result: 'Защита от XSS и clickjacking' },
    { id: 'E4', action: 'Регулярная проверка уязвимостей (npm audit, Snyk) и обновление backend/frontend-пакетов; исправление критичных CVE', responsible: 'Разработка', result: 'Нет известных критичных уязвимостей' },
    { id: 'E5', action: 'Firewall (только 80/443 снаружи, SSH по ключу или с ограничением IP); секреты только в env/vault', responsible: 'Инфраструктура', result: 'Сокращение поверхности атаки' },
    { id: 'E6', action: 'Логирование неудачных входов и подозрительных запросов; при возможности алерты при аномалиях', responsible: 'Разработка / DevOps', result: 'Быстрое выявление попыток взлома' },
  ]},
  { id: 'F', title: 'Защита от вирусов и вредоносного ПО', steps: [
    { id: 'F1', action: 'Антивирус на рабочих местах и серверах: регулярное сканирование, обновление баз', responsible: 'Инфраструктура / ИТ', result: 'Снижение риска заражения' },
    { id: 'F2', action: 'Проверка загружаемых файлов: ограничение типов и размера; при возможности сканирование при загрузке (ClamAV)', responsible: 'Разработка / DevOps', result: 'Загрузки не становятся каналом вирусов' },
    { id: 'F3', action: 'Обновление ОС и ПО: патчи хоста и образов Docker; Node, PostgreSQL и прокси до поддерживаемых версий', responsible: 'Инфраструктура', result: 'Меньше уязвимостей в стеке' },
    { id: 'F4', action: 'Не запускать непроверенные скрипты; зависимости только из доверенных реестров (npm); при необходимости проверка целостности', responsible: 'Разработка', result: 'Снижение риска supply-chain атак' },
    { id: 'F5', action: 'Политика для сотрудников: не открывать подозрительные вложения, не ставить неподтверждённое ПО; ограничение прав учёток', responsible: 'Ответственный / ИТ', result: 'Меньше риска заноса вирусов' },
  ]},
];

type TabId = 'dashboard' | 'plan';

function formatDate(iso: string) {
  try {
    return new Date(iso).toLocaleString('ru-RU', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', second: '2-digit' });
  } catch {
    return iso;
  }
}

export const SecuritySection: React.FC = () => {
  const [tab, setTab] = useState<TabId>('dashboard');
  const [expanded, setExpanded] = useState<Set<BlockId>>(new Set(['A', 'B']));

  // Дашборд: настройки, статистика, логи, чёрный список
  const [settings, setSettings] = useState<{ captchaEnabled: boolean; turnstileSiteKey: string | null; turnstileSecretKeySet: boolean } | null>(null);
  const [stats, setStats] = useState<{ failedLast24h: number; totalAttemptsLast24h: number; blockedCount: number } | null>(null);
  const [logs, setLogs] = useState<{ items: Array<{ id: number; ip: string; loginMasked: string; success: boolean; createdAt: string }>; total: number; page: number; limit: number } | null>(null);
  const [blacklist, setBlacklist] = useState<Array<{ id: number; type: string; value: string; reason: string | null; createdAt: string }>>([]);
  const [loading, setLoading] = useState(false);
  const [logsPage, setLogsPage] = useState(1);
  const [logsSuccessFilter, setLogsSuccessFilter] = useState<'all' | true | false>('all');
  const [blacklistForm, setBlacklistForm] = useState({ type: 'ip' as 'ip' | 'login', value: '', reason: '' });
  const [blacklistSubmitting, setBlacklistSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);
  // Форма настройки капчи (синхронизируем site key из settings при загрузке)
  const [captchaSiteKey, setCaptchaSiteKey] = useState('');
  const [captchaSecretKey, setCaptchaSecretKey] = useState('');
  const [captchaSaving, setCaptchaSaving] = useState(false);

  const loadDashboard = async () => {
    setLoading(true);
    setError(null);
    try {
      const [settingsRes, statsRes, logsRes, blacklistRes] = await Promise.all([
        backendApi.getSecuritySettings(),
        backendApi.getSecurityStats(),
        backendApi.getSecurityLogs({ page: logsPage, limit: 20, success: logsSuccessFilter === 'all' ? undefined : logsSuccessFilter }),
        backendApi.getSecurityBlacklist(),
      ]);
      setSettings(settingsRes);
      setCaptchaSiteKey(settingsRes.turnstileSiteKey || '');
      setStats(statsRes);
      setLogs(logsRes);
      setBlacklist(blacklistRes);
    } catch (e: unknown) {
      setError((e as Error)?.message || 'Ошибка загрузки дашборда');
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (tab === 'dashboard') loadDashboard();
  }, [tab, logsPage, logsSuccessFilter]);

  const toggle = (id: BlockId) => {
    setExpanded((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };

  const handleAddBlacklist = async () => {
    const val = blacklistForm.value.trim();
    if (!val) return;
    setBlacklistSubmitting(true);
    setError(null);
    try {
      await backendApi.addSecurityBlacklist({ type: blacklistForm.type, value: val, reason: blacklistForm.reason.trim() || undefined });
      setBlacklistForm({ ...blacklistForm, value: '', reason: '' });
      await loadDashboard();
    } catch (e: unknown) {
      setError((e as Error)?.message || 'Ошибка добавления');
    } finally {
      setBlacklistSubmitting(false);
    }
  };

  const handleDeleteBlacklist = async (id: number) => {
    try {
      await backendApi.deleteSecurityBlacklist(id);
      setBlacklist((prev) => prev.filter((r) => r.id !== id));
    } catch (e: unknown) {
      setError((e as Error)?.message || 'Ошибка удаления');
    }
  };

  const handleSaveCaptcha = async () => {
    setCaptchaSaving(true);
    setError(null);
    try {
      const res = await backendApi.saveSecuritySettings({
        turnstileSiteKey: captchaSiteKey.trim() || undefined,
        turnstileSecretKey: captchaSecretKey.trim() || undefined,
      });
      setSettings(res);
      setCaptchaSiteKey(res.turnstileSiteKey || '');
      setCaptchaSecretKey('');
      await loadDashboard();
    } catch (e: unknown) {
      setError((e as Error)?.message || 'Ошибка сохранения');
    } finally {
      setCaptchaSaving(false);
    }
  };

  return (
    <div className="space-y-6">
      <div className="flex gap-2 border-b border-slate-200">
        <button
          type="button"
          onClick={() => setTab('dashboard')}
          className={`flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-t-lg transition-colors ${tab === 'dashboard' ? 'bg-slate-100 text-slate-800 border border-slate-200 border-b-0 -mb-px' : 'text-slate-600 hover:bg-slate-50'}`}
        >
          <Shield className="w-4 h-4" />
          Дашборд безопасности
        </button>
        <button
          type="button"
          onClick={() => setTab('plan')}
          className={`flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-t-lg transition-colors ${tab === 'plan' ? 'bg-slate-100 text-slate-800 border border-slate-200 border-b-0 -mb-px' : 'text-slate-600 hover:bg-slate-50'}`}
        >
          <List className="w-4 h-4" />
          План (152-ФЗ)
        </button>
      </div>

      {tab === 'dashboard' && (
        <div className="space-y-6">
          {error && (
            <div className="rounded-xl border border-red-200 bg-red-50 p-4 text-red-700 text-sm flex items-center justify-between">
              <span>{error}</span>
              <button type="button" onClick={() => setError(null)} className="text-red-500 hover:text-red-700">×</button>
            </div>
          )}

          <div className="flex items-center justify-between">
            <h3 className="text-lg font-bold text-slate-800">Мониторинг и настройки</h3>
            <button
              type="button"
              onClick={loadDashboard}
              disabled={loading}
              className="flex items-center gap-2 px-3 py-1.5 text-sm text-slate-600 hover:bg-slate-100 rounded-lg"
            >
              {loading ? <Loader2 className="w-4 h-4 animate-spin" /> : <RefreshCw className="w-4 h-4" />}
              Обновить
            </button>
          </div>

          {loading && !settings ? (
            <div className="flex items-center justify-center py-12"><Loader2 className="w-8 h-8 animate-spin text-slate-400" /></div>
          ) : (
            <>
              {/* Настройка капчи Turnstile */}
              <div className="rounded-xl border border-slate-200 bg-white p-4">
                <div className="flex items-center gap-2 text-slate-500 text-sm mb-3">
                  <Shield className="w-4 h-4" /> Капча (Turnstile)
                </div>
                <div className="flex flex-wrap items-end gap-3 mb-2">
                  <span className="font-semibold text-slate-800">
                    {settings?.captchaEnabled ? 'Включена' : 'Выключена'}
                  </span>
                  <span className="text-xs text-slate-500">
                    Задайте ключи из <a href="https://dash.cloudflare.com/?to=/:account/turnstile" target="_blank" rel="noopener noreferrer" className="text-primary-600 hover:underline">Cloudflare Turnstile</a> и сохраните — виджет появится на форме входа.
                  </span>
                </div>
                <div className="flex flex-wrap gap-3 items-end">
                  <label className="flex flex-col gap-1">
                    <span className="text-xs font-medium text-slate-600">Site key (публичный)</span>
                    <input
                      type="text"
                      value={captchaSiteKey}
                      onChange={(e) => setCaptchaSiteKey(e.target.value)}
                      placeholder="0x4AAAAAAA..."
                      className="text-sm border border-slate-200 rounded-lg px-3 py-2 min-w-[200px] font-mono"
                    />
                  </label>
                  <label className="flex flex-col gap-1">
                    <span className="text-xs font-medium text-slate-600">Secret key</span>
                    <input
                      type="password"
                      value={captchaSecretKey}
                      onChange={(e) => setCaptchaSecretKey(e.target.value)}
                      placeholder={settings?.turnstileSecretKeySet ? 'Оставьте пустым, чтобы не менять' : 'Секретный ключ'}
                      className="text-sm border border-slate-200 rounded-lg px-3 py-2 min-w-[200px] font-mono"
                    />
                  </label>
                  <button
                    type="button"
                    onClick={handleSaveCaptcha}
                    disabled={captchaSaving}
                    className="flex items-center gap-2 px-4 py-2 bg-primary-600 text-white text-sm font-medium rounded-lg hover:bg-primary-700 disabled:opacity-50"
                  >
                    {captchaSaving ? <Loader2 className="w-4 h-4 animate-spin" /> : null}
                    Сохранить
                  </button>
                </div>
              </div>

              {/* Статистика */}
              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                <div className="rounded-xl border border-slate-200 bg-white p-4">
                  <div className="flex items-center gap-2 text-slate-500 text-sm mb-1"><BarChart3 className="w-4 h-4" /> Неудачных входов за 24 ч</div>
                  <div className="font-semibold text-slate-800">{stats?.failedLast24h ?? '—'}</div>
                </div>
                <div className="rounded-xl border border-slate-200 bg-white p-4">
                  <div className="flex items-center gap-2 text-slate-500 text-sm mb-1"><BarChart3 className="w-4 h-4" /> Всего попыток за 24 ч</div>
                  <div className="font-semibold text-slate-800">{stats?.totalAttemptsLast24h ?? '—'}</div>
                </div>
                <div className="rounded-xl border border-slate-200 bg-white p-4">
                  <div className="flex items-center gap-2 text-slate-500 text-sm mb-1"><Ban className="w-4 h-4" /> В чёрном списке</div>
                  <div className="font-semibold text-slate-800">{stats?.blockedCount ?? '—'}</div>
                </div>
              </div>

              {/* Логи входа */}
              <div className="rounded-xl border border-slate-200 bg-white overflow-hidden">
                <div className="p-4 border-b border-slate-100 flex flex-wrap items-center gap-3">
                  <h4 className="font-semibold text-slate-800">Логи входа</h4>
                  <select
                    value={logsSuccessFilter === 'all' ? 'all' : logsSuccessFilter ? 'true' : 'false'}
                    onChange={(e) => { const v = e.target.value; setLogsSuccessFilter(v === 'all' ? 'all' : v === 'true'); setLogsPage(1); }}
                    className="text-sm border border-slate-200 rounded-lg px-2 py-1"
                  >
                    <option value="all">Все</option>
                    <option value="true">Успешные</option>
                    <option value="false">Неудачные</option>
                  </select>
                </div>
                <div className="overflow-x-auto">
                  <table className="w-full text-sm">
                    <thead>
                      <tr className="bg-slate-50 text-left text-xs font-semibold text-slate-500 uppercase tracking-wider">
                        <th className="px-4 py-2">IP</th>
                        <th className="px-4 py-2">Логин (маска)</th>
                        <th className="px-4 py-2">Результат</th>
                        <th className="px-4 py-2">Время</th>
                      </tr>
                    </thead>
                    <tbody>
                      {logs?.items?.length ? logs.items.map((row) => (
                        <tr key={row.id} className="border-t border-slate-100">
                          <td className="px-4 py-2 font-mono text-slate-700">{row.ip}</td>
                          <td className="px-4 py-2 text-slate-600">{row.loginMasked || '—'}</td>
                          <td className="px-4 py-2">
                            {row.success ? <span className="text-emerald-600">Успех</span> : <span className="text-red-600">Ошибка</span>}
                          </td>
                          <td className="px-4 py-2 text-slate-500">{formatDate(row.createdAt)}</td>
                        </tr>
                      )) : (
                        <tr><td colSpan={4} className="px-4 py-6 text-center text-slate-500">Нет записей</td></tr>
                      )}
                    </tbody>
                  </table>
                </div>
                {logs && logs.total > logs.limit && (
                  <div className="p-3 border-t border-slate-100 flex items-center justify-between text-sm text-slate-600">
                    <span>Всего: {logs.total}</span>
                    <div className="flex gap-2">
                      <button type="button" disabled={logsPage <= 1} onClick={() => setLogsPage((p) => p - 1)} className="px-2 py-1 rounded border border-slate-200 disabled:opacity-50">Назад</button>
                      <span>Стр. {logsPage}</span>
                      <button type="button" disabled={logsPage * logs.limit >= logs.total} onClick={() => setLogsPage((p) => p + 1)} className="px-2 py-1 rounded border border-slate-200 disabled:opacity-50">Вперёд</button>
                    </div>
                  </div>
                )}
              </div>

              {/* Чёрный список */}
              <div className="rounded-xl border border-slate-200 bg-white overflow-hidden">
                <div className="p-4 border-b border-slate-100">
                  <h4 className="font-semibold text-slate-800 mb-3">Чёрный список (IP или логин)</h4>
                  <div className="flex flex-wrap gap-2 items-end">
                    <select
                      value={blacklistForm.type}
                      onChange={(e) => setBlacklistForm({ ...blacklistForm, type: e.target.value as 'ip' | 'login' })}
                      className="text-sm border border-slate-200 rounded-lg px-3 py-2"
                    >
                      <option value="ip">IP</option>
                      <option value="login">Логин</option>
                    </select>
                    <input
                      type="text"
                      value={blacklistForm.value}
                      onChange={(e) => setBlacklistForm({ ...blacklistForm, value: e.target.value })}
                      placeholder={blacklistForm.type === 'ip' ? '192.168.1.1' : 'логин'}
                      className="text-sm border border-slate-200 rounded-lg px-3 py-2 min-w-[140px]"
                    />
                    <input
                      type="text"
                      value={blacklistForm.reason}
                      onChange={(e) => setBlacklistForm({ ...blacklistForm, reason: e.target.value })}
                      placeholder="Причина (необяз.)"
                      className="text-sm border border-slate-200 rounded-lg px-3 py-2 min-w-[120px]"
                    />
                    <button
                      type="button"
                      onClick={handleAddBlacklist}
                      disabled={!blacklistForm.value.trim() || blacklistSubmitting}
                      className="flex items-center gap-1 px-3 py-2 bg-slate-800 text-white text-sm font-medium rounded-lg hover:bg-slate-700 disabled:opacity-50"
                    >
                      {blacklistSubmitting ? <Loader2 className="w-4 h-4 animate-spin" /> : <Plus className="w-4 h-4" />}
                      Добавить
                    </button>
                  </div>
                </div>
                <div className="overflow-x-auto">
                  <table className="w-full text-sm">
                    <thead>
                      <tr className="bg-slate-50 text-left text-xs font-semibold text-slate-500 uppercase tracking-wider">
                        <th className="px-4 py-2">Тип</th>
                        <th className="px-4 py-2">Значение</th>
                        <th className="px-4 py-2">Причина</th>
                        <th className="px-4 py-2">Добавлено</th>
                        <th className="px-4 py-2 w-20"></th>
                      </tr>
                    </thead>
                    <tbody>
                      {blacklist.length ? blacklist.map((row) => (
                        <tr key={row.id} className="border-t border-slate-100">
                          <td className="px-4 py-2 font-mono text-slate-600">{row.type}</td>
                          <td className="px-4 py-2 text-slate-800">{row.value}</td>
                          <td className="px-4 py-2 text-slate-500">{row.reason || '—'}</td>
                          <td className="px-4 py-2 text-slate-500">{formatDate(row.createdAt)}</td>
                          <td className="px-4 py-2">
                            <button type="button" onClick={() => handleDeleteBlacklist(row.id)} className="p-1 text-red-600 hover:bg-red-50 rounded" title="Удалить"><Trash2 className="w-4 h-4" /></button>
                          </td>
                        </tr>
                      )) : (
                        <tr><td colSpan={5} className="px-4 py-6 text-center text-slate-500">Пусто</td></tr>
                      )}
                    </tbody>
                  </table>
                </div>
              </div>
            </>
          )}
        </div>
      )}

      {tab === 'plan' && (
        <>
          <p className="text-sm text-slate-600">
            План защиты персональных данных (152-ФЗ), HTTPS, шифрование при передаче и хранении, защита от взлома и от вирусов. Выполняйте шаги по порядку; приоритеты указаны ниже.
          </p>
          <div className="rounded-xl border border-amber-200 bg-amber-50/80 p-4">
            <h3 className="text-xs font-bold uppercase tracking-wider text-amber-800 mb-2 flex items-center gap-2"><AlertTriangle className="w-4 h-4" /> Приоритеты</h3>
            <ul className="text-sm text-slate-700 space-y-1">
              <li><strong>Критично:</strong> A1–A2, A6, B3–B7 (HTTPS + JWT_SECRET). Без этого высоки риски штрафов и компрометации.</li>
              <li><strong>Важно:</strong> A3–A5, A7, C1–C4, E1–E3, E5, F1, F3. Требования 152-ФЗ, аудит, базовая защита от взлома и вирусов.</li>
              <li><strong>Далее:</strong> C5–C7, D1–D2, E4, E6, F2, F4, F5.</li>
            </ul>
          </div>
          <div className="space-y-2">
            {BLOCKS.map((block) => {
              const isOpen = expanded.has(block.id);
              return (
                <div key={block.id} className="rounded-xl border border-slate-200 bg-white overflow-hidden">
                  <button type="button" onClick={() => toggle(block.id)} className="w-full flex items-center gap-2 py-3 px-4 text-left font-semibold text-slate-800 hover:bg-slate-50 transition-colors">
                    {isOpen ? <ChevronDown className="w-4 h-4" /> : <ChevronRight className="w-4 h-4" />}
                    <span className="text-xs uppercase tracking-wider text-slate-500">Блок {block.id}</span>
                    <span className="ml-1">{block.title}</span>
                  </button>
                  {isOpen && (
                    <div className="border-t border-slate-100 p-4 bg-slate-50/50">
                      <div className="overflow-x-auto">
                        <table className="w-full text-sm border-collapse">
                          <thead>
                            <tr className="text-left text-xs font-semibold text-slate-500 uppercase tracking-wider">
                              <th className="pb-2 pr-4">№</th>
                              <th className="pb-2 pr-4">Действие</th>
                              <th className="pb-2 pr-4 whitespace-nowrap">Ответственный</th>
                              <th className="pb-2">Результат</th>
                            </tr>
                          </thead>
                          <tbody>
                            {block.steps.map((step) => (
                              <tr key={step.id} className="border-t border-slate-100 first:border-t-0">
                                <td className="py-2 pr-4 font-mono text-slate-600">{step.id}</td>
                                <td className="py-2 pr-4 text-slate-700">{step.action}</td>
                                <td className="py-2 pr-4 text-slate-600 whitespace-nowrap">{step.responsible}</td>
                                <td className="py-2 text-slate-600">{step.result}</td>
                              </tr>
                            ))}
                          </tbody>
                        </table>
                      </div>
                    </div>
                  )}
                </div>
              );
            })}
          </div>
          <div className="rounded-xl border border-slate-200 bg-slate-50 p-4 flex items-start gap-3">
            <CheckCircle2 className="w-5 h-5 text-emerald-600 shrink-0 mt-0.5" />
            <div className="text-sm text-slate-600">
              <p className="font-medium text-slate-800 mb-1">Шифрование по закону</p>
              <p>Передача: TLS (HTTPS) везде. Пароли: bcrypt (уже используется). Хранение в БД: разграничение доступа; при повышенных рисках — шифрование чувствительных полей. Биометрия не используется — ст. 19 572-ФЗ не применяется.</p>
            </div>
          </div>
        </>
      )}
    </div>
  );
};
