import { env } from "@/lib/env";
import { logError } from "@/lib/logger";
import { safeFetch } from "@/lib/safeFetch";

export interface UpdotSession {
  admin_session: string;
  admin_session_id: string;
  admin_scopes?: string;
}

export class UpdotAuthManager {
  private static instance: UpdotAuthManager;
  private baseUrl: string;
  private currentSession: UpdotSession | null = null;
  private email: string;
  private password: string;
  // In-flight login, used to coalesce concurrent callers onto a single signin.
  private loginPromise: Promise<UpdotSession | null> | null = null;

  private constructor() {
    // this.baseUrl = env.GetString("UPDOT_ADMIN_CORE_BASE_URL");
    this.baseUrl = env.GetString("UPDOT_CORE_BASE_URL");
    this.email = env.GetString("UPDOT_ADMIN_CORE_EMAIL");
    this.password = env.GetString("UPDOT_ADMIN_CORE_PASSWORD");

    if (!this.email || !this.password) {
      console.error(
        "[UpdotAuth] Missing UPDOT_ADMIN_CORE_EMAIL or UPDOT_ADMIN_CORE_PASSWORD in ENV",
      );
    }
  }

  public static getInstance(): UpdotAuthManager {
    if (!UpdotAuthManager.instance) {
      UpdotAuthManager.instance = new UpdotAuthManager();
    }
    return UpdotAuthManager.instance;
  }

  public getSession(): UpdotSession | null {
    return this.currentSession;
  }

  public invalidate() {
    this.currentSession = null;
  }

  /**
   * Get existing session or login using ENV credentials
   */
  public async getOrLogin(): Promise<UpdotSession | null> {
    if (this.currentSession) return this.currentSession;

    if (!this.email || !this.password) return null;

    // Coalesce concurrent logins: if a signin is already in flight, await that
    // one instead of starting a second. Updot rotates the admin session on each
    // signin, so two racing logins would invalidate each other and one caller
    // would get back a null session ("Unable to obtain ... session.").
    if (this.loginPromise) return this.loginPromise;

    this.loginPromise = this.login().finally(() => {
      this.loginPromise = null;
    });
    return this.loginPromise;
  }

  /**
   * Perform login using stored ENV credentials
   */
  private async login(): Promise<UpdotSession | null> {
    const url = `${this.baseUrl}/v1/admin/console-user/signin`;

    try {
      const response = await safeFetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          email: this.email,
          password: this.password,
          browser: "chrome",
          deviceType: "unknown",
          fcmToken: "unknown",
          ipAddress: "unknown",
          location: "unknown",
          os: "unknown",
        }),
      });

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(
          `Updot Signin Failed (${response.status}): ${errorText}`,
        );
      }

      // ⚠️ Node 18+ required for getSetCookie()
      const setCookieHeaders =
        typeof response.headers.getSetCookie === "function"
          ? response.headers.getSetCookie()
          : response.headers.get("set-cookie")
            ? [response.headers.get("set-cookie") as string]
            : [];

      let admin_session = "";
      let admin_session_id = "";
      let admin_scopes = "";

      for (const cookie of setCookieHeaders || []) {
        if (cookie.includes("admin_session=")) {
          admin_session = cookie.split("admin_session=")[1].split(";")[0];
        } else if (cookie.includes("__sstkn=")) {
          admin_session = cookie.split("__sstkn=")[1].split(";")[0];
        } else if (cookie.includes("admin_session_id=")) {
          admin_session_id = cookie.split("admin_session_id=")[1].split(";")[0];
        }
        else if (cookie.includes("admin_scopes=")) {
          admin_scopes = cookie.split("admin_scopes=")[1].split(";")[0];
        }
        
         if (cookie.includes("__ssid=")) {
          admin_session_id = cookie.split("__ssid=")[1].split(";")[0];
        }
      }

      if (admin_session && admin_session_id) {
        this.currentSession = { admin_session, admin_session_id, admin_scopes };
        return this.currentSession;
      }

      console.error(
        "[UpdotAuth] Required session cookies not found in response",
      );
      return null;
    } catch (err) {
      logError(`[UpdotAuth] Login Error: ${err}`);
      return null;
    }
  }
}
