'use client';

import { useCallback, useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { CreditCard, Settings } from 'lucide-react';
import { CustomDropdown } from '@/app/admin/_components/CustomDropdown';
import { CustomToggle } from '@/app/admin/_components/CustomToggle';
import { getResponseErrorTextWithRequestId } from '@/lib/api-client';
import {
  buildAppSettingsPayload,
  buildPlanPricesPayload,
  cn,
  toAppSettingsDraft,
  toCryptobotDraft,
} from '@/lib/admin/utils';
import {
  APP_SETTINGS_OG_STORAGE_OPTIONS,
  PAID_PLAN_OPTIONS,
  PLAN_LABEL,
  RATE_LIMIT_BOUNDS,
  RATE_LIMIT_ROWS,
  type AdminAppSettingsDraft,
  type AdminAppSettingsResponse,
  type CryptobotDraft,
  type CryptobotSettingsResponse,
  type PaidPlanPrices,
} from '@/lib/types/admin';
import { appSettingsCache, cryptobotSettingsCache } from './_cache';

type SettingsTabProps = {
  isAdmin: boolean;
  setErrorMessage: (message: string) => void;
  setSuccessMessage: (message: string) => void;
};

export function SettingsTab({ isAdmin, setErrorMessage, setSuccessMessage }: SettingsTabProps) {
  const initialAppSettings = appSettingsCache.read()?.data ?? null;
  const initialCryptobot = cryptobotSettingsCache.read()?.data ?? null;
  const [appSettingsDraft, setAppSettingsDraft] = useState<AdminAppSettingsDraft | null>(
    initialAppSettings ? toAppSettingsDraft(initialAppSettings) : null
  );
  const [isAppSettingsSaving, setIsAppSettingsSaving] = useState(false);
  const [cryptoDraft, setCryptoDraft] = useState<CryptobotDraft | null>(
    initialCryptobot ? toCryptobotDraft(initialCryptobot) : null
  );
  const [isPricesSaving, setIsPricesSaving] = useState(false);

  const getApiErrorText = useCallback(async (response: Response, fallback: string) => {
    return getResponseErrorTextWithRequestId(response, fallback);
  }, []);

  const fetchAdminSettings = useCallback(async () => {
    if (!isAdmin) return;

    const data = await appSettingsCache.fetch(async () => {
      const response = await fetch('/api/admin/settings', { cache: 'no-store' });
      if (!response.ok) {
        throw new Error(await getApiErrorText(response, 'Не удалось загрузить настройки приложения'));
      }
      return await response.json() as AdminAppSettingsResponse;
    });

    setAppSettingsDraft(toAppSettingsDraft(data));
  }, [getApiErrorText, isAdmin]);

  const fetchCryptobotSettings = useCallback(async () => {
    if (!isAdmin) return;

    const data = await cryptobotSettingsCache.fetch(async () => {
      const response = await fetch('/api/admin/billing/providers/cryptobot', { cache: 'no-store' });
      if (!response.ok) {
        throw new Error(await getApiErrorText(response, 'Не удалось загрузить цены тарифов'));
      }
      return await response.json() as CryptobotSettingsResponse;
    });

    setCryptoDraft(toCryptobotDraft(data));
  }, [getApiErrorText, isAdmin]);

  useEffect(() => {
    if (!isAdmin) return;
    const cachedApp = appSettingsCache.read();
    const cachedCrypto = cryptobotSettingsCache.read();
    const appFresh = cachedApp ? appSettingsCache.isFresh(cachedApp) : false;
    const cryptoFresh = cachedCrypto ? cryptobotSettingsCache.isFresh(cachedCrypto) : false;

    if (appFresh && cryptoFresh) return;

    let cancelled = false;
    if (!appFresh) {
      void fetchAdminSettings().catch((error) => {
        if (!cancelled) {
          setErrorMessage(error instanceof Error ? error.message : 'Не удалось загрузить настройки приложения');
        }
      });
    }
    if (!cryptoFresh) {
      void fetchCryptobotSettings().catch((error) => {
        if (!cancelled) {
          setErrorMessage(error instanceof Error ? error.message : 'Не удалось загрузить цены тарифов');
        }
      });
    }
    return () => {
      cancelled = true;
    };
  }, [fetchAdminSettings, fetchCryptobotSettings, isAdmin, setErrorMessage]);

  const handleSavePrices = useCallback(async () => {
    if (!isAdmin || !cryptoDraft) return;

    let planPricesPayload: PaidPlanPrices;
    try {
      planPricesPayload = buildPlanPricesPayload(cryptoDraft.planPrices);
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : 'Некорректные цены тарифов.');
      return;
    }

    setIsPricesSaving(true);
    setSuccessMessage('');

    try {
      const response = await fetch('/api/admin/billing/providers/cryptobot', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ planPrices: planPricesPayload }),
      });
      if (!response.ok) {
        throw new Error(await getApiErrorText(response, 'Не удалось сохранить цены тарифов'));
      }

      const data = await response.json() as CryptobotSettingsResponse;
      cryptobotSettingsCache.set(data);
      setCryptoDraft(toCryptobotDraft(data));
      setErrorMessage('');
      setSuccessMessage('Цены тарифов сохранены.');
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : 'Не удалось сохранить цены тарифов');
    } finally {
      setIsPricesSaving(false);
    }
  }, [cryptoDraft, getApiErrorText, isAdmin, setErrorMessage, setSuccessMessage]);

  const handleSaveAppSettings = useCallback(async () => {
    if (!isAdmin || !appSettingsDraft) return;

    let payload: AdminAppSettingsResponse;
    try {
      payload = buildAppSettingsPayload(appSettingsDraft);
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : 'Некорректные настройки приложения.');
      return;
    }

    setIsAppSettingsSaving(true);
    setSuccessMessage('');

    try {
      const response = await fetch('/api/admin/settings', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      if (!response.ok) {
        throw new Error(await getApiErrorText(response, 'Не удалось сохранить настройки приложения'));
      }

      const data = await response.json() as AdminAppSettingsResponse;
      appSettingsCache.set(data);
      setAppSettingsDraft(toAppSettingsDraft(data));
      setErrorMessage('');
      setSuccessMessage('Настройки приложения сохранены.');
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : 'Не удалось сохранить настройки приложения');
    } finally {
      setIsAppSettingsSaving(false);
    }
  }, [appSettingsDraft, getApiErrorText, isAdmin, setErrorMessage, setSuccessMessage]);

  return (
    <motion.div key="settings" initial={{ opacity: 0, y: 10 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }} className="space-y-6 max-w-5xl mx-auto pb-10">
      {!isAdmin ? (
        <div className="rounded-2xl border border-white/10 bg-white/[0.02] p-6 text-sm text-gray-300">
          Настройки доступны только администратору.
        </div>
      ) : !cryptoDraft || !appSettingsDraft ? (
        <div className="rounded-2xl border border-white/10 bg-white/[0.02] p-10 text-sm text-gray-400 text-center">
          <div className="inline-block w-6 h-6 border-2 border-violet-500 border-t-transparent rounded-full animate-spin mb-3" />
          <p>Загрузка настроек...</p>
        </div>
      ) : (
        <>
          <div className="flex flex-col md:flex-row md:items-center justify-between gap-6 mb-2 group">
            <div>
              <h2 className="text-2xl font-bold flex items-center gap-3">
                <div className="p-2.5 bg-violet-500/10 rounded-xl border border-violet-500/20 group-hover:scale-110 transition-transform">
                  <Settings className="w-6 h-6 text-violet-400" />
                </div>
                Настройки
              </h2>
              <p className="text-gray-400 mt-2 max-w-2xl leading-relaxed text-sm">
                Глобальные параметры сервиса. Цены подписок применяются во всех платёжных провайдерах.
              </p>
            </div>
          </div>

          <div className="bg-[#0A0A0A] border border-white/5 rounded-3xl p-6 md:p-8 shadow-xl hover:border-white/10 transition-colors">
            <div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
              <div>
                <h3 className="text-lg font-bold text-white mb-2 flex items-center gap-2">
                  <CreditCard className="w-5 h-5 text-gray-400" /> Цены подписок
                </h3>
                <p className="text-sm text-gray-400 max-w-2xl">
                  Задайте стоимость тарифов в USD cents за месяц и за год. Значения используются при выставлении счетов в CryptoBot и отображаются в тарифах.
                </p>
              </div>
              <button
                type="button"
                onClick={() => void handleSavePrices()}
                disabled={isPricesSaving}
                className="bg-gradient-to-r from-fuchsia-500 to-violet-600 hover:brightness-110 text-white font-medium px-6 py-2.5 rounded-xl text-sm transition-all shadow-[0_0_20px_rgba(139,92,246,0.2)] hover:shadow-[0_0_25px_rgba(139,92,246,0.4)] hover:-translate-y-0.5 disabled:opacity-60 whitespace-nowrap"
              >
                {isPricesSaving ? 'Сохранение...' : 'Сохранить цены'}
              </button>
            </div>

            <div className="bg-white/[0.02] border border-white/5 rounded-2xl p-5 md:p-6 space-y-6">
              {PAID_PLAN_OPTIONS.map((planId) => (
                <div key={planId} className={cn('grid grid-cols-[1.5fr_1fr_1fr] items-center gap-4', planId !== 'MINIMAL' && 'border-t border-white/5 pt-4')}>
                  <div className="flex flex-col gap-0.5">
                    <span className="text-sm font-bold text-white">{PLAN_LABEL[planId]}</span>
                    <span className="text-[10px] text-gray-500 font-mono uppercase tracking-wider">{planId}</span>
                  </div>
                  <div className="space-y-1.5">
                    {planId === 'MINIMAL' ? (
                      <label className="text-[10px] text-gray-500 font-bold tracking-wider">МЕСЯЦ (USD cents)</label>
                    ) : null}
                    <input
                      type="number"
                      value={cryptoDraft.planPrices[planId].monthlyUsdCents}
                      onChange={(event) => {
                        const value = event.target.value;
                        setCryptoDraft((prev) => {
                          if (!prev) return prev;
                          return {
                            ...prev,
                            planPrices: {
                              ...prev.planPrices,
                              [planId]: {
                                ...prev.planPrices[planId],
                                monthlyUsdCents: value,
                              },
                            },
                          };
                        });
                      }}
                      className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-4 py-2 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                    />
                  </div>
                  <div className="space-y-1.5">
                    {planId === 'MINIMAL' ? (
                      <label className="text-[10px] text-gray-500 font-bold tracking-wider">ГОД (USD cents)</label>
                    ) : null}
                    <input
                      type="number"
                      value={cryptoDraft.planPrices[planId].yearlyUsdCents}
                      onChange={(event) => {
                        const value = event.target.value;
                        setCryptoDraft((prev) => {
                          if (!prev) return prev;
                          return {
                            ...prev,
                            planPrices: {
                              ...prev.planPrices,
                              [planId]: {
                                ...prev.planPrices[planId],
                                yearlyUsdCents: value,
                              },
                            },
                          };
                        });
                      }}
                      className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-4 py-2 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                    />
                  </div>
                </div>
              ))}
            </div>
          </div>

          <div className="bg-[#0A0A0A] border border-white/5 rounded-3xl p-6 md:p-8 shadow-xl hover:border-white/10 transition-colors">
            <div className="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
              <div>
                <h3 className="text-lg font-bold text-white mb-2 flex items-center gap-2">
                  <Settings className="w-5 h-5 text-violet-300" /> Общие настройки приложения
                </h3>
                <p className="text-sm text-gray-400 max-w-2xl">
                  Эти параметры применяются на лету, без перезапуска сервера — можно менять лимиты и поведение в реальном времени.
                </p>
              </div>
              <button
                type="button"
                onClick={() => void handleSaveAppSettings()}
                disabled={isAppSettingsSaving}
                className="bg-gradient-to-r from-fuchsia-500 to-violet-600 hover:brightness-110 text-white font-medium px-6 py-2.5 rounded-xl text-sm transition-all shadow-[0_0_20px_rgba(139,92,246,0.2)] hover:shadow-[0_0_25px_rgba(139,92,246,0.4)] hover:-translate-y-0.5 disabled:opacity-60 whitespace-nowrap"
              >
                {isAppSettingsSaving ? 'Сохранение...' : 'Сохранить настройки'}
              </button>
            </div>

            <div className="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-4 gap-5 mb-5">
              <div className="space-y-2 bg-white/[0.02] border border-white/5 rounded-2xl p-4">
                <label className="text-xs uppercase tracking-wider text-gray-500 font-semibold">Название проекта</label>
                <input
                  type="text"
                  value={appSettingsDraft.branding.projectName}
                  onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                    ...prev,
                    branding: {
                      ...prev.branding,
                      projectName: event.target.value,
                    },
                  } : prev))}
                  className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2.5 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                />
              </div>
              <div className="space-y-2 bg-white/[0.02] border border-white/5 rounded-2xl p-4">
                <label className="text-xs uppercase tracking-wider text-gray-500 font-semibold">Email поддержки</label>
                <input
                  type="email"
                  value={appSettingsDraft.branding.supportEmail}
                  onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                    ...prev,
                    branding: {
                      ...prev.branding,
                      supportEmail: event.target.value,
                    },
                  } : prev))}
                  className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2.5 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                />
              </div>
              <div className="space-y-2 bg-white/[0.02] border border-white/5 rounded-2xl p-4">
                <label className="text-xs uppercase tracking-wider text-gray-500 font-semibold">Telegram поддержки</label>
                <div className="flex items-stretch gap-0 rounded-xl border border-white/10 hover:border-white/20 bg-black/40 focus-within:border-violet-500/50 transition-colors overflow-hidden">
                  <span className="px-3 py-2.5 text-sm text-violet-300 font-mono bg-violet-500/10 border-r border-white/10 select-none">@</span>
                  <input
                    type="text"
                    autoComplete="off"
                    spellCheck={false}
                    placeholder="snaplink_support"
                    value={appSettingsDraft.branding.supportTelegramUsername}
                    onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                      ...prev,
                      branding: {
                        ...prev.branding,
                        supportTelegramUsername: event.target.value.replace(/^@+/, ''),
                      },
                    } : prev))}
                    className="flex-1 min-w-0 bg-transparent px-3 py-2.5 text-sm outline-none text-white font-mono"
                  />
                </div>
                <p className="text-[11px] text-gray-500">Если поле пустое — кнопка поддержки в футере и профиле не показывается. 5–32 символа: латинские буквы, цифры и нижнее подчёркивание.</p>
              </div>
              <div className="space-y-2 bg-white/[0.02] border border-white/5 rounded-2xl p-4">
                <label className="text-xs uppercase tracking-wider text-gray-500 font-semibold">Часовой пояс приложения</label>
                <input
                  type="text"
                  value={appSettingsDraft.time.timeZone}
                  onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                    ...prev,
                    time: {
                      ...prev.time,
                      timeZone: event.target.value,
                    },
                  } : prev))}
                  placeholder="Europe/Moscow"
                  className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2.5 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                />
                <p className="text-[11px] text-gray-500">IANA-формат, например Europe/Moscow.</p>
              </div>
            </div>

            <div className="grid grid-cols-1 xl:grid-cols-2 gap-5 mb-5">
              <div className="space-y-4 bg-white/[0.02] border border-white/5 rounded-2xl p-4">
                <div className="flex items-center justify-between gap-3">
                  <div>
                    <p className="text-sm font-semibold text-white">Строгий фильтр ботов</p>
                    <p className="text-xs text-gray-500">Блокирует известных ботов до фиксации кликов.</p>
                  </div>
                  <CustomToggle
                    checked={appSettingsDraft.antiAbuse.botFilterStrictMode}
                    onChange={(value) => setAppSettingsDraft((prev) => (prev ? {
                      ...prev,
                      antiAbuse: {
                        ...prev.antiAbuse,
                        botFilterStrictMode: value,
                      },
                    } : prev))}
                  />
                </div>
                <div className="flex items-center justify-between gap-3">
                  <div>
                    <p className="text-sm font-semibold text-white">Определение страны по IP</p>
                    <p className="text-xs text-gray-500">Определение страны и города через внешний сервис.</p>
                  </div>
                  <CustomToggle
                    checked={appSettingsDraft.antiAbuse.geoLookupEnabled}
                    onChange={(value) => setAppSettingsDraft((prev) => (prev ? {
                      ...prev,
                      antiAbuse: {
                        ...prev.antiAbuse,
                        geoLookupEnabled: value,
                      },
                    } : prev))}
                  />
                </div>
                <div className="flex items-center justify-between gap-3">
                  <div>
                    <p className="text-sm font-semibold text-white">Показывать отладочные блоки аналитики</p>
                    <p className="text-xs text-gray-500">Дополнительные блоки на странице аналитики — для проверки фильтров и источников кликов.</p>
                  </div>
                  <CustomToggle
                    checked={appSettingsDraft.analytics.debugVisibilityEnabled}
                    onChange={(value) => setAppSettingsDraft((prev) => (prev ? {
                      ...prev,
                      analytics: {
                        ...prev.analytics,
                        debugVisibilityEnabled: value,
                      },
                    } : prev))}
                  />
                </div>
              </div>

              <div className="space-y-4 bg-white/[0.02] border border-white/5 rounded-2xl p-4">
                <div className="space-y-2">
                  <label className="text-xs uppercase tracking-wider text-gray-500 font-semibold">Хранилище OG-картинок</label>
                  <CustomDropdown
                    value={APP_SETTINGS_OG_STORAGE_OPTIONS.find((item) => item.value === appSettingsDraft.og.storageProvider)?.label || 'Локальное хранилище'}
                    onChange={(selectedLabel) => {
                      const selected = APP_SETTINGS_OG_STORAGE_OPTIONS.find((item) => item.label === selectedLabel);
                      if (!selected) return;
                      setAppSettingsDraft((prev) => (prev ? {
                        ...prev,
                        og: {
                          ...prev.og,
                          storageProvider: selected.value,
                        },
                      } : prev));
                    }}
                    options={APP_SETTINGS_OG_STORAGE_OPTIONS.map((item) => item.label)}
                  />
                </div>
                <div className="space-y-2">
                  <label className="text-xs uppercase tracking-wider text-gray-500 font-semibold">Папка Cloudinary</label>
                  <input
                    type="text"
                    value={appSettingsDraft.og.cloudinaryFolder}
                    onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                      ...prev,
                      og: {
                        ...prev.og,
                        cloudinaryFolder: event.target.value,
                      },
                    } : prev))}
                    className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2.5 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                  />
                </div>
                <div className="space-y-2">
                  <label className="text-xs uppercase tracking-wider text-gray-500 font-semibold">Таймаут загрузки OG-картинки (мс)</label>
                  <input
                    type="number"
                    min={500}
                    max={120000}
                    value={appSettingsDraft.og.sourceFetchTimeoutMs}
                    onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                      ...prev,
                      og: {
                        ...prev.og,
                        sourceFetchTimeoutMs: event.target.value,
                      },
                    } : prev))}
                    className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2.5 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                  />
                </div>
              </div>
            </div>

            <details className="group bg-white/[0.02] border border-white/5 rounded-2xl p-4 open:border-violet-500/30 transition-all">
              <summary className="flex items-center justify-between cursor-pointer list-none">
                <div>
                  <p className="text-sm font-semibold text-white">Лимиты запросов</p>
                  <p className="text-xs text-gray-500">Для каждого действия задаётся максимум запросов за выбранное окно времени.</p>
                </div>
                <span className="text-xs text-violet-300 group-open:text-violet-200 transition-colors">Развернуть</span>
              </summary>
              <div className="mt-4 space-y-3">
                {RATE_LIMIT_ROWS.map((row) => (
                  <div key={row.limitKey} className="grid grid-cols-1 md:grid-cols-[1.4fr_1fr_1fr] gap-3 items-center bg-black/30 border border-white/5 rounded-xl p-3">
                    <div className="min-w-0">
                      <p className="text-sm text-white font-medium">{row.label}</p>
                      <p className="text-[11px] text-gray-500 truncate">
                        {row.description}
                      </p>
                    </div>
                    <div className="space-y-1">
                      <label className="text-[10px] text-gray-500 uppercase tracking-wider">Макс. запросов</label>
                      <input
                        type="number"
                        min={RATE_LIMIT_BOUNDS.limit.min}
                        max={RATE_LIMIT_BOUNDS.limit.max}
                        value={appSettingsDraft.antiAbuse.rateLimits[row.limitKey]}
                        onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                          ...prev,
                          antiAbuse: {
                            ...prev.antiAbuse,
                            rateLimits: {
                              ...prev.antiAbuse.rateLimits,
                              [row.limitKey]: event.target.value,
                            },
                          },
                        } : prev))}
                        className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                      />
                    </div>
                    <div className="space-y-1">
                      <label className="text-[10px] text-gray-500 uppercase tracking-wider">Окно (секунды)</label>
                      <input
                        type="number"
                        min={RATE_LIMIT_BOUNDS.windowSec.min}
                        max={RATE_LIMIT_BOUNDS.windowSec.max}
                        value={appSettingsDraft.antiAbuse.rateLimits[row.windowKey]}
                        onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                          ...prev,
                          antiAbuse: {
                            ...prev.antiAbuse,
                            rateLimits: {
                              ...prev.antiAbuse.rateLimits,
                              [row.windowKey]: event.target.value,
                            },
                          },
                        } : prev))}
                        className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2 text-sm outline-none focus:border-violet-500/50 transition-colors text-white"
                      />
                    </div>
                  </div>
                ))}
              </div>
            </details>

            <details className="group mt-5 bg-white/[0.02] border border-white/5 rounded-2xl p-4 open:border-violet-500/30 transition-all">
              <summary className="flex items-center justify-between cursor-pointer list-none">
                <div>
                  <p className="text-sm font-semibold text-white">Security blacklist</p>
                  <p className="text-xs text-gray-500">Скрытый блок для управления доменами и URL-паттернами, которые запрещены при создании ссылок.</p>
                </div>
                <span className="text-xs text-violet-300 group-open:text-violet-200 transition-colors">Развернуть</span>
              </summary>
              <div className="mt-4 grid grid-cols-1 xl:grid-cols-2 gap-4">
                <div className="space-y-2 bg-black/30 border border-white/5 rounded-xl p-3">
                  <label className="text-[10px] text-gray-500 uppercase tracking-wider">Заблокированные домены</label>
                  <textarea
                    rows={8}
                    placeholder={'phishing-example.com\nmalicious-site.net'}
                    value={appSettingsDraft.security.blockedDomains}
                    onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                      ...prev,
                      security: {
                        ...prev.security,
                        blockedDomains: event.target.value,
                      },
                    } : prev))}
                    className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2 text-sm outline-none focus:border-violet-500/50 transition-colors text-white font-mono resize-y"
                  />
                  <p className="text-[11px] text-gray-500">Один домен на строку. Можно указывать `example.com`, `https://example.com/path` или `example.com:443`.</p>
                </div>

                <div className="space-y-2 bg-black/30 border border-white/5 rounded-xl p-3">
                  <label className="text-[10px] text-gray-500 uppercase tracking-wider">Заблокированные regex-паттерны</label>
                  <textarea
                    rows={8}
                    placeholder={'/\\/download\\.php\\?file=/i\n^https?:\\/\\/[^\\s]+\\.(exe|bat)$'}
                    value={appSettingsDraft.security.blockedPatterns}
                    onChange={(event) => setAppSettingsDraft((prev) => (prev ? {
                      ...prev,
                      security: {
                        ...prev.security,
                        blockedPatterns: event.target.value,
                      },
                    } : prev))}
                    className="w-full bg-black/40 border border-white/10 hover:border-white/20 rounded-xl px-3 py-2 text-sm outline-none focus:border-violet-500/50 transition-colors text-white font-mono resize-y"
                  />
                  <p className="text-[11px] text-gray-500">Один regex на строку. Поддерживается формат `/pattern/flags` и обычная строка regex.</p>
                </div>
              </div>
            </details>
          </div>
        </>
      )}
    </motion.div>
  );
}
