import { useState, useRef, useEffect } from "react";
import {
  githubOpenLoginWindow,
  githubPollOAuth,
  githubFetchUser,
  githubSaveAccount,
  githubGetClientId,
  updateSettings,
  type GitAccount,
} from "../../lib/commands";
import { useUIStore } from "../../store/ui";

type Step = "checking" | "setup" | "idle" | "waiting" | "done" | "error";

interface Props {
  onLogin: (account: GitAccount) => void;
}

export default function LoginPage({ onLogin }: Props) {
  const showToast = useUIStore((s) => s.showToast);
  const [step, setStep] = useState<Step>("checking");
  const [errorMsg, setErrorMsg] = useState("");
  const [clientId, setClientId] = useState("");
  const [clientSecret, setClientSecret] = useState("");
  const [savingConfig, setSavingConfig] = useState(false);

  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const cancelledRef = useRef(false);

  // 启动时检查是否已配置 OAuth App
  useEffect(() => {
    githubGetClientId()
      .then(() => setStep("idle"))
      .catch(() => setStep("setup"));
  }, []);

  useEffect(() => () => {
    cancelledRef.current = true;
    if (pollRef.current) clearInterval(pollRef.current);
  }, []);

  const stopPolling = () => {
    if (pollRef.current) { clearInterval(pollRef.current); pollRef.current = null; }
  };

  const handleSaveConfig = async () => {
    if (!clientId.trim() || !clientSecret.trim()) {
      showToast("❌ Client ID 和 Client Secret 均不能为空");
      return;
    }
    setSavingConfig(true);
    try {
      await updateSettings({
        github_client_id: clientId.trim(),
        github_client_secret: clientSecret.trim(),
      });
      showToast("配置已保存 ✓");
      setStep("idle");
    } catch (e) {
      showToast(`❌ ${e}`);
    } finally {
      setSavingConfig(false);
    }
  };

  const handleLogin = async () => {
    cancelledRef.current = false;
    setErrorMsg("");
    setStep("waiting");
    try {
      await githubOpenLoginWindow();
      pollRef.current = setInterval(async () => {
        if (cancelledRef.current) { stopPolling(); return; }
        try {
          const token = await githubPollOAuth();
          if (token === null) return;
          stopPolling();
          const user = await githubFetchUser(token);
          const account = await githubSaveAccount(user.login, user.avatar_url, token);
          if (cancelledRef.current) return;
          setStep("done");
          onLogin(account);
        } catch (e) {
          stopPolling();
          setStep("error");
          setErrorMsg(String(e));
        }
      }, 2000);
    } catch (e) {
      setStep("error");
      setErrorMsg(String(e));
    }
  };

  const handleCancel = () => {
    cancelledRef.current = true;
    stopPolling();
    setStep("idle");
    setErrorMsg("");
  };

  return (
    <div className="flex flex-col items-center justify-center h-full gap-8 p-8">
      <div className="text-center">
        <h1 className="text-2xl font-bold mb-2">Dev Space Manager</h1>
        <p className="text-zinc-400 text-sm">基于 Git 的本地开发空间管理器</p>
      </div>

      {step === "checking" && (
        <div className="w-5 h-5 border-2 border-zinc-600 border-t-transparent rounded-full animate-spin" />
      )}

      {step === "setup" && (
        <div className="w-80 bg-zinc-800 rounded-xl border border-zinc-700 p-5 space-y-4">
          <div>
            <p className="text-sm font-semibold text-white mb-1">配置 GitHub OAuth App</p>
            <p className="text-xs text-zinc-400 leading-relaxed">
              前往 GitHub → Settings → Developer settings → OAuth Apps 创建应用。
              Callback URL 填 <code className="bg-zinc-700 px-1 rounded">http://localhost</code>，
              勾选 Enable Device Flow 无需勾选。
            </p>
          </div>
          <div className="space-y-3">
            <div>
              <label className="block text-xs text-zinc-400 mb-1">Client ID</label>
              <input
                value={clientId}
                onChange={(e) => setClientId(e.target.value)}
                placeholder="Ov23li..."
                className="w-full bg-zinc-900 border border-zinc-600 rounded-lg px-3 py-2 text-sm text-white font-mono outline-none focus:ring-2 focus:ring-blue-500 placeholder:text-zinc-600"
              />
            </div>
            <div>
              <label className="block text-xs text-zinc-400 mb-1">Client Secret</label>
              <input
                type="password"
                value={clientSecret}
                onChange={(e) => setClientSecret(e.target.value)}
                placeholder="••••••••••••••••••••••••••••••••••••"
                className="w-full bg-zinc-900 border border-zinc-600 rounded-lg px-3 py-2 text-sm text-white font-mono outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>
          </div>
          <p className="text-xs text-zinc-500">Secret 仅存于本机 SQLite，由 Rust 完成 token 交换。</p>
          <button
            onClick={handleSaveConfig}
            disabled={savingConfig}
            className="w-full py-2 rounded-lg text-sm bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50 transition-colors"
          >
            {savingConfig ? "保存中…" : "保存并继续"}
          </button>
        </div>
      )}

      {step === "idle" && (
        <div className="flex flex-col items-center gap-3 w-72">
          <button
            onClick={handleLogin}
            className="w-full px-6 py-2.5 bg-zinc-100 text-zinc-900 rounded-lg font-medium hover:bg-white transition-colors flex items-center justify-center gap-2"
          >
            <svg viewBox="0 0 16 16" className="w-4 h-4 fill-current shrink-0">
              <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" />
            </svg>
            使用 GitHub 登录
          </button>
          <button
            onClick={() => setStep("setup")}
            className="text-xs text-zinc-500 hover:text-zinc-300 underline"
          >
            重新配置 OAuth App
          </button>
        </div>
      )}

      {step === "waiting" && (
        <div className="flex flex-col items-center gap-4 p-6 bg-zinc-800 rounded-xl border border-zinc-700 w-72 text-center">
          <div className="w-7 h-7 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" />
          <p className="text-sm text-zinc-200">请在浏览器中完成 GitHub 授权</p>
          <p className="text-xs text-zinc-500">授权完成后应用自动登录</p>
          <button onClick={handleCancel} className="text-xs text-zinc-500 hover:text-zinc-300 underline">
            取消
          </button>
        </div>
      )}

      {step === "done" && (
        <p className="text-green-400 text-sm">登录成功！</p>
      )}

      {step === "error" && (
        <div className="flex flex-col items-center gap-3 w-80">
          <p className="text-red-400 text-sm text-center">{errorMsg}</p>
          {errorMsg.includes("代理") && (
            <p className="text-xs text-zinc-500 text-center">
              请确认 v2rayN 系统代理已开启后重试
            </p>
          )}
          <div className="flex gap-3">
            <button onClick={handleCancel} className="px-4 py-2 bg-zinc-700 rounded-lg text-sm hover:bg-zinc-600">
              重试
            </button>
            <button
              onClick={() => setStep("setup")}
              className="px-4 py-2 bg-zinc-700 rounded-lg text-sm hover:bg-zinc-600 text-zinc-300"
            >
              重新配置
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
