import { FormEvent, useEffect, useMemo, useState } from "react";
import { invoke } from "@tauri-apps/api/core";

type EnrollmentState = {
  assignedIp: string;
  resources: string[];
  profileRevision: number;
  gatewayEndpoint: string;
  profilePath: string;
  lastSyncTime: string;
  tunnelStrategy: string;
};

function formatInvokeError(err: unknown, fallback: string) {
  if (typeof err === "string" && err.trim().length > 0) {
    return err;
  }

  if (err instanceof Error && err.message.trim().length > 0) {
    return err.message;
  }

  return fallback;
}

function currentProfileLabel(state: EnrollmentState | null) {
  if (!state) {
    return "Not provisioned";
  }

  if (state.resources.includes("0.0.0.0/0")) {
    return "Full tunnel";
  }

  if (state.resources.length === 1) {
    return "Single resource access";
  }

  return `Split tunnel (${state.resources.length} resources)`;
}

export function App() {
  const [serverUrl, setServerUrl] = useState("http://localhost");
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [loading, setLoading] = useState(false);
  const [syncing, setSyncing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [connected, setConnected] = useState(false);
  const [state, setState] = useState<EnrollmentState | null>(null);

  useEffect(() => {
    void invoke<EnrollmentState | null>("load_state")
      .then((value) => {
        if (value) {
          setState(value);
        }
      })
      .catch(() => undefined);
  }, []);

  const profileLabel = useMemo(() => currentProfileLabel(state), [state]);

  async function onSubmit(event: FormEvent) {
    event.preventDefault();
    setLoading(true);
    setError(null);

    try {
      const result = await invoke<EnrollmentState>("enroll_device", {
        payload: { serverUrl, username, password }
      });
      setState(result);
    } catch (err) {
      setError(formatInvokeError(err, "Enrollment failed"));
    } finally {
      setLoading(false);
    }
  }

  async function onSyncProfile() {
    setSyncing(true);
    setError(null);

    try {
      const result = await invoke<EnrollmentState>("sync_profile");
      setState(result);
    } catch (err) {
      setError(formatInvokeError(err, "Profile sync failed"));
    } finally {
      setSyncing(false);
    }
  }

  async function toggleConnection() {
    const command = connected ? "disconnect_tunnel" : "connect_tunnel";
    try {
      await invoke(command);
      setConnected((value) => !value);
      setError(null);
    } catch (err) {
      setError(formatInvokeError(err, "Tunnel action failed"));
    }
  }

  async function resetEnrollment() {
    try {
      await invoke("clear_session");
      setConnected(false);
      setState(null);
      setError(null);
    } catch (err) {
      setError(formatInvokeError(err, "Unable to clear local profile"));
    }
  }

  return (
    <div className="client-shell">
      <div className="app-frame">
        <div className="top-strip">
          <div className="brand-lockup">
            <img src="/icon.png" alt="NexaVPN" />
            <div className="brand-copy">
              <p className="eyebrow">NexaVPN</p>
              <h1>VPN Client</h1>
              <p>{state ? "Private access client" : "Sign in to add this device"}</p>
            </div>
          </div>
          <div className="top-actions">
            {state ? (
              <button className="shell-button-secondary" disabled={syncing} onClick={onSyncProfile} type="button">
                {syncing ? "Syncing..." : "Sync"}
              </button>
            ) : null}
            {state ? (
              <button className="shell-button-secondary" onClick={resetEnrollment} type="button">
                Logout
              </button>
            ) : null}
            <button className="shell-button" disabled={!state} onClick={toggleConnection} type="button">
              {!state ? "Provision first" : connected ? "Disconnect" : "Connect"}
            </button>
          </div>
        </div>

        <div className="body-grid">
          {!state ? (
            <section className="login-panel">
              <div className="surface-header">
                <div>
                  <p className="eyebrow">Sign in</p>
                  <h3>Provision device</h3>
                </div>
              </div>
              <form onSubmit={onSubmit}>
                <label>
                  VPN server address
                  <input value={serverUrl} onChange={(event) => setServerUrl(event.target.value)} />
                </label>
                <label>
                  Username
                  <input value={username} onChange={(event) => setUsername(event.target.value)} />
                </label>
                <label>
                  Password
                  <input type="password" value={password} onChange={(event) => setPassword(event.target.value)} />
                </label>
                {error ? <div className="error">{error}</div> : null}
                <div className="login-card-actions">
                  <button className="shell-button" disabled={loading} type="submit">
                    {loading ? "Provisioning..." : "Sign in"}
                  </button>
                </div>
              </form>
            </section>
          ) : (
            <section className="status-panel">
              <div className="status-top">
                <div>
                  <p className="eyebrow">Status</p>
                  <h3>{connected ? "Connected" : "Disconnected"}</h3>
                  <div className="status-state">
                    <span className={`status-dot ${connected ? "online" : ""}`} />
                    {connected ? "Tunnel active" : "Ready"}
                  </div>
                </div>
              </div>

              <div className="surface">
                <div className="surface-header">
                  <div>
                    <p className="eyebrow">Connection</p>
                    <h4>Overview</h4>
                  </div>
                </div>
                <div className="status-grid">
                  <div className="detail-card">
                    <span>Assigned VPN IP</span>
                    <strong>{state.assignedIp}</strong>
                  </div>
                  <div className="detail-card">
                    <span>Gateway endpoint</span>
                    <strong>{state.gatewayEndpoint}</strong>
                  </div>
                  <div className="detail-card">
                    <span>Access</span>
                    <strong>{profileLabel}</strong>
                  </div>
                  <div className="detail-card">
                    <span>Last sync</span>
                    <strong>{state.lastSyncTime}</strong>
                  </div>
                </div>
              </div>

              {error ? <div className="error">{error}</div> : null}
            </section>
          )}

          <aside className="status-panel">
            <div className="surface-header">
              <div>
                <p className="eyebrow">Access</p>
                <h4>Resources</h4>
              </div>
            </div>
            <p>Press <strong>Sync</strong> after policy changes.</p>
            <ul className="resource-stack">
              {(state?.resources ?? ["No resources assigned yet"]).map((resource) => (
                <li key={resource}>{resource}</li>
              ))}
            </ul>
            {state ? (
              <button className="shell-button-secondary" onClick={resetEnrollment} type="button">
                Neu einbinden
              </button>
            ) : null}
          </aside>
        </div>
      </div>
    </div>
  );
}
