// HTTP client wrapper for z-image.ai API calls
// Handles auth cookie injection, error handling, and base URL

import { requireAuth } from "./auth.js";
import { BASE_URL } from "./types.js";

interface FetchOptions {
  method?: string;
  body?: unknown;
  headers?: Record<string, string>;
  rawBody?: BodyInit; // For FormData uploads
}

export class ZImageClient {
  private baseUrl: string;

  constructor(baseUrl: string = BASE_URL) {
    this.baseUrl = baseUrl;
  }

  private getCookieHeader(): string {
    const token = requireAuth();
    return `__Secure-better-auth.session_token=${token}`;
  }

  async fetch<T = unknown>(path: string, options: FetchOptions = {}): Promise<T> {
    const url = `${this.baseUrl}${path}`;
    const headers: Record<string, string> = {
      Cookie: this.getCookieHeader(),
      ...options.headers,
    };

    let fetchInit: RequestInit;

    if (options.rawBody) {
      // FormData — don't set Content-Type (browser/node sets boundary)
      fetchInit = {
        method: options.method || "POST",
        headers,
        body: options.rawBody,
      };
    } else if (options.body) {
      headers["Content-Type"] = "application/json";
      fetchInit = {
        method: options.method || "POST",
        headers,
        body: JSON.stringify(options.body),
      };
    } else {
      fetchInit = {
        method: options.method || "GET",
        headers,
      };
    }

    const response = await fetch(url, fetchInit);

    if (!response.ok) {
      const text = await response.text().catch(() => "");
      throw new Error(`API error ${response.status}: ${text.slice(0, 500)}`);
    }

    return response.json() as Promise<T>;
  }

  async get<T = unknown>(path: string): Promise<T> {
    return this.fetch<T>(path, { method: "GET" });
  }

  async post<T = unknown>(path: string, body: unknown): Promise<T> {
    return this.fetch<T>(path, { method: "POST", body });
  }

  async postForm<T = unknown>(path: string, formData: FormData): Promise<T> {
    return this.fetch<T>(path, { method: "POST", rawBody: formData });
  }
}

// Singleton client instance
let _client: ZImageClient | null = null;

export function getClient(): ZImageClient {
  if (!_client) {
    _client = new ZImageClient();
  }
  return _client;
}
