import { useEffect, useState } from "react";
import { Copy, ExternalLink, Loader2, ShieldCheck, X } from "lucide-react";
import { authorize, cancelAuthorize, onCliAuth } from "../ipc";
import type { AuthFlowEvent, AuthModeInfo } from "../ipc/types";
import { Modal } from "./Modal";

/** 官方授权方式中文名 */
function authModeLabel(mode: string): string {
  switch (mode) {
    case "browser_oauth":
      return "账号授权（浏览器）";
    case "device_code":
      return "设备码";
    case "api_key":
      return "API Key";
    case "local_tui":
      return "本机终端授权";
    default:
      return mode;
  }
}

function modeButtonLabel(mode: string): string {
  switch (mode) {
    case "browser_oauth":
      return "开始授权";
    case "device_code":
      return "开始授权";
    case "local_tui":
      return "打开终端授权";
    case "api_key":
      return "用已保存的 Key 授权";
    default:
      return "去授权";
  }
}

interface FlowState {
  mode: string;
  events: AuthFlowEvent[];
  device: { code: string; url: string } | null;
  done: boolean | null; // null=进行中
}

/** 软件内授权面板（Wave 2.2 Req 2）：把「说明文字」升级为可操作授权流程。
 *  覆盖 API Key / 浏览器 / 设备码 / 本机终端四类，事件流经 cli-auth-event 实时回传。 */
export function AuthPanel({
  id,
  authModes,
  onAuthChanged,
}: {
  id: string;
  authModes: AuthModeInfo[];
  onAuthChanged: () => void;
}) {
  const [flow, setFlow] = useState<FlowState | null>(null);

  useEffect(() => {
    let unlisten: (() => void) | undefined;
    onCliAuth((ev) => {
      if (ev.cli_id !== id) return;
      setFlow((f) => {
        if (!f) return f;
        const next: FlowState = { ...f, events: [...f.events, ev] };
        if (ev.kind === "device_code" && ev.user_code && ev.verification_url) {
          next.device = { code: ev.user_code, url: ev.verification_url };
        }
        if (ev.kind === "done") {
          next.done = ev.authorized ?? false;
          onAuthChanged();
        }
        if (ev.kind === "error" || ev.kind === "cancelled") {
          next.done = false;
        }
        return next;
      });
    }).then((fn) => {
      unlisten = fn;
    });
    return () => unlisten?.();
  }, [id, onAuthChanged]);

  function start(mode: string) {
    setFlow({ mode, events: [], device: null, done: null });
    void authorize(id, mode);
  }

  function cancel() {
    if (flow) void cancelAuthorize(id, flow.mode);
  }

  function close() {
    setFlow(null);
  }

  if (authModes.length === 0) return null;

  return (
    <>
      <ul className="auth-modes">
        {authModes.map((m) => (
          <li key={m.mode} className="auth-mode">
            <span className="auth-mode-name">{authModeLabel(m.mode)}</span>
            {m.notes_zh && <span className="auth-mode-note">{m.notes_zh}</span>}
            <button type="button" className="btn btn-secondary auth-mode-action" onClick={() => start(m.mode)}>
              {modeButtonLabel(m.mode)}
            </button>
          </li>
        ))}
      </ul>

      {flow && (
        <Modal
          title={`${authModeLabel(flow.mode)}授权 · ${id}`}
          onClose={flow.done == null ? undefined : close}
          footer={
            flow.done == null ? (
              <button type="button" className="btn btn-secondary" onClick={cancel}>
                <X size={14} strokeWidth={1.5} aria-hidden="true" /> 取消授权
              </button>
            ) : (
              <button type="button" className="btn btn-primary" onClick={close}>
                完成
              </button>
            )
          }
        >
          <AuthFlowBody flow={flow} />
        </Modal>
      )}
    </>
  );
}

function AuthFlowBody({ flow }: { flow: FlowState }) {
  const { device, events, done } = flow;
  return (
    <div className="auth-flow">
      {/* 设备码：大号验证码 + 一键复制 + 打开授权网页 */}
      {device && (
        <div className="auth-device">
          <div className="auth-device-label">在浏览器打开验证链接，输入以下设备码</div>
          <div className="auth-device-code">
            <span className="auth-device-code-text">{device.code}</span>
            <button
              type="button"
              className="btn btn-secondary auth-copy"
              onClick={() => void navigator.clipboard.writeText(device.code)}
            >
              <Copy size={14} strokeWidth={1.5} aria-hidden="true" /> 复制
            </button>
          </div>
          <a className="btn btn-primary auth-open" href={device.url} target="_blank" rel="noreferrer">
            <ExternalLink size={14} strokeWidth={1.5} aria-hidden="true" /> 打开授权网页
          </a>
          <div className="auth-device-hint">请在弹出的浏览器里完成确认，本软件会轮询授权结果。</div>
        </div>
      )}

      {/* 状态行 */}
      <div className="auth-status">
        {done == null ? (
          <span className="auth-waiting">
            <Loader2 size={14} strokeWidth={1.5} className="spin" aria-hidden="true" />
            {device ? "等待浏览器确认…（可随时取消）" : "授权进行中，等待浏览器确认…（可随时取消）"}
          </span>
        ) : done ? (
          <span className="auth-done">
            <ShieldCheck size={14} strokeWidth={1.5} aria-hidden="true" /> 已授权 ✓
          </span>
        ) : (
          <span className="auth-failed">
            <X size={14} strokeWidth={1.5} aria-hidden="true" /> 授权未完成，请重试或改用其它方式
          </span>
        )}
      </div>

      {/* 实时输出（脱敏后） */}
      {events.length > 0 && (
        <div className="auth-log">
          {events
            .filter((e) => e.kind === "line" || e.kind === "waiting")
            .map((e, i) => (
              <div key={i} className={`auth-log-line ${e.kind}`}>
                {e.message}
              </div>
            ))}
        </div>
      )}
    </div>
  );
}
