import type { Response } from "express";
import { getSecureCookie } from "./secure-cookie.util.js";

/**
 * Auth tokens structure for cookie setting
 */
export interface AuthTokens {
  accessToken: string;
  refreshToken: string;
  expiresAt: string;
  refreshExpiresAt: string;
}

/**
 * Session info returned to client (excludes actual tokens)
 */
export interface SessionInfo {
  expiresAt: string;
  refreshExpiresAt: string;
  tokenType: "Bearer";
}

// Cookie paths - access token needs broader access, refresh token only for refresh endpoint
export const ACCESS_COOKIE_PATH = "/api";
export const REFRESH_COOKIE_PATH = "/api/auth/refresh";
export const TOKEN_TYPE = "Bearer" as const;

/**
 * Calculate cookie max age from ISO timestamp
 */
export function calculateCookieMaxAge(isoTimestamp: string): number {
  const expiresAt = Date.parse(isoTimestamp);
  if (Number.isNaN(expiresAt)) {
    return 0;
  }
  return Math.max(0, expiresAt - Date.now());
}

/**
 * Set authentication cookies on the response.
 *
 * Uses res.setSecureCookie if available (custom helper that sets
 * httpOnly, secure, sameSite), otherwise falls back to standard res.cookie.
 */
export function setAuthCookies(res: Response, tokens: AuthTokens): void {
  const accessMaxAge = calculateCookieMaxAge(tokens.expiresAt);
  const refreshMaxAge = calculateCookieMaxAge(tokens.refreshExpiresAt);

  const setSecureCookie = getSecureCookie(res);
  if (setSecureCookie) {
    // Use the custom setSecureCookie helper if available
    setSecureCookie("access_token", tokens.accessToken, {
      maxAge: accessMaxAge,
      path: ACCESS_COOKIE_PATH,
    });
    setSecureCookie("refresh_token", tokens.refreshToken, {
      maxAge: refreshMaxAge,
      path: REFRESH_COOKIE_PATH,
    });
  } else {
    // Fallback to standard cookie with secure options
    const isProduction = process.env["NODE_ENV"] === "production";

    res.cookie("access_token", tokens.accessToken, {
      httpOnly: true,
      secure: isProduction,
      sameSite: "lax",
      path: ACCESS_COOKIE_PATH,
      maxAge: accessMaxAge,
    });

    res.cookie("refresh_token", tokens.refreshToken, {
      httpOnly: true,
      secure: isProduction,
      sameSite: "lax",
      path: REFRESH_COOKIE_PATH,
      maxAge: refreshMaxAge,
    });
  }
}

/**
 * Clear authentication cookies from the response.
 */
export function clearAuthCookies(res: Response): void {
  const setSecureCookie = getSecureCookie(res);
  if (setSecureCookie) {
    setSecureCookie("access_token", "", { maxAge: 0, path: ACCESS_COOKIE_PATH });
    setSecureCookie("refresh_token", "", { maxAge: 0, path: REFRESH_COOKIE_PATH });
  } else {
    // Fallback to standard cookie clearing
    const isProduction = process.env["NODE_ENV"] === "production";
    const clearOptions = {
      httpOnly: true,
      secure: isProduction,
      sameSite: "lax" as const,
      maxAge: 0,
    };

    res.cookie("access_token", "", { ...clearOptions, path: ACCESS_COOKIE_PATH });
    res.cookie("refresh_token", "", { ...clearOptions, path: REFRESH_COOKIE_PATH });
  }
}

/**
 * Build session info from tokens (for client response, excludes actual tokens)
 */
export function buildSessionInfo(tokens: AuthTokens): SessionInfo {
  return {
    expiresAt: tokens.expiresAt,
    refreshExpiresAt: tokens.refreshExpiresAt,
    tokenType: TOKEN_TYPE,
  };
}
