import React, { useEffect, useState } from 'react';
import { createRoot } from 'react-dom/client';
import './styles.css';
import { api } from './api.js';
import { ClientOverviewPage } from './components/ClientOverviewPage.jsx';

function App() {
  const previewReady = new URLSearchParams(window.location.search).has('preview-ready');
  const [state, setState] = useState(null);
  const [subscriptionUrl, setSubscriptionUrl] = useState('');
  const [servers, setServers] = useState([]);
  const [pendingTag, setPendingTag] = useState('');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');

  async function loadState() {
    const data = await api.state();
    setState(data);
    setServers(data.servers || []);
    setPendingTag((current) => (
      (data.servers || []).some((server) => server.tag === current)
        ? current
        : data.selectedTag || ''
    ));
  }

  useEffect(() => {
    loadState().catch((err) => setError(err.message));
    const timer = setInterval(() => loadState().catch(() => {}), 5000);
    return () => clearInterval(timer);
  }, []);

  useEffect(() => {
    if (!state?.mode) return;
    const isGateway = state.mode === 'gateway';
    document.title = isGateway ? 'Harbor Gateway' : 'Harbor Connect';
    document.getElementById('harbor-favicon').href = isGateway
      ? '/harbor-gateway.svg'
      : '/harbor-connect.svg';
  }, [state?.mode]);

  async function run(action) {
    setBusy(true);
    setError('');
    try {
      await action();
      await loadState();
    } catch (err) {
      setError(err.message);
      throw err;
    } finally {
      setBusy(false);
    }
  }

  async function fetchSubscription() {
    return run(async () => {
      const data = await api.subscription.fetch(subscriptionUrl);
      setServers(data.servers || []);
      setPendingTag('');
    });
  }

  async function refreshSubscription() {
    const data = await api.subscription.refresh();
    setState((current) => current ? {
      ...current,
      userInfo: data.userInfo,
      fetchedAt: data.fetchedAt,
      servers: data.servers,
      selectedTag: data.selectedTag,
    } : current);
    setServers(data.servers || []);
    setPendingTag(data.selectedTag || '');
    return data;
  }

  async function forgetSubscription() {
    return run(async () => {
      await api.subscription.forget();
      setSubscriptionUrl('');
      setServers([]);
      setPendingTag('');
    });
  }

  if (!state) return <div className="app-loading">Harbor</div>;

  return (
    <div className="app client-app">
      <div className="app-body client-mode">
        <main className="app-main">
          <ClientOverviewPage
            state={previewReady ? { ...state, mode: 'client', hasSubscription: true, subscriptionHost: 'harbor.example', selectedTag: 'Amsterdam', proxyPort: 8082 } : state}
            busy={busy}
            error={error}
            subscriptionUrl={subscriptionUrl}
            setSubscriptionUrl={setSubscriptionUrl}
            servers={previewReady ? [{ tag: 'Amsterdam', server: '127.0.0.1', server_port: 443 }] : servers}
            pendingTag={previewReady ? 'Amsterdam' : pendingTag}
            setPendingTag={setPendingTag}
            onFetchSubscription={fetchSubscription}
            onRefreshSubscription={refreshSubscription}
            onForgetSubscription={forgetSubscription}
            onApply={(tag) => run(() => api.apply(tag))}
            onRestart={() => run(api.singbox.restart)}
            onStop={() => run(api.singbox.stop)}
            onSetGatewayAuto={(enabled) => run(() => api.gatewayAuto.setEnabled(enabled))}
          />
        </main>
      </div>
    </div>
  );
}

createRoot(document.getElementById('root')).render(<App />);
