import { useEffect, useMemo, useRef, useState } from 'react';
import { open } from '@tauri-apps/plugin-dialog';
import { Cpu, FileCode2, FolderOpen, Gauge, Info, Link2, MoreHorizontal, Trash2, Wand2 } from 'lucide-react';
import {
  applyProfiles,
  fetchSingBoxSubscription,
  forgetSingBoxSubscription,
  generateSingBoxConfig,
  getComponents,
  getProxiFyreSetupStatus,
  getSavedState,
  getSingBoxSetupStatus,
  getSingBoxStatus,
  installProxiFyre,
  installSingBox,
  openConfigLocation,
  pingAllSingBoxServers,
  saveProfile,
  saveSingBoxSubscription,
  saveTarget,
  selectSingBoxServer,
  startProxiFyreService,
  startSingBoxService,
  stopProxiFyreService,
  stopSingBoxService,
  uninstallProxiFyre,
  uninstallSingBox,
  type ApplyProfilesResponse,
  type LocalSingBoxStatusResponse,
  type PingServerResponse,
  type ProxiFyreSetupStatus,
  type SingBoxSetupStatus,
} from '../api/tauriCommands';
import type { ComponentStatus, Profile, ProfileItemInput, ProfileItemType, SubscriptionServer, Target } from '../domain/types';

type DraftItemType = Extract<ProfileItemType, 'process' | 'folder' | 'exe'>;
type ProxiFyreAction = 'start' | 'stop' | 'install' | 'uninstall';
type SingBoxAction = 'start' | 'stop' | 'install' | 'uninstall' | 'fetch' | 'forget' | 'generate' | 'ping';
type RouteMode = 'external' | 'local-singbox';
type ServiceVisualState = 'active' | 'settling' | null;

interface DraftItem {
  id: string;
  type: DraftItemType;
  value: string;
}

interface Notice {
  kind: 'success' | 'error' | 'info';
  title: string;
  text: string;
}

interface LogEntry extends Notice {
  id: string;
  at: number;
}

const MAIN_TARGET_ID = 'main-proxy';
const MAIN_PROFILE_ID = 'main-profile';
const LOCAL_SINGBOX_TARGET_ID = 'local-singbox';
const LOG_VISIBLE_MS = 6500;

const fallbackComponents: ComponentStatus[] = [
  {
    id: 'proxyfier',
    name: 'ProxiFyre',
    state: 'missing',
    installed: false,
    running: false,
    problems: ['ProxiFyre не найден'],
    actions: [],
  },
  {
    id: 'singbox',
    name: 'Локальный sing-box',
    state: 'missing',
    installed: false,
    running: false,
    problems: [],
    actions: [],
  },
];

export function App() {
  const [proxyInput, setProxyInput] = useState('');
  const [routeMode, setRouteMode] = useState<RouteMode>('external');
  const [profileId, setProfileId] = useState(MAIN_PROFILE_ID);
  const [targetId, setTargetId] = useState(MAIN_TARGET_ID);
  const [items, setItems] = useState<DraftItem[]>([]);
  const [hasUnappliedChanges, setHasUnappliedChanges] = useState(false);
  const [loadedProfiles, setLoadedProfiles] = useState<Profile[]>([]);
  const [isProcessInputOpen, setIsProcessInputOpen] = useState(false);
  const [processInput, setProcessInput] = useState('');
  const [pickerAction, setPickerAction] = useState<'exe' | 'folder' | null>(null);
  const [components, setComponents] = useState<ComponentStatus[]>(fallbackComponents);
  const [setupStatus, setSetupStatus] = useState<ProxiFyreSetupStatus | null>(null);
  const [singBoxStatus, setSingBoxStatus] = useState<LocalSingBoxStatusResponse | null>(null);
  const [singBoxSetupStatus, setSingBoxSetupStatus] = useState<SingBoxSetupStatus | null>(null);
  const [subscriptionInput, setSubscriptionInput] = useState('');
  const [serverPings, setServerPings] = useState<Record<string, PingServerResponse>>({});
  const [isSetupOpen, setIsSetupOpen] = useState(false);
  const [isSingBoxSetupOpen, setIsSingBoxSetupOpen] = useState(false);
  const [isSingBoxInfoOpen, setIsSingBoxInfoOpen] = useState(false);
  const [generatedConfigPath, setGeneratedConfigPath] = useState('');
  const [logEntries, setLogEntries] = useState<LogEntry[]>([]);
  const [activeLogId, setActiveLogId] = useState<string | null>(null);
  const [isLogOpen, setIsLogOpen] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [isDetectingComponents, setIsDetectingComponents] = useState(true);
  const [isApplying, setIsApplying] = useState(false);
  const [isOpeningConfig, setIsOpeningConfig] = useState(false);
  const [serviceAction, setServiceAction] = useState<ProxiFyreAction | null>(null);
  const [singBoxAction, setSingBoxAction] = useState<SingBoxAction | null>(null);
  const [isServiceMenuOpen, setIsServiceMenuOpen] = useState(false);
  const [isSingBoxMenuOpen, setIsSingBoxMenuOpen] = useState(false);
  const [serviceVisualState, setServiceVisualState] = useState<ServiceVisualState>(null);
  const serviceVisualTimerRef = useRef<number | null>(null);

  const proxyfier = useMemo(
    () => components.find((component) => component.id === 'proxyfier'),
    [components],
  );
  const singbox = useMemo(
    () => singBoxStatus?.component ?? components.find((component) => component.id === 'singbox'),
    [components, singBoxStatus],
  );
  const activeLog = useMemo(
    () => logEntries.find((entry) => entry.id === activeLogId) ?? null,
    [activeLogId, logEntries],
  );
  const finderStateClass = isDetectingComponents ? 'checking' : proxyfier?.installed ? 'found' : 'missing';
  const finderVisualClass =
    serviceVisualState === 'active' ? 'working' : serviceVisualState === 'settling' ? 'settling' : '';
  const isSingBoxInstalled = Boolean(singbox?.installed);
  const singBoxStateClass = isDetectingComponents ? 'checking' : singbox?.installed ? 'found' : 'missing';
  const singBoxVisualClass = singBoxAction ? 'working' : '';

  useEffect(() => {
    void refresh();
  }, []);

  useEffect(() => {
    return () => {
      if (serviceVisualTimerRef.current !== null) {
        window.clearTimeout(serviceVisualTimerRef.current);
      }
    };
  }, []);

  useEffect(() => {
    if (!activeLogId) return undefined;

    const timer = window.setTimeout(() => {
      setActiveLogId((current) => (current === activeLogId ? null : current));
    }, LOG_VISIBLE_MS);

    return () => window.clearTimeout(timer);
  }, [activeLogId]);

  async function refresh() {
    setIsLoading(true);
    try {
      const saved = await getSavedState();
      applySavedState(saved.profiles, saved.targets, saved.generatedConfigPath);
    } catch {
      showNotice({
        kind: 'info',
        title: 'Режим предпросмотра',
        text: 'Запусти приложение через Tauri, чтобы увидеть найденный ProxiFyre и применить конфиг.',
      });
    } finally {
      setIsLoading(false);
    }

    void refreshComponents();
  }

  async function refreshComponents() {
    setIsDetectingComponents(true);
    try {
      const [detectedComponents, detectedSetupStatus, detectedSingBoxStatus, detectedSingBoxSetupStatus] = await Promise.all([
        getComponents(),
        getProxiFyreSetupStatus(),
        getSingBoxStatus(),
        getSingBoxSetupStatus(),
      ]);
      setComponents(detectedComponents);
      setSetupStatus(detectedSetupStatus);
      setSingBoxStatus(detectedSingBoxStatus);
      setSingBoxSetupStatus(detectedSingBoxSetupStatus);
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Компоненты не проверены',
        text: errorMessage(error),
      });
    } finally {
      setIsDetectingComponents(false);
    }
  }

  function applySavedState(profiles: Profile[], targets: Target[], generatedPath: string) {
    const activeProfiles = profiles.filter((profile) => profile.enabled);
    const mainProfile = profiles.find((profile) => profile.id === MAIN_PROFILE_ID);
    const activeProfile = mainProfile ?? activeProfiles[0];
    const activeTarget = targetForUi(targets, activeProfile);
    const externalTarget = targetForExternalProxy(targets);
    const editableProfiles = mainProfile ? [mainProfile] : activeProfiles;

    if (externalTarget) setProxyInput(formatProxy(externalTarget));
    setItems(itemsForProfiles(editableProfiles));
    setLoadedProfiles(profiles);
    setProfileId(mainProfile?.id ?? MAIN_PROFILE_ID);
    setTargetId(externalTarget?.id ?? MAIN_TARGET_ID);
    setRouteMode(
      activeTarget?.id === LOCAL_SINGBOX_TARGET_ID || activeProfile?.targetId === LOCAL_SINGBOX_TARGET_ID
        ? 'local-singbox'
        : 'external',
    );
    setGeneratedConfigPath(generatedPath);
    setHasUnappliedChanges(false);
  }

  function addItem(type: DraftItemType, rawValue: string) {
    const value = normalizeItemValue(rawValue, type);
    if (!value) {
      showNotice({
        kind: 'error',
        title: 'Нечего добавить',
        text: emptyItemMessage(type),
      });
      return false;
    }

    if (items.some((item) => item.type === type && sameValue(item.value, value))) {
      showNotice({
        kind: 'info',
        title: 'Уже добавлено',
        text: value,
      });
      return false;
    }

    setItems((current) => [
      ...current,
      {
        id: `${type}-${Date.now()}`,
        type,
        value,
      },
    ]);
    setHasUnappliedChanges(true);
    return true;
  }

  function addProcess() {
    if (addItem('process', processInput)) {
      setProcessInput('');
      setIsProcessInputOpen(false);
    }
  }

  function removeItem(id: string) {
    setItems((current) => current.filter((item) => item.id !== id));
    setHasUnappliedChanges(true);
  }

  function changeRouteMode(nextMode: RouteMode) {
    setRouteMode((current) => {
      if (current !== nextMode) setHasUnappliedChanges(true);
      return nextMode;
    });
  }

  function changeProxyInput(nextValue: string) {
    setProxyInput(nextValue);
    setHasUnappliedChanges(true);
  }

  async function pickAndAddItem(type: Extract<DraftItemType, 'exe' | 'folder'>) {
    setPickerAction(type);
    try {
      const selectedPath = await pickPath(type);
      if (selectedPath) {
        addItem(type, selectedPath);
      }
    } catch (error) {
      showNotice({
        kind: 'error',
        title: type === 'exe' ? 'EXE не выбран' : 'Папка не выбрана',
        text: errorMessage(error),
      });
    } finally {
      setPickerAction(null);
    }
  }

  async function updateConfig() {
    let parsedProxy: ParsedProxy | null = null;
    try {
      if (!items.length) throw new Error('Добавь хотя бы один процесс, EXE-файл или папку.');
      if (routeMode === 'external') {
        parsedProxy = parseProxy(proxyInput);
      } else if (!isSingBoxInstalled) {
        throw new Error('Сначала установи Local sing-box.');
      } else if (!singBoxStatus?.config.selectedServerTag) {
        throw new Error('Выбери сервер Local sing-box.');
      }
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Проверь данные',
        text: errorMessage(error),
      });
      return;
    }

    setIsApplying(true);
    try {
      let singBoxGeneratedPath = '';
      if (routeMode === 'external') {
        if (!parsedProxy) throw new Error('Прокси не разобран.');
        await saveTarget({
          id: targetId,
          name: 'Основной прокси',
          kind: 'external',
          protocol: parsedProxy.protocol,
          host: parsedProxy.host,
          port: parsedProxy.port,
        });
      } else {
        const singBoxResult = await generateSingBoxConfig();
        singBoxGeneratedPath = singBoxResult.generatedConfigPath;
        await ensureSingBoxRunningForApply();
      }

      await saveProfile({
        id: profileId,
        name: 'Приложения через прокси',
        enabled: true,
        targetId: routeMode === 'local-singbox' ? LOCAL_SINGBOX_TARGET_ID : targetId,
        protocols: ['TCP', 'UDP'],
        items: items.map(profileItemInput),
      });
      await Promise.all(
        loadedProfiles
          .filter((profile) => profile.enabled && profile.id !== profileId)
          .map((profile) => saveProfile(profileInputFromProfile(profile, false))),
      );

      const result = await applyProfiles();
      const [saved, detectedComponents, detectedSetupStatus, detectedSingBoxStatus, detectedSingBoxSetupStatus] = await Promise.all([
        getSavedState(),
        getComponents(),
        getProxiFyreSetupStatus(),
        getSingBoxStatus(),
        getSingBoxSetupStatus(),
      ]);

      applySavedState(saved.profiles, saved.targets, result.generatedConfigPath);
      setComponents(detectedComponents);
      setSetupStatus(detectedSetupStatus);
      setSingBoxStatus(detectedSingBoxStatus);
      setSingBoxSetupStatus(detectedSingBoxSetupStatus);
      setHasUnappliedChanges(false);
      showNotice(routeMode === 'local-singbox' ? noticeFromLocalApply(result, singBoxGeneratedPath) : noticeFromApply(result));
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Конфиг не обновлен',
        text: errorMessage(error),
      });
    } finally {
      setIsApplying(false);
    }
  }

  async function ensureSingBoxRunningForApply() {
    if (routeMode !== 'local-singbox' || !singbox?.installed) return;

    setIsSingBoxMenuOpen(false);
    try {
      await nextFrame();
      if (singbox.running) {
        setSingBoxAction('stop');
        const stopped = await stopSingBoxService();
        setComponents((current) => upsertComponent(current, stopped));
      }

      setSingBoxAction('start');
      const component = await startSingBoxService();
      setComponents((current) => upsertComponent(current, component));
      const status = await refreshSingBoxState();
      if (!status.component.running) {
        throw new Error('Local sing-box установлен, но служба не запустилась.');
      }
    } finally {
      setSingBoxAction(null);
    }
  }

  async function openConfig() {
    setIsOpeningConfig(true);
    try {
      const openedPath = await openConfigLocation();
      showNotice({
        kind: 'info',
        title: 'Конфиг открыт',
        text: openedPath,
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Не удалось открыть конфиг',
        text: errorMessage(error),
      });
    } finally {
      setIsOpeningConfig(false);
    }
  }

  async function setProxiFyreServiceRunning(shouldRun: boolean) {
    const action = shouldRun ? 'start' : 'stop';
    setServiceAction(action);
    setIsServiceMenuOpen(false);
    startServiceVisual();
    try {
      await nextFrame();
      const component = shouldRun
        ? await startProxiFyreService()
        : await stopProxiFyreService();

      setComponents((current) => upsertComponent(current, component));
      showNotice({
        kind: 'success',
        title: shouldRun ? 'Служба запущена' : 'Служба остановлена',
        text: proxyfierDetails(component, false),
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: shouldRun ? 'Служба не запущена' : 'Служба не остановлена',
        text: errorMessage(error),
      });
    } finally {
      setServiceAction(null);
      settleServiceVisual();
    }
  }

  async function installProxiFyrePackage() {
    setServiceAction('install');
    setIsServiceMenuOpen(false);
    startServiceVisual();
    try {
      await nextFrame();
      const component = await installProxiFyre();
      const detectedSetupStatus = await getProxiFyreSetupStatus();
      setComponents((current) => upsertComponent(current, component));
      setSetupStatus(detectedSetupStatus);
      showNotice({
        kind: 'success',
        title: 'ProxiFyre установлен',
        text: proxyfierDetails(component, false),
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'ProxiFyre не установлен',
        text: errorMessage(error),
      });
    } finally {
      setServiceAction(null);
      settleServiceVisual();
    }
  }

  async function uninstallProxiFyrePackage() {
    const confirmed = window.confirm(
      'Удалить ProxiFyre с компьютера? Будет удалена служба и папка установки ProxiFyre.',
    );
    if (!confirmed) return;

    setServiceAction('uninstall');
    setIsServiceMenuOpen(false);
    startServiceVisual();
    try {
      await nextFrame();
      const component = await uninstallProxiFyre();
      const detectedSetupStatus = await getProxiFyreSetupStatus();
      setComponents((current) => upsertComponent(current, component));
      setSetupStatus(detectedSetupStatus);
      showNotice({
        kind: 'success',
        title: 'ProxiFyre удален',
        text: 'Служба и папка установки ProxiFyre удалены.',
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'ProxiFyre не удален',
        text: errorMessage(error),
      });
    } finally {
      setServiceAction(null);
      settleServiceVisual();
    }
  }

  async function refreshSingBoxState() {
    const [detectedSingBoxStatus, detectedSingBoxSetupStatus, detectedComponents] = await Promise.all([
      getSingBoxStatus(),
      getSingBoxSetupStatus(),
      getComponents(),
    ]);
    setSingBoxStatus(detectedSingBoxStatus);
    setSingBoxSetupStatus(detectedSingBoxSetupStatus);
    setComponents(detectedComponents);
    return detectedSingBoxStatus;
  }

  async function setSingBoxServiceRunning(shouldRun: boolean) {
    const action: SingBoxAction = shouldRun ? 'start' : 'stop';
    setSingBoxAction(action);
    setIsSingBoxMenuOpen(false);
    try {
      await nextFrame();
      const component = shouldRun ? await startSingBoxService() : await stopSingBoxService();
      setComponents((current) => upsertComponent(current, component));
      await refreshSingBoxState();
      showNotice({
        kind: 'success',
        title: shouldRun ? 'sing-box запущен' : 'sing-box остановлен',
        text: componentDetails(component, false),
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: shouldRun ? 'sing-box не запущен' : 'sing-box не остановлен',
        text: errorMessage(error),
      });
    } finally {
      setSingBoxAction(null);
    }
  }

  async function installSingBoxPackage() {
    setSingBoxAction('install');
    setIsSingBoxMenuOpen(false);
    try {
      await nextFrame();
      const component = await installSingBox();
      setComponents((current) => upsertComponent(current, component));
      await refreshSingBoxState();
      showNotice({
        kind: 'success',
        title: 'Local sing-box установлен',
        text: componentDetails(component, false),
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Local sing-box не установлен',
        text: errorMessage(error),
      });
    } finally {
      setSingBoxAction(null);
    }
  }

  async function uninstallSingBoxPackage() {
    const confirmed = window.confirm(
      'Удалить Local sing-box с компьютера? Будет удалена служба и папка установки sing-box.',
    );
    if (!confirmed) return;

    setSingBoxAction('uninstall');
    setIsSingBoxMenuOpen(false);
    try {
      await nextFrame();
      const component = await uninstallSingBox();
      setComponents((current) => upsertComponent(current, component));
      await refreshSingBoxState();
      showNotice({
        kind: 'success',
        title: 'Local sing-box удален',
        text: 'Служба и папка установки Local sing-box удалены.',
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Local sing-box не удален',
        text: errorMessage(error),
      });
    } finally {
      setSingBoxAction(null);
    }
  }

  async function syncSingBoxSubscription() {
    const subscriptionUrl = subscriptionInput.trim();
    if (!subscriptionUrl && !singBoxStatus?.config.hasSubscription) {
      showNotice({
        kind: 'error',
        title: 'Ссылка не указана',
        text: 'Вставь ссылку подписки Local sing-box.',
      });
      return;
    }

    setSingBoxAction('fetch');
    try {
      if (subscriptionUrl) {
        await saveSingBoxSubscription(subscriptionUrl);
      }
      const status = await fetchSingBoxSubscription();
      setSingBoxStatus(status);
      setComponents((current) => upsertComponent(current, status.component));
      setSubscriptionInput('');
      setServerPings({});
      setHasUnappliedChanges(true);
      showNotice({
        kind: 'success',
        title: 'Подписка обновлена',
        text: `Серверов: ${status.cache?.servers.length ?? 0}`,
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Подписка не обновлена',
        text: errorMessage(error),
      });
    } finally {
      setSingBoxAction(null);
    }
  }

  async function forgetSingBoxSubscriptionData() {
    setSingBoxAction('forget');
    setIsSingBoxMenuOpen(false);
    try {
      const status = await forgetSingBoxSubscription();
      setSingBoxStatus(status);
      setComponents((current) => upsertComponent(current, status.component));
      setServerPings({});
      setHasUnappliedChanges(true);
      showNotice({
        kind: 'info',
        title: 'Подписка очищена',
        text: 'Ссылка, cache и выбранный сервер Local sing-box удалены.',
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Подписка не очищена',
        text: errorMessage(error),
      });
    } finally {
      setSingBoxAction(null);
    }
  }

  async function chooseSingBoxServer(server: SubscriptionServer) {
    try {
      const status = await selectSingBoxServer(server);
      setSingBoxStatus(status);
      setComponents((current) => upsertComponent(current, status.component));
      setHasUnappliedChanges(true);
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Сервер не выбран',
        text: errorMessage(error),
      });
    }
  }

  async function pingSingBoxServers() {
    setSingBoxAction('ping');
    try {
      const results = await pingAllSingBoxServers();
      setServerPings(Object.fromEntries(results.map((result) => [result.tag, result])));
      showNotice({
        kind: 'info',
        title: 'Ping завершен',
        text: pingSummary(results),
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Ping не выполнен',
        text: errorMessage(error),
      });
    } finally {
      setSingBoxAction(null);
    }
  }

  async function generateSingBoxNow() {
    setSingBoxAction('generate');
    try {
      const result = await generateSingBoxConfig();
      await refreshSingBoxState();
      showNotice({
        kind: 'success',
        title: 'Конфиг sing-box создан',
        text: result.generatedConfigPath,
      });
    } catch (error) {
      showNotice({
        kind: 'error',
        title: 'Конфиг sing-box не создан',
        text: errorMessage(error),
      });
    } finally {
      setSingBoxAction(null);
    }
  }

  function startServiceVisual() {
    if (serviceVisualTimerRef.current !== null) {
      window.clearTimeout(serviceVisualTimerRef.current);
      serviceVisualTimerRef.current = null;
    }

    setServiceVisualState('active');
  }

  function settleServiceVisual() {
    if (serviceVisualTimerRef.current !== null) {
      window.clearTimeout(serviceVisualTimerRef.current);
    }

    setServiceVisualState('settling');
    serviceVisualTimerRef.current = window.setTimeout(() => {
      setServiceVisualState(null);
      serviceVisualTimerRef.current = null;
    }, 700);
  }

  function showNotice(notice: Notice) {
    const entry: LogEntry = {
      ...notice,
      id: `log-${Date.now()}-${Math.random().toString(36).slice(2)}`,
      at: Date.now(),
    };

    setLogEntries((current) => [entry, ...current].slice(0, 40));
    setActiveLogId(entry.id);
  }

  return (
    <main className="simple-shell">
      <section className="simple-panel">
        <header className="simple-header">
          <div>
            <small>VPN Proxy</small>
            <h1>Прокси для приложений</h1>
          </div>
          <button
            type="button"
            className="ghost-button"
            onClick={refresh}
            disabled={isLoading || isDetectingComponents}
          >
            {isLoading ? 'Загружаю...' : isDetectingComponents ? 'Проверяю...' : 'Обновить'}
          </button>
        </header>

        <div className={`finder-card ${finderStateClass} ${finderVisualClass}`.trim()}>
          <span className="finder-border-glow" aria-hidden="true">
            <span className="finder-border-glow-segment top" />
            <span className="finder-border-glow-segment right" />
            <span className="finder-border-glow-segment bottom" />
            <span className="finder-border-glow-segment left" />
          </span>
          <span className="status-light" />
          <div className="finder-text">
            <strong>{proxyfierTitle(proxyfier, isDetectingComponents)}</strong>
            <span>{proxyfierDetails(proxyfier, isDetectingComponents)}</span>
            <button
              type="button"
              className="setup-toggle"
              onClick={() => setIsSetupOpen((current) => !current)}
              disabled={isDetectingComponents && !setupStatus}
              aria-expanded={isSetupOpen}
            >
              {proxyfier?.installed ? 'Состав ProxiFyre' : 'Что будет установлено'}
              {setupStatus ? (
                <span>{setupStatus.ready ? 'все есть' : `не хватает: ${setupStatus.missingCount}`}</span>
              ) : null}
            </button>
          </div>
          <div className="service-actions" aria-label="Управление службой ProxiFyre">
            {proxyfier?.installed ? (
              <>
                <button
                  type="button"
                  className={`service-button ${proxyfier.running ? 'stop' : ''}`.trim()}
                  onClick={() => setProxiFyreServiceRunning(!proxyfier.running)}
                  disabled={isDetectingComponents || Boolean(serviceAction)}
                >
                  {serviceAction === 'start' || serviceAction === 'stop'
                    ? '...'
                    : proxyfier.running
                      ? 'Остановить'
                      : 'Запустить'}
                </button>
                <div className="service-menu">
                  <button
                    type="button"
                    className="service-menu-button"
                    onClick={() => setIsServiceMenuOpen((current) => !current)}
                    disabled={isDetectingComponents || Boolean(serviceAction)}
                    aria-label="Дополнительные действия ProxiFyre"
                    aria-expanded={isServiceMenuOpen}
                    title="Еще"
                  >
                    <MoreHorizontal size={20} strokeWidth={2} />
                  </button>
                  {isServiceMenuOpen ? (
                    <div className="service-menu-popover">
                      <button type="button" onClick={() => void uninstallProxiFyrePackage()}>
                        {serviceAction === 'uninstall' ? 'Удаляю...' : 'Удалить ProxiFyre'}
                      </button>
                    </div>
                  ) : null}
                </div>
              </>
            ) : (
              <button
                type="button"
                className="service-button install"
                onClick={() => void installProxiFyrePackage()}
                disabled={isDetectingComponents || Boolean(serviceAction)}
              >
                {serviceAction === 'install' ? '...' : 'Установить'}
              </button>
            )}
          </div>
          {isSetupOpen ? (
            <div className="setup-details">
              {setupStatus ? (
                setupStatus.items.map((item) => (
                  <div className={`setup-item ${item.installed ? 'installed' : 'missing'}`} key={item.id}>
                    <span className="setup-state-dot" aria-hidden="true" />
                    <div>
                      <strong>{item.name}</strong>
                      <span>{setupItemDetails(item.installed, item.version, item.details)}</span>
                    </div>
                  </div>
                ))
              ) : (
                <div className="setup-item">
                  <span className="setup-state-dot" aria-hidden="true" />
                  <div>
                    <strong>Проверяю состав</strong>
                    <span>Ищу установленные зависимости ProxiFyre.</span>
                  </div>
                </div>
              )}
            </div>
          ) : null}
        </div>

        <section className="route-panel" aria-label="Маршрут приложений">
          <div className="route-switch">
            <button
              type="button"
              className={routeMode === 'external' ? 'active' : ''}
              onClick={() => changeRouteMode('external')}
              aria-pressed={routeMode === 'external'}
            >
              Внешний прокси
            </button>
            <button
              type="button"
              className={routeMode === 'local-singbox' ? 'active' : ''}
              onClick={() => changeRouteMode('local-singbox')}
              aria-pressed={routeMode === 'local-singbox'}
            >
              Local sing-box
            </button>
          </div>

          {routeMode === 'external' ? (
            <label className="simple-field route-proxy-field">
              <span className="sr-only">Внешний прокси</span>
              <input
                value={proxyInput}
                onChange={(event) => changeProxyInput(event.target.value)}
                placeholder="socks5://127.0.0.1:1080"
                spellCheck={false}
              />
            </label>
          ) : null}
        </section>

        {routeMode === 'local-singbox' ? (
          <div className={`finder-card singbox-card ${singBoxStateClass} ${singBoxVisualClass}`.trim()}>
          <span className="finder-border-glow" aria-hidden="true">
            <span className="finder-border-glow-segment top" />
            <span className="finder-border-glow-segment right" />
            <span className="finder-border-glow-segment bottom" />
            <span className="finder-border-glow-segment left" />
          </span>
          <span className="status-light" />
          <div className="finder-text">
            <strong>{singBoxTitle(singbox, isDetectingComponents)}</strong>
            <span>{singBoxDetails(singbox, singBoxStatus, isDetectingComponents)}</span>
            <div className="singbox-inline-actions">
              <button
                type="button"
                className="setup-toggle"
                onClick={() => setIsSingBoxSetupOpen((current) => !current)}
                disabled={isDetectingComponents && !singBoxSetupStatus}
                aria-expanded={isSingBoxSetupOpen}
              >
                {singbox?.installed ? 'Состав Local sing-box' : 'Что будет установлено'}
                {singBoxSetupStatus ? (
                  <span>{singBoxSetupStatus.ready ? 'все есть' : `не хватает: ${singBoxSetupStatus.missingCount}`}</span>
                ) : null}
              </button>
              <button
                type="button"
                className="info-toggle"
                onClick={() => setIsSingBoxInfoOpen((current) => !current)}
                aria-label="Подробности Local sing-box"
                aria-expanded={isSingBoxInfoOpen}
                title="Подробности"
              >
                <Info size={16} strokeWidth={2} />
              </button>
            </div>
          </div>
          <div className="service-actions" aria-label="Управление службой Local sing-box">
            {singbox?.installed ? (
              <>
                <button
                  type="button"
                  className={`service-button ${singbox.running ? 'stop' : ''}`.trim()}
                  onClick={() => void setSingBoxServiceRunning(!singbox.running)}
                  disabled={isDetectingComponents || Boolean(singBoxAction)}
                >
                  {singBoxAction === 'start' || singBoxAction === 'stop'
                    ? '...'
                    : singbox.running
                      ? 'Остановить'
                      : 'Запустить'}
                </button>
                <div className="service-menu">
                  <button
                    type="button"
                    className="service-menu-button"
                    onClick={() => setIsSingBoxMenuOpen((current) => !current)}
                    disabled={isDetectingComponents || Boolean(singBoxAction)}
                    aria-label="Дополнительные действия Local sing-box"
                    aria-expanded={isSingBoxMenuOpen}
                    title="Еще"
                  >
                    <MoreHorizontal size={20} strokeWidth={2} />
                  </button>
                  {isSingBoxMenuOpen ? (
                    <div className="service-menu-popover">
                      <button type="button" onClick={() => void uninstallSingBoxPackage()}>
                        {singBoxAction === 'uninstall' ? 'Удаляю...' : 'Удалить Local sing-box'}
                      </button>
                    </div>
                  ) : null}
                </div>
              </>
            ) : (
              <button
                type="button"
                className="service-button install"
                onClick={() => void installSingBoxPackage()}
                disabled={isDetectingComponents || Boolean(singBoxAction)}
              >
                {singBoxAction === 'install' ? '...' : 'Установить'}
              </button>
            )}
          </div>

          {isSingBoxInfoOpen ? (
            <div className="singbox-info-popover">
              <div className="singbox-info-grid">
                <span>Локально</span>
                <strong>{localSingBoxAddress(singBoxStatus)}</strong>
                <span>LAN</span>
                <strong>{lanSingBoxAddress(singBoxStatus) ?? 'недоступен'}</strong>
                <span>Сервер</span>
                <strong>
                  {singBoxStatus?.config.selectedServerTag
                    ? displayServerTag(singBoxStatus.config.selectedServerTag)
                    : 'не выбран'}
                </strong>
                <span>Файл</span>
                <strong>{singbox?.path ?? 'не найден'}</strong>
                <span>Конфиг</span>
                <strong>{singBoxStatus?.generatedConfigPath ?? 'не создан'}</strong>
              </div>
              <div className="singbox-info-actions">
                <button
                  type="button"
                  onClick={() => void pingSingBoxServers()}
                  disabled={Boolean(singBoxAction) || !singBoxStatus?.cache?.servers.length}
                >
                  <Gauge size={15} strokeWidth={1.9} />
                  Ping
                </button>
                <button
                  type="button"
                  onClick={() => void generateSingBoxNow()}
                  disabled={Boolean(singBoxAction) || !singBoxStatus?.config.selectedServerTag}
                >
                  <Wand2 size={15} strokeWidth={1.9} />
                  Конфиг
                </button>
              </div>
            </div>
          ) : null}

          {isSingBoxSetupOpen ? (
            <div className="setup-details">
              {singBoxSetupStatus ? (
                singBoxSetupStatus.items.map((item) => (
                  <div className={`setup-item ${item.installed ? 'installed' : 'missing'}`} key={item.id}>
                    <span className="setup-state-dot" aria-hidden="true" />
                    <div>
                      <strong>{item.name}</strong>
                      <span>{setupItemDetails(item.installed, item.version, item.details)}</span>
                    </div>
                  </div>
                ))
              ) : (
                <div className="setup-item">
                  <span className="setup-state-dot" aria-hidden="true" />
                  <div>
                    <strong>Проверяю состав</strong>
                    <span>Ищу sing-box, WinSW wrapper и службу.</span>
                  </div>
                </div>
              )}
            </div>
          ) : null}

          {isSingBoxInstalled ? (
            <div className="singbox-workspace">
              <div className="subscription-line">
                <span className="subscription-icon" aria-hidden="true">
                  <Link2 size={18} strokeWidth={1.9} />
                </span>
                <input
                  value={subscriptionInput}
                  onChange={(event) => setSubscriptionInput(event.target.value)}
                  placeholder={singBoxStatus?.config.subscriptionDisplayUrl ?? 'https://example.com/sub'}
                  spellCheck={false}
                />
                <button
                  type="button"
                  onClick={() => void syncSingBoxSubscription()}
                  disabled={singBoxAction === 'fetch'}
                >
                  {singBoxAction === 'fetch' ? '...' : subscriptionInput.trim() || !singBoxStatus?.config.hasSubscription ? 'Загрузить' : 'Обновить'}
                </button>
                <button
                  type="button"
                  className="icon-command"
                  onClick={() => void forgetSingBoxSubscriptionData()}
                  disabled={Boolean(singBoxAction) || !singBoxStatus?.config.hasSubscription}
                  aria-label="Очистить подписку Local sing-box"
                  title="Очистить"
                >
                  <Trash2 size={18} strokeWidth={1.9} />
                </button>
              </div>

              {singBoxStatus?.cache?.servers.length ? (
                <div className="server-list">
                  {singBoxStatus.cache.servers.map((server) => (
                    <button
                      type="button"
                      className={`server-row ${server.tag === singBoxStatus.config.selectedServerTag ? 'selected' : ''}`.trim()}
                      key={server.tag}
                      onClick={() => void chooseSingBoxServer(server)}
                      title={serverTooltip(server, serverPings[server.tag])}
                    >
                      <span className="server-select-dot" aria-hidden="true" />
                      <strong>{displayServerTag(server.tag)}</strong>
                    </button>
                  ))}
                </div>
              ) : (
                <div className="empty-state">Подписка Local sing-box еще не загружена.</div>
              )}
            </div>
          ) : (
            <div className="singbox-install-note">
              <strong>Local sing-box не установлен</strong>
              <span>Установи компонент, чтобы подключить подписку, выбрать сервер и включить локальный маршрут.</span>
            </div>
          )}
          </div>
        ) : null}

        <section className="apps-section">
          <div className="section-head">
            <h2>Приложения</h2>
            <span>{items.length}</span>
          </div>

          {isProcessInputOpen ? (
            <div className="process-add-line">
              <input
                value={processInput}
                onChange={(event) => setProcessInput(event.target.value)}
                onKeyDown={(event) => {
                  if (event.key === 'Enter') addProcess();
                  if (event.key === 'Escape') {
                    setProcessInput('');
                    setIsProcessInputOpen(false);
                  }
                }}
                placeholder="Discord"
                spellCheck={false}
                autoFocus
              />
              <button type="button" onClick={addProcess}>
                OK
              </button>
              <button
                type="button"
                className="process-cancel-button"
                onClick={() => {
                  setProcessInput('');
                  setIsProcessInputOpen(false);
                }}
              >
                Отмена
              </button>
            </div>
          ) : (
            <div className="add-toolbar" aria-label="Добавить приложение">
              <button
                type="button"
                className="add-tile"
                onClick={() => setIsProcessInputOpen(true)}
                aria-label="Добавить процесс"
                title="Процесс"
              >
                <Cpu size={22} strokeWidth={1.8} />
                <span className="sr-only">Процесс</span>
              </button>
              <button
                type="button"
                className="add-tile"
                onClick={() => void pickAndAddItem('exe')}
                disabled={Boolean(pickerAction)}
                aria-label="Добавить EXE-файл"
                title="EXE-файл"
              >
                {pickerAction === 'exe' ? <span className="tile-loading">...</span> : <FileCode2 size={22} strokeWidth={1.8} />}
                <span className="sr-only">EXE-файл</span>
              </button>
              <button
                type="button"
                className="add-tile"
                onClick={() => void pickAndAddItem('folder')}
                disabled={Boolean(pickerAction)}
                aria-label="Добавить папку"
                title="Папка"
              >
                {pickerAction === 'folder' ? <span className="tile-loading">...</span> : <FolderOpen size={22} strokeWidth={1.8} />}
                <span className="sr-only">Папка</span>
              </button>
            </div>
          )}

          <div className="app-list">
            {isLoading ? (
              <div className="list-skeleton" aria-label="Загрузка приложений">
                <span />
                <span />
              </div>
            ) : items.length ? (
              items.map((item) => (
                <div className="app-row" key={item.id}>
                  <div className="app-row-main">
                    <span className="item-icon" aria-hidden="true">
                      {itemIcon(item.type)}
                    </span>
                    <div>
                      <strong>{item.value}</strong>
                      <span>{itemTypeLabel(item.type)}</span>
                    </div>
                  </div>
                  <button type="button" onClick={() => removeItem(item.id)} aria-label={`Удалить ${item.value}`}>
                    Удалить
                  </button>
                </div>
              ))
            ) : (
              <div className="empty-state">Добавь процесс, папку или путь к EXE-файлу.</div>
            )}
          </div>
        </section>

        {hasUnappliedChanges ? (
          <div className="apply-state pending" role="status">
            <strong>Изменения еще не применены в ProxiFyre</strong>
            <span>{applyStateText(routeMode, isSingBoxInstalled, Boolean(singbox?.running))}</span>
          </div>
        ) : null}

        <div className="command-row">
          <button type="button" className="apply-button" onClick={updateConfig} disabled={isApplying}>
            {isApplying
              ? singBoxAction === 'start'
                ? 'Запускаю sing-box...'
                : singBoxAction === 'stop'
                  ? 'Перезапускаю sing-box...'
                  : 'Применяю...'
              : hasUnappliedChanges
                ? 'Применить в ProxiFyre'
                : 'Обновить конфиг'}
          </button>
          <button
            type="button"
            className="open-config-button"
            onClick={openConfig}
            disabled={isOpeningConfig}
          >
            {isOpeningConfig ? '...' : 'Открыть'}
          </button>
        </div>

        {generatedConfigPath ? <p className="config-path">{generatedConfigPath}</p> : null}
      </section>

      {logEntries.length ? (
        <aside className={`log-dock ${activeLog?.kind ?? 'idle'}`} aria-live="polite">
          <div className={`log-current ${activeLog ? 'visible' : 'hidden'}`}>
            {activeLog ? (
              <>
                <strong>{activeLog.title}</strong>
                <span>{activeLog.text}</span>
              </>
            ) : (
              <span className="log-muted">Журнал событий</span>
            )}
          </div>
          <button type="button" className="log-toggle" onClick={() => setIsLogOpen((current) => !current)}>
            {isLogOpen ? 'Скрыть' : 'Посмотреть'}
            <span>{logEntries.length}</span>
          </button>
          {isLogOpen ? (
            <div className="log-history">
              {logEntries.map((entry) => (
                <div className={`log-history-row ${entry.kind}`} key={entry.id}>
                  <time>{formatLogTime(entry.at)}</time>
                  <div>
                    <strong>{entry.title}</strong>
                    <span>{entry.text}</span>
                  </div>
                </div>
              ))}
            </div>
          ) : null}
        </aside>
      ) : null}
    </main>
  );
}

interface ParsedProxy {
  protocol: 'socks5';
  host: string;
  port: number;
}

function parseProxy(rawValue: string): ParsedProxy {
  const value = rawValue.trim();
  if (!value) throw new Error('Введи адрес прокси.');

  const withProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(value) ? value : `socks5://${value}`;
  let parsed: URL;
  try {
    parsed = new URL(withProtocol);
  } catch {
    throw new Error('Формат: socks5://host:port или host:port.');
  }

  const protocol = parsed.protocol.replace(':', '').toLowerCase();
  if (protocol !== 'socks5') {
    throw new Error('Сейчас поддерживается только SOCKS5.');
  }
  if (parsed.username || parsed.password) {
    throw new Error('Прокси с логином и паролем пока не поддерживаются.');
  }

  const host = parsed.hostname.replace(/^\[|\]$/g, '');
  const port = Number(parsed.port);
  if (!host || !Number.isInteger(port) || port < 1 || port > 65535) {
    throw new Error('Укажи хост и порт прокси.');
  }

  return { protocol: 'socks5', host, port };
}

function targetForUi(targets: Target[], profile: Profile | undefined) {
  if (profile) return targets.find((target) => target.id === profile.targetId);
  return targets.find((target) => target.id === MAIN_TARGET_ID) ?? targets.find((target) => target.kind === 'external');
}

function targetForExternalProxy(targets: Target[]) {
  return targets.find((target) => target.id === MAIN_TARGET_ID)
    ?? targets.find((target) => target.kind === 'external' && target.id !== LOCAL_SINGBOX_TARGET_ID);
}

function itemsForProfiles(profiles: Profile[]): DraftItem[] {
  const seen = new Set<string>();
  const items: DraftItem[] = [];

  for (const profile of profiles) {
    for (const item of profile.items) {
      if (item.type !== 'process' && item.type !== 'folder' && item.type !== 'exe') continue;

      const key = `${item.type}:${item.value.trim().toLowerCase()}`;
      if (seen.has(key)) continue;
      seen.add(key);
      items.push({
        id: `${item.type}-${items.length}-${item.value}`,
        type: item.type,
        value: item.value,
      });
    }
  }

  return items;
}

function formatProxy(target: Target) {
  return target.protocol === 'socks5'
    ? `${target.host}:${target.port}`
    : `${target.protocol}://${target.host}:${target.port}`;
}

function normalizeItemValue(value: string, type: DraftItemType) {
  const clean = value.trim().replace(/^"|"$/g, '');
  if (!clean) return '';
  if (type === 'folder' || type === 'exe') return clean;

  return clean
    .split(/[\\/]/)
    .pop()
    ?.replace(/\.exe$/i, '')
    .trim() ?? '';
}

async function pickPath(type: Extract<DraftItemType, 'exe' | 'folder'>) {
  const selected = await open(
    type === 'folder'
      ? {
          title: 'Выбери папку',
          directory: true,
          multiple: false,
        }
      : {
          title: 'Выбери EXE-файл',
          directory: false,
          multiple: false,
          filters: [{ name: 'EXE-файлы', extensions: ['exe'] }],
        },
  );

  if (Array.isArray(selected)) return selected[0] ?? null;
  return selected;
}

function nextFrame() {
  return new Promise<void>((resolve) => {
    window.requestAnimationFrame(() => resolve());
  });
}

function profileItemInput(item: DraftItem): ProfileItemInput {
  return {
    type: item.type,
    value: item.value,
    recursive: item.type === 'folder',
  };
}

function emptyItemMessage(type: DraftItemType) {
  if (type === 'process') return 'Введи имя процесса.';
  if (type === 'folder') return 'Введи путь к папке.';
  return 'Введи путь к EXE-файлу.';
}

function itemTypeLabel(type: DraftItemType) {
  if (type === 'process') return 'процесс';
  if (type === 'folder') return 'папка';
  return 'EXE-файл';
}

function itemIcon(type: DraftItemType) {
  if (type === 'process') return <Cpu size={18} strokeWidth={1.9} />;
  if (type === 'folder') return <FolderOpen size={18} strokeWidth={1.9} />;
  return <FileCode2 size={18} strokeWidth={1.9} />;
}

function setupItemDetails(installed: boolean, version: string | undefined, details: string) {
  if (!installed) return `Нужно установить. ${details}`;
  if (version) return `${version}. ${details}`;
  return details;
}

function profileInputFromProfile(profile: Profile, enabled: boolean) {
  return {
    id: profile.id,
    name: profile.name,
    enabled,
    targetId: profile.targetId,
    protocols: profile.protocols,
    items: profile.items.map((item) => ({
      type: item.type,
      value: item.value,
      recursive: item.recursive,
    })),
  };
}

function proxyfierTitle(component: ComponentStatus | undefined, checking: boolean) {
  if (checking) return 'Проверяю ProxiFyre';
  if (!component) return 'ProxiFyre не проверен';
  if (component.running) return 'ProxiFyre найден и запущен';
  if (component.installed) return 'ProxiFyre найден';
  return 'ProxiFyre не найден';
}

function proxyfierDetails(component: ComponentStatus | undefined, checking: boolean) {
  if (checking) return 'Ищу установленный клиент и состояние службы.';
  if (!component) return 'Нажми «Обновить», чтобы проверить компьютер.';
  if (component.path) return component.path;
  return component.problems[0] ?? 'Путь установки не найден.';
}

function singBoxTitle(component: ComponentStatus | undefined, checking: boolean) {
  if (checking) return 'Проверяю Local sing-box';
  if (!component) return 'Local sing-box не проверен';
  if (component.running) return 'Local sing-box найден и запущен';
  if (component.installed) return 'Local sing-box найден';
  return 'Local sing-box не установлен';
}

function singBoxDetails(
  component: ComponentStatus | undefined,
  status: LocalSingBoxStatusResponse | null,
  checking: boolean,
) {
  if (checking) return 'Ищу sing-box, wrapper и службу.';
  if (component?.running && status) {
    const lanAddress = lanSingBoxAddress(status);
    return lanAddress
      ? `Доступен локально: ${localSingBoxAddress(status)} · LAN: ${lanAddress}`
      : `Доступен локально: ${localSingBoxAddress(status)}`;
  }
  if (component?.installed) return 'Служба остановлена. Запусти Local sing-box перед применением маршрута.';
  if (status?.config.hasSubscription) {
    return status.config.subscriptionDisplayUrl ?? 'Подписка сохранена.';
  }
  return component?.problems[0] ?? 'Установи компонент, чтобы подключить подписку и выбрать сервер.';
}

function componentDetails(component: ComponentStatus | undefined, checking: boolean) {
  if (checking) return 'Проверяю состояние службы.';
  if (!component) return 'Компонент не проверен.';
  if (component.path) return component.path;
  return component.problems[0] ?? 'Путь установки не найден.';
}

function noticeFromApply(result: ApplyProfilesResponse): Notice {
  return {
    kind: result.success ? 'success' : 'error',
    title: result.success ? 'Конфиг обновлен' : 'Конфиг создан, но не применен',
    text: result.message,
  };
}

function noticeFromLocalApply(result: ApplyProfilesResponse, singBoxGeneratedPath: string): Notice {
  return {
    kind: result.success ? 'success' : 'error',
    title: result.success ? 'Local sing-box применен' : 'Конфиг создан, но не применен',
    text: singBoxGeneratedPath ? `${result.message} sing-box: ${singBoxGeneratedPath}` : result.message,
  };
}

function applyStateText(routeMode: RouteMode, isSingBoxInstalled: boolean, isSingBoxRunning: boolean) {
  if (routeMode === 'local-singbox' && isSingBoxInstalled && !isSingBoxRunning) {
    return 'Local sing-box сейчас остановлен. При применении клиент сначала запустит службу, затем обновит ProxiFyre.';
  }
  if (routeMode === 'local-singbox' && isSingBoxInstalled && isSingBoxRunning) {
    return 'При применении клиент обновит конфиг, перезапустит Local sing-box и затем обновит ProxiFyre.';
  }
  return 'Нажми «Применить в ProxiFyre». Если служба уже запущена и маршрут не обновился, перезапусти ProxiFyre.';
}

function upsertComponent(components: ComponentStatus[], component: ComponentStatus) {
  const index = components.findIndex((current) => current.id === component.id);
  if (index === -1) return [...components, component];

  return [
    ...components.slice(0, index),
    component,
    ...components.slice(index + 1),
  ];
}

function sameValue(left: string, right: string) {
  return left.trim().toLowerCase() === right.trim().toLowerCase();
}

function formatLogTime(timestamp: number) {
  return new Date(timestamp).toLocaleTimeString('ru-RU', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit',
  });
}

function serverLabel(server: SubscriptionServer) {
  return `${server.type} · ${server.server}:${server.serverPort}`;
}

function serverTooltip(server: SubscriptionServer, ping: PingServerResponse | undefined) {
  const details = serverLabel(server);
  if (!ping) return details;
  return ping.ok ? `${details} · ping ${ping.latency ?? 0} ms` : `${details} · ping fail`;
}

function displayServerTag(tag: string) {
  const withoutFlags = tag
    .replace(/[\u{1f1e6}-\u{1f1ff}]/gu, '')
    .replace(/\s*->\s*/g, ' -> ')
    .replace(/\s*->\s*$/g, '')
    .replace(/^\s*->\s*/g, '')
    .replace(/\s{2,}/g, ' ')
    .trim();

  return withoutFlags || tag;
}

function pingSummary(results: PingServerResponse[]) {
  if (!results.length) return 'Серверов для проверки нет.';
  const ok = results.filter((result) => result.ok);
  if (!ok.length) return `Не ответил ни один сервер из ${results.length}.`;
  const best = ok.reduce((current, result) => {
    if ((result.latency ?? Number.MAX_SAFE_INTEGER) < (current.latency ?? Number.MAX_SAFE_INTEGER)) return result;
    return current;
  });
  return `Ответили ${ok.length}/${results.length}; быстрее ${best.tag}: ${best.latency ?? 0} ms.`;
}

function localSingBoxAddress(status: LocalSingBoxStatusResponse | null) {
  if (!status) return 'не загружен';
  const host = status.config.listenHost.trim();
  const displayHost = host === '0.0.0.0' || host === '::' || !host ? '127.0.0.1' : host;
  return formatHostPort(displayHost, status.config.listenPort);
}

function lanSingBoxAddress(status: LocalSingBoxStatusResponse | null) {
  if (!status) return null;
  const host = status.config.listenHost.trim().toLowerCase();
  if (host === '127.0.0.1' || host === 'localhost' || host === '::1') return null;
  const lanHost = host === '0.0.0.0' || host === '::' || !host
    ? status.lanListenHost
    : status.config.listenHost;
  if (!lanHost) return null;
  return formatHostPort(lanHost, status.config.listenPort);
}

function formatHostPort(host: string, port: number) {
  return host.includes(':') && !host.startsWith('[') ? `[${host}]:${port}` : `${host}:${port}`;
}

function errorMessage(error: unknown) {
  if (error instanceof Error) return error.message;
  if (typeof error === 'string') return error;
  if (error && typeof error === 'object' && 'message' in error) {
    return String((error as { message: unknown }).message);
  }
  return 'Неизвестная ошибка.';
}
