import * as vscode from "vscode";
import * as http from "http";
import * as path from "path";
import * as fs from "fs";
import { onTokenReceived, type UserInfo, clearUserInfo } from "./userService";
import { getConfig } from "../config/settings";
import { resetInvitationVerification } from "./apiClient";

/**
 * IC Coder Authentication Provider
 * 集成到 VSCode 账户系统
 */
export class ICCoderAuthenticationProvider
  implements vscode.AuthenticationProvider
{
  private static readonly AUTH_TYPE = "iccoder";
  private static readonly AUTH_NAME = "IC Coder";
  private static loginServer: http.Server | null = null;
  private static currentPort: number | null = null;

  private _onDidChangeSessions =
    new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
  public readonly onDidChangeSessions = this._onDidChangeSessions.event;

  private _sessions: vscode.AuthenticationSession[] = [];

  constructor(private readonly context: vscode.ExtensionContext) {
    // 从存储中恢复会话（同步执行）
    this.loadSessionsSync();
  }

  /**
   * 从存储中加载会话（同步版本）
   */
  private loadSessionsSync(): void {
    const storedSessions = this.context.globalState.get<
      vscode.AuthenticationSession[]
    >("icCoderSessions", []);
    this._sessions = storedSessions;
    console.log("[AuthProvider] 同步加载 sessions, 数量:", this._sessions.length);
    if (this._sessions.length > 0) {
      console.log("[AuthProvider] Session ID:", this._sessions[0].id);
      console.log("[AuthProvider] Account:", this._sessions[0].account.label);
    }
  }

  /**
   * 从存储中加载会话
   */
  private async loadSessions(): Promise<void> {
    const storedSessions = this.context.globalState.get<
      vscode.AuthenticationSession[]
    >("icCoderSessions", []);
    this._sessions = storedSessions;
  }

  /**
   * 保存会话到存储
   */
  private async saveSessions(): Promise<void> {
    console.log("[AuthProvider] 保存 sessions, 数量:", this._sessions.length);
    await this.context.globalState.update("icCoderSessions", this._sessions);
    console.log("[AuthProvider] sessions 已保存到 globalState");
  }

  /**
   * 获取会话列表
   */
  async getSessions(
    scopes?: readonly string[]
  ): Promise<vscode.AuthenticationSession[]> {
    console.log("[AuthProvider] getSessions 被调用, 当前 sessions 数量:", this._sessions.length);
    return [...this._sessions];
  }

  /**
   * 创建会话（登录）
   */
  async createSession(
    scopes: readonly string[]
  ): Promise<vscode.AuthenticationSession> {
    try {
      // 先删除旧的 session（静默删除，不弹窗、不重载窗口）
      if (this._sessions.length > 0) {
        const oldSession = this._sessions[0];
        this._sessions = [];
        await this.saveSessions();
        await clearUserInfo();
        this._onDidChangeSessions.fire({
          added: [],
          removed: [oldSession],
          changed: [],
        });
        console.log("🔄 已清除旧的 session");
      }

      const token = await this.login();

      // 获取到 token 后立即调用用户信息接口
      const userInfo = await onTokenReceived(token);

      // 创建会话
      const session: vscode.AuthenticationSession = {
        id: this.generateSessionId(),
        accessToken: token,
        account: {
          id: userInfo?.userId || "iccoder-user",
          label: userInfo?.nickname || userInfo?.username || "IC Coder 用户",
        },
        scopes: [...scopes],
      };

      this._sessions.push(session);
      await this.saveSessions();

      // 触发会话变化事件
      this._onDidChangeSessions.fire({
        added: [session],
        removed: [],
        changed: [],
      });

      vscode.window.showInformationMessage("登录成功！窗口将自动刷新...");

      // 延迟 1 秒后重新加载窗口，让用户看到成功消息
      setTimeout(() => {
        vscode.commands.executeCommand("workbench.action.reloadWindow");
      }, 1000);

      return session;
    } catch (error) {
      vscode.window.showErrorMessage(
        `登录失败: ${error instanceof Error ? error.message : String(error)}`
      );
      throw error;
    }
  }

  /**
   * 删除会话（登出）
   */
  async removeSession(sessionId: string): Promise<void> {
    const sessionIndex = this._sessions.findIndex((s) => s.id === sessionId);
    if (sessionIndex > -1) {
      const session = this._sessions[sessionIndex];

      // 1. 先调用后端重置邀请码验证状态
      try {
        await resetInvitationVerification();
        console.log("[AuthProvider] 邀请码验证状态已重置");
      } catch (error) {
        console.warn("[AuthProvider] 重置邀请码验证状态失败，但继续退出流程:", error);
        // 即使失败也继续退出流程
      }

      // 2. 清除本地 session
      this._sessions.splice(sessionIndex, 1);
      await this.saveSessions();

      // 3. 清除用户信息缓存
      await clearUserInfo();

      // 4. 触发会话变化事件
      this._onDidChangeSessions.fire({
        added: [],
        removed: [session],
        changed: [],
      });

      vscode.window.showInformationMessage("已退出登录！窗口将自动刷新...");

      // 延迟 1 秒后重新加载窗口，让用户看到成功消息
      setTimeout(() => {
        vscode.commands.executeCommand("workbench.action.reloadWindow");
      }, 1000);
    }
  }

  /**
   * Clear local authentication state without window reload.
   * Used by re-login flow when session is expired.
   */
  async clearSessionsForRelogin(): Promise<void> {
    if (this._sessions.length === 0) {
      await clearUserInfo();
      return;
    }

    const removed = [...this._sessions];
    this._sessions = [];
    await this.saveSessions();
    await clearUserInfo();

    this._onDidChangeSessions.fire({
      added: [],
      removed,
      changed: [],
    });
  }

  /**
   * 生成会话 ID
   */
  private generateSessionId(): string {
    return `iccoder-${Date.now()}-${Math.random().toString(36).substring(7)}`;
  }

  /**
   * 登录逻辑（打开浏览器并等待回调）
   */
  private async login(): Promise<string> {
    // 如果已有服务器在运行，先关闭
    if (ICCoderAuthenticationProvider.loginServer) {
      ICCoderAuthenticationProvider.loginServer.close();
      ICCoderAuthenticationProvider.loginServer = null;
    }

    // 创建本地服务器监听回调
    const { server, port } = await this.createCallbackServer();
    ICCoderAuthenticationProvider.loginServer = server;
    ICCoderAuthenticationProvider.currentPort = port;

    // 构建登录 URL
    const callbackUrl = `http://localhost:${port}/callback`;
    const config = getConfig();
    const loginUrl = `${config.loginUrl}?redirect_uri=${encodeURIComponent(callbackUrl)}`;

    console.log("🔐 登录服务器已启动，监听端口:", port);
    console.log("🌐 登录 URL:", loginUrl);

    // 打开浏览器登录
    await vscode.env.openExternal(vscode.Uri.parse(loginUrl));

    vscode.window.showInformationMessage(
      "请在浏览器中完成登录，登录成功后将自动返回..."
    );

    // 等待 token（通过 Promise）
    return new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        if (ICCoderAuthenticationProvider.loginServer) {
          ICCoderAuthenticationProvider.loginServer.close();
          ICCoderAuthenticationProvider.loginServer = null;
          reject(new Error("登录超时"));
        }
      }, 5 * 60 * 1000);

      // 将 resolve 和 reject 保存到服务器上下文
      (server as any)._loginResolve = resolve;
      (server as any)._loginReject = reject;
      (server as any)._loginTimeout = timeout;
    });
  }

  /**
   * 创建本地回调服务器
   */
  private createCallbackServer(): Promise<{
    server: http.Server;
    port: number;
  }> {
    return new Promise((resolve, reject) => {
      // 读取 icon.png 并转换为 Base64
      const iconPath = path.join(
        this.context.extensionPath,
        "media",
        "icon.png"
      );
      let iconBase64 = "";
      try {
        const iconBuffer = fs.readFileSync(iconPath);
        iconBase64 = `data:image/png;base64,${iconBuffer.toString("base64")}`;
      } catch (error) {
        console.warn("无法读取 icon.png:", error);
      }

      const server = http.createServer(async (req, res) => {
        try {
          console.log("📥 收到回调请求:", req.url);

          const url = new URL(
            req.url!,
            `http://localhost:${ICCoderAuthenticationProvider.currentPort}`
          );
          console.log("📍 路径:", url.pathname);
          console.log("📋 所有参数:", Object.fromEntries(url.searchParams));

          if (url.pathname === "/callback") {
            const token = url.searchParams.get("token");
            console.log("🔑 Token:", token ? "已获取" : "未找到");

            if (token) {
              // 返回成功页面
              res.writeHead(200, {
                "Content-Type": "text/html; charset=utf-8",
              });
              res.end(this.getSuccessPage(iconBase64));

              // 关闭服务器
              server.close();
              ICCoderAuthenticationProvider.loginServer = null;

              // 清除超时
              if ((server as any)._loginTimeout) {
                clearTimeout((server as any)._loginTimeout);
              }

              // 返回 token
              if ((server as any)._loginResolve) {
                (server as any)._loginResolve(token);
              }
            } else {
              res.writeHead(400, {
                "Content-Type": "text/html; charset=utf-8",
              });
              res.end(`
                <!DOCTYPE html>
                <html>
                <head><meta charset="utf-8"><title>登录失败</title></head>
                <body><h1>❌ 登录失败</h1><p>未获取到有效的 Token</p></body>
                </html>
              `);

              if ((server as any)._loginReject) {
                (server as any)._loginReject(new Error("未获取到有效的 Token"));
              }
            }
          } else {
            res.writeHead(404);
            res.end("Not Found");
          }
        } catch (error) {
          res.writeHead(500);
          res.end("Internal Server Error");
          if ((server as any)._loginReject) {
            (server as any)._loginReject(error);
          }
        }
      });

      // 监听端口（使用 0 表示自动分配可用端口）
      server.listen(0, () => {
        const address = server.address();
        const port =
          typeof address === "object" && address ? address.port : 3000;
        resolve({ server, port });
      });

      // 处理错误
      server.on("error", (error: NodeJS.ErrnoException) => {
        reject(error);
      });
    });
  }

  /**
   * 获取登录成功页面 HTML
   */
  private getSuccessPage(iconBase64: string): string {
    return `
      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>登录成功 - IC Coder</title>
        <style>
          * { margin: 0; padding: 0; box-sizing: border-box; }
          body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background: linear-gradient(135deg, #dbeafe 0%, #93c5fd 100%);
            overflow: hidden;
            position: relative;
          }
          .bg-circle {
            position: absolute;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.1);
            animation: float 20s infinite ease-in-out;
          }
          .bg-circle:nth-child(1) { width: 300px; height: 300px; top: -150px; left: -150px; }
          .bg-circle:nth-child(2) { width: 200px; height: 200px; bottom: -100px; right: -100px; animation-delay: 5s; }
          .bg-circle:nth-child(3) { width: 150px; height: 150px; top: 50%; right: 10%; animation-delay: 10s; }
          @keyframes float {
            0%, 100% { transform: translate(0, 0) scale(1); }
            33% { transform: translate(30px, -30px) scale(1.1); }
            66% { transform: translate(-20px, 20px) scale(0.9); }
          }
          .container {
            position: relative;
            z-index: 10;
            text-align: center;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            padding: 60px 50px;
            border-radius: 24px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
            max-width: 500px;
            animation: slideUp 0.6s ease-out;
          }
          @keyframes slideUp {
            from { opacity: 0; transform: translateY(30px); }
            to { opacity: 1; transform: translateY(0); }
          }
          .success-icon {
            width: 80px;
            height: 80px;
            margin: 0 auto 30px;
            background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 100%);
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            animation: scaleIn 0.5s ease-out 0.2s both;
          }
          @keyframes scaleIn {
            from { transform: scale(0); opacity: 0; }
            to { transform: scale(1); opacity: 1; }
          }
          .checkmark {
            width: 40px;
            height: 40px;
            border: 4px solid white;
            border-radius: 50%;
            position: relative;
          }
          .checkmark::after {
            content: '';
            position: absolute;
            left: 8px;
            top: 3px;
            width: 12px;
            height: 20px;
            border: solid white;
            border-width: 0 4px 4px 0;
            transform: rotate(45deg);
          }
          h1 {
            color: #2d3748;
            font-size: 32px;
            font-weight: 700;
            margin-bottom: 16px;
            animation: fadeIn 0.6s ease-out 0.3s both;
          }
          p {
            color: #718096;
            font-size: 18px;
            line-height: 1.6;
            margin-bottom: 30px;
            animation: fadeIn 0.6s ease-out 0.4s both;
          }
          @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
          }
          .brand {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 10px;
            margin-top: 20px;
            padding-top: 20px;
            border-top: 1px solid #e2e8f0;
            animation: fadeIn 0.6s ease-out 0.5s both;
          }
          .brand-logo {
            width: 32px;
            height: 32px;
            border-radius: 6px;
            overflow: hidden;
          }
          .brand-logo img {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
          .brand-text {
            color: #4a5568;
            font-size: 16px;
            font-weight: 600;
          }
        </style>
      </head>
      <body>
        <div class="bg-circle"></div>
        <div class="bg-circle"></div>
        <div class="bg-circle"></div>
        <div class="container">
          <div class="success-icon">
            <div class="checkmark"></div>
          </div>
          <h1>登录成功！</h1>
          <p>您已成功登录 IC Coder<br>现在可以返回 VSCode 继续使用</p>
          <div class="brand">
            <div class="brand-logo">
              <img src="${iconBase64}" alt="IC Coder" />
            </div>
            <span class="brand-text">IC Coder</span>
          </div>
        </div>
      </body>
      </html>
    `;
  }
}
