import React, { useEffect, useMemo, useState } from 'react';
import { flagFor } from '../utils/country.js';
import { formatRelative } from '../utils/format.js';
import { resolveClientRoute } from '../utils/clientRoute.js';

function CopyValue({ value }) {
  const [copied, setCopied] = useState(false);

  async function copy() {
    await navigator.clipboard.writeText(value);
    setCopied(true);
    setTimeout(() => setCopied(false), 1200);
  }

  return (
    <button className="client-copy" type="button" onClick={copy}>
      <span>{value}</span>
      <strong>{copied ? 'OK' : 'Copy'}</strong>
    </button>
  );
}

function StatusPanel({ route, state }) {
  const statusLabel = {
    connected: 'Работает',
    stopped: 'Остановлен',
    empty: 'Не настроен',
  }[route.status];

  return (
    <section className={`client-status-panel ${route.status}`}>
      <div className="client-status-main">
        <span className={`client-status-dot ${route.status}`} />
        <div>
          <div className="client-eyebrow">Текущий маршрут</div>
          <h1>{route.title}</h1>
          <p>{route.description}</p>
        </div>
      </div>
      <div className="client-status-facts">
        <div>
          <small>Куда</small>
          <strong>{route.target}</strong>
          <span>{route.targetDetail}</span>
        </div>
        <div>
          <small>Локальный proxy</small>
          <strong>{route.localProxy}</strong>
          <span>HTTP и SOCKS5</span>
        </div>
        <div>
          <small>Сервис</small>
          <strong>{statusLabel}</strong>
          <span>{state?.appliedAt ? `применено ${formatRelative(state.appliedAt)}` : 'нет примененного config'}</span>
        </div>
      </div>
    </section>
  );
}

function RouteLine({ route }) {
  return (
    <div className="client-route-line">
      {route.path.map((item, index) => (
        <React.Fragment key={`${item}-${index}`}>
          <span>{item}</span>
          {index < route.path.length - 1 && <b>→</b>}
        </React.Fragment>
      ))}
    </div>
  );
}

function ModeButton({ active, selected, title, subtitle, onClick, disabled }) {
  return (
    <button
      type="button"
      className={`client-mode-button ${selected ? 'selected' : ''} ${active ? 'active' : ''}`}
      disabled={disabled}
      onClick={onClick}
    >
      <strong>{title}</strong>
      <span>{subtitle}</span>
    </button>
  );
}

function GatewaySettings({ settings, busy, onCheck }) {
  const [draftUrl, setDraftUrl] = useState(settings?.sharedProxyControlUrl || '');
  const sharedProxy = settings?.sharedProxy;

  useEffect(() => {
    setDraftUrl(settings?.sharedProxyControlUrl || '');
  }, [settings?.sharedProxyControlUrl]);

  return (
    <div className="client-mode-settings">
      <div className="field">
        <label className="field-label">Адрес gateway UI</label>
        <div className="client-inline-form">
          <input
            className="input"
            placeholder="http://192.168.50.111:3456"
            value={draftUrl}
            onChange={(e) => setDraftUrl(e.target.value)}
            onKeyDown={(e) => e.key === 'Enter' && draftUrl && onCheck(draftUrl)}
          />
          <button className="btn btn-primary" disabled={busy || !draftUrl} onClick={() => onCheck(draftUrl)}>
            Подключить
          </button>
        </div>
      </div>
      {sharedProxy && (
        <div className="client-current-target">
          <small>Найден общий proxy</small>
          <strong>{sharedProxy.host}:{sharedProxy.port}</strong>
        </div>
      )}
    </div>
  );
}

function VpnSettings({
  state,
  servers,
  subscriptionUrl,
  setSubscriptionUrl,
  pendingTag,
  setPendingTag,
  busy,
  onFetchSubscription,
  onApply,
}) {
  const selected = pendingTag || state?.selectedTag || '';
  const activeServer = servers.find((server) => server.tag === selected);

  return (
    <div className="client-mode-settings">
      <div className="field">
        <label className="field-label">Подписка или VLESS</label>
        <div className="client-inline-form">
          <input
            className="input"
            placeholder="https://… или vless://…"
            value={subscriptionUrl}
            onChange={(e) => setSubscriptionUrl(e.target.value)}
            onKeyDown={(e) => e.key === 'Enter' && subscriptionUrl && onFetchSubscription()}
          />
          <button className="btn btn-secondary" disabled={busy || !subscriptionUrl} onClick={onFetchSubscription}>
            Загрузить
          </button>
        </div>
      </div>
      <div className="field">
        <label className="field-label">VPN-сервер</label>
        <div className="client-inline-form">
          <select
            className="select"
            value={selected}
            disabled={!servers.length}
            onChange={(e) => setPendingTag(e.target.value)}
          >
            <option value="">Выберите сервер</option>
            {servers.map((server) => (
              <option key={server.tag} value={server.tag}>
                {flagFor(server)} {server.tag}
              </option>
            ))}
          </select>
          <button className="btn btn-primary" disabled={busy || !selected} onClick={() => onApply(selected)}>
            Подключить
          </button>
        </div>
        {activeServer && <small className="field-hint">Выбран {flagFor(activeServer)} {activeServer.tag}</small>}
      </div>
    </div>
  );
}

function DirectSettings({ busy, onEnable }) {
  return (
    <div className="client-mode-settings direct">
      <div>
        <strong>Прямой режим</strong>
        <p className="muted">Приложения продолжают использовать локальный proxy, но трафик идет без VPN и без gateway.</p>
      </div>
      <button className="btn btn-primary" disabled={busy} onClick={onEnable}>
        Включить напрямую
      </button>
    </div>
  );
}

function ProxySettings({ state, settings, busy, onSave }) {
  const range = state?.clientProxyPortRange || { start: 8080, end: 8090 };
  const port = settings?.proxyPort || state?.proxyPort || 8080;
  const [draftPort, setDraftPort] = useState(String(port));

  useEffect(() => {
    setDraftPort(String(port));
  }, [port]);

  const parsed = Number.parseInt(draftPort, 10);
  const invalid = !Number.isInteger(parsed) || parsed < range.start || parsed > range.end;
  const dirty = !invalid && parsed !== port;
  const singlePublishedPort = range.start === range.end;

  return (
    <aside className="client-side-panel">
      <div>
        <div className="client-panel-title">Адрес для приложений</div>
        <div className="client-copy-stack">
          <CopyValue value={`http://127.0.0.1:${port}`} />
          <CopyValue value={`socks5://127.0.0.1:${port}`} />
        </div>
      </div>
      <div className="field">
        <label className="field-label">Порт proxy</label>
        <div className="client-port-row">
          <input
            className="input"
            type="number"
            min={range.start}
            max={range.end}
            value={draftPort}
            disabled={singlePublishedPort}
            onChange={(e) => setDraftPort(e.target.value)}
          />
          <button
            className="btn btn-secondary"
            disabled={busy || singlePublishedPort || !dirty}
            onClick={() => onSave({ ...settings, proxyPort: parsed })}
          >
            Save
          </button>
        </div>
        <small className={invalid ? 'field-error' : 'field-hint'}>
          {singlePublishedPort ? 'Порт задаётся установщиком' : `${range.start}–${range.end}`}
        </small>
      </div>
    </aside>
  );
}

export function ClientOverviewPage({
  state,
  activeServer,
  busy,
  subscriptionUrl,
  setSubscriptionUrl,
  servers,
  pendingTag,
  setPendingTag,
  clientSettings,
  onSaveClientSettings,
  onCheckSharedProxy,
  onFetchSubscription,
  onApply,
}) {
  const route = useMemo(
    () => resolveClientRoute({ state, activeServer }),
    [state, activeServer],
  );
  const [setupMode, setSetupMode] = useState(route.mode === 'none' ? 'gateway' : route.mode);

  useEffect(() => {
    if (route.mode !== 'none') setSetupMode(route.mode);
  }, [route.mode]);

  function enableDirect() {
    return onSaveClientSettings({
      ...clientSettings,
      homeBypassEnabled: true,
      sharedProxyEnabled: false,
    });
  }

  function selectGateway() {
    setSetupMode('gateway');
    if (clientSettings?.sharedProxyControlUrl) {
      return onCheckSharedProxy(clientSettings.sharedProxyControlUrl);
    }
    return null;
  }

  function selectVpn() {
    setSetupMode('vpn');
    if (state?.selectedTag) {
      return onApply(state.selectedTag);
    }
    return onSaveClientSettings({
      ...clientSettings,
      homeBypassEnabled: false,
      sharedProxyEnabled: false,
    });
  }

  return (
    <div className="client-dashboard">
      <StatusPanel route={route} state={state} />
      <RouteLine route={route} />

      <section className="client-workspace">
        <div className="client-main-panel">
          <div className="client-mode-grid">
            <ModeButton
              active={route.mode === 'gateway'}
              selected={setupMode === 'gateway'}
              title="Общий gateway"
              subtitle={clientSettings?.sharedProxy ? `${clientSettings.sharedProxy.host}:${clientSettings.sharedProxy.port}` : 'серверная proxy'}
              disabled={busy}
              onClick={selectGateway}
            />
            <ModeButton
              active={route.mode === 'vpn'}
              selected={setupMode === 'vpn'}
              title="Локальный VPN"
              subtitle={state?.selectedTag || 'выбрать сервер'}
              disabled={busy}
              onClick={selectVpn}
            />
            <ModeButton
              active={route.mode === 'direct'}
              selected={setupMode === 'direct'}
              title="Напрямую"
              subtitle="без VPN"
              disabled={busy}
              onClick={() => {
                setSetupMode('direct');
                enableDirect();
              }}
            />
          </div>

          {setupMode === 'gateway' && (
            <GatewaySettings
              settings={clientSettings}
              busy={busy}
              onCheck={onCheckSharedProxy}
            />
          )}
          {setupMode === 'vpn' && (
            <VpnSettings
              state={state}
              servers={servers}
              subscriptionUrl={subscriptionUrl}
              setSubscriptionUrl={setSubscriptionUrl}
              pendingTag={pendingTag}
              setPendingTag={setPendingTag}
              busy={busy}
              onFetchSubscription={onFetchSubscription}
              onApply={onApply}
            />
          )}
          {setupMode === 'direct' && (
            <DirectSettings busy={busy} onEnable={enableDirect} />
          )}
        </div>

        <ProxySettings
          state={state}
          settings={clientSettings}
          busy={busy}
          onSave={onSaveClientSettings}
        />
      </section>
    </div>
  );
}
