/**
 * API Client for Settings REST endpoints.
 *
 * Provides typed functions for communicating with the WordPress REST API.
 */

import type { AIProvider, FontCacheEntry } from "@/stores/settingsStore";

/**
 * Get the REST API base URL
 */
const getApiUrl = (): string => {
  return window.oppbAdmin?.apiUrl ?? "/wp-json/opus-price-builder/v1";
};

/**
 * Get the REST API nonce for authentication
 */
const getNonce = (): string => {
  return window.oppbAdmin?.nonce ?? "";
};

/**
 * Settings data as returned by the API
 */
export interface SettingsData {
  google_fonts_local: boolean;
  google_fonts_cdn: boolean;
  google_fonts_disabled: boolean;
  google_fonts_cache: Record<string, FontCacheEntry>;
  ai_provider: AIProvider;
  ai_api_key: string;
  ai_model: string;
  has_api_key: boolean;
  default_scenario: string;
}

/**
 * Settings update payload
 */
export interface SettingsUpdatePayload {
  google_fonts_local?: boolean;
  google_fonts_cdn?: boolean;
  google_fonts_disabled?: boolean;
  ai_provider?: AIProvider;
  ai_api_key?: string;
  clear_ai_api_key?: boolean;
  ai_model?: string;
  default_scenario?: string;
}

/**
 * Font update response
 */
export interface FontUpdateResponse {
  downloaded: Record<string, FontCacheEntry>;
  skipped: Record<string, string[]>;
  errors: Record<string, string>;
  cache: Record<string, FontCacheEntry>;
  google_fonts_local: boolean;
}

/**
 * Font variant for downloading specific weights/styles
 */
export interface FontVariantRequest {
  weights: number[];
  styles: ("normal" | "italic")[];
}

/**
 * Fonts request payload - can be simple array of names or detailed with variants
 */
export type FontsRequestPayload = string[] | Record<string, FontVariantRequest>;

/**
 * API Error type
 */
export interface ApiError {
  code: string;
  message: string;
  data?: {
    status: number;
    content?: string;
  };
}

/**
 * Make an API request with authentication
 */
async function apiRequest<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
  const url = `${getApiUrl()}${endpoint}`;

  const response = await fetch(url, {
    ...options,
    headers: {
      "Content-Type": "application/json",
      "X-WP-Nonce": getNonce(),
      ...options.headers,
    },
  });

  const data = await response.json();

  if (!response.ok) {
    const error: ApiError = {
      code: data.code || "api_error",
      message: data.message || "An error occurred",
      data: data.data,
    };
    throw error;
  }

  return data as T;
}

/**
 * Fetch settings
 */
export async function getSettings(): Promise<SettingsData> {
  return apiRequest<SettingsData>("/settings");
}

/**
 * Update settings
 */
export async function updateSettings(data: SettingsUpdatePayload): Promise<SettingsData> {
  return apiRequest<SettingsData>("/settings", {
    method: "PUT",
    body: JSON.stringify(data),
  });
}

/**
 * Update/download local Google fonts
 * @param options.fonts - Can be simple array of font names OR detailed object with weights/styles
 */
export async function updateFonts(options: {
  fonts: FontsRequestPayload;
  googleFontsLocal?: boolean;
}): Promise<FontUpdateResponse> {
  return apiRequest<FontUpdateResponse>("/settings/update-fonts", {
    method: "POST",
    body: JSON.stringify({
      fonts: options.fonts,
      google_fonts_local: options.googleFontsLocal,
    }),
  });
}
