export interface CatalogFrameConfig {
  restNamespace: string;
  restNonce?: string;
  customGptUrl: string;
  connectorsUrl: string;
  productsUrl?: string;
  supportUrl: string;
  donationUrl: string;
  wooAvailable: boolean;
  i18n?: {
    closeWarning?: string;
  };
}

export interface PluginStatus {
  aiClientAvailable: boolean;
  imageGenerationAvailable: boolean;
  canConfigureProviders: boolean;
  wooAvailable: boolean;
}

export interface GeneratedResult {
  sku: string;
  attachment: {
    id: number;
    url: string;
    filename: string;
  };
  mapping: {
    mapped: boolean;
    productId?: number;
    message: string;
  };
}

export interface GenerationJob {
  jobId: string;
  status: "queued" | "running" | "completed" | "failed";
  createdAt: number;
  updatedAt: number;
  result: GeneratedResult | null;
  error: string;
}

export interface GenerateRequest {
  sku: string;
  productName: string;
  prompt: string;
  referenceImage?: string;
  brandLogo?: string;
  autoMap: boolean;
  options: {
    size: string;
  };
}

export interface WordPressMediaAttachment {
  id?: number;
  url?: string;
  alt?: string;
  filename?: string;
  title?: string;
  type?: string;
  mime?: string;
}

interface WordPressMediaFrame {
  on(event: "open" | "select", callback: () => void): WordPressMediaFrame;
  open(): void;
  state(): {
    get(key: "selection"): {
      first(): { toJSON(): WordPressMediaAttachment } | undefined;
    };
  };
  content?: {
    mode(mode: "upload"): void;
  };
}

declare global {
  interface Window {
    CatalogFrameStudio?: CatalogFrameConfig;
    wp?: {
      apiFetch?: <T>(options: {
        path: string;
        method?: string;
        data?: unknown;
        headers?: Record<string, string>;
      }) => Promise<T>;
      media?: (options: {
        title: string;
        button: { text: string };
        library: { type: "image" };
        multiple: false;
      }) => WordPressMediaFrame;
    };
  }
}

export const config: CatalogFrameConfig = window.CatalogFrameStudio ?? {
  restNamespace: "catalogframe/v1",
  customGptUrl:
    "https://chatgpt.com/g/g-6a4e11087a5481918e7371fc6e23c7a5-woocommerce-product-csv-builder",
  connectorsUrl: "options-connectors.php",
  productsUrl: "edit.php?post_type=product",
  supportUrl: "https://taistudio.co/catalogframe",
  donationUrl: "https://www.paypal.com/ncp/payment/RBBNGNS348UXQ",
  wooAvailable: false,
};

export function getErrorMessage(error: unknown, fallback: string) {
  if (typeof error === "string" && error.trim()) return error;
  if (error && typeof error === "object" && "message" in error) {
    const message = (error as { message?: unknown }).message;
    if (typeof message === "string" && message.trim()) {
      const code = "code" in error ? (error as { code?: unknown }).code : undefined;
      const data = "data" in error ? (error as { data?: unknown }).data : undefined;
      const details: string[] = [];

      if (typeof code === "string" && code.trim()) details.push(`code: ${code}`);
      if (data && typeof data === "object" && "status" in data) {
        const status = (data as { status?: unknown }).status;
        if (typeof status === "number" || typeof status === "string") {
          details.push(`status: ${status}`);
        }
      }

      return details.length ? `${message} (${details.join(", ")})` : message;
    }
  }
  if (error instanceof Error && error.message) return error.message;
  if (error && typeof error === "object") {
    try {
      const serialized = JSON.stringify(error);
      if (serialized && serialized !== "{}") return serialized;
    } catch {
      return fallback;
    }
  }
  return fallback;
}

async function apiFetch<T>(path: string, options: { method?: string; data?: unknown } = {}) {
  if (!window.wp?.apiFetch) {
    throw new Error("WordPress REST API is not available on this page.");
  }

  try {
    return await window.wp.apiFetch<T>({
      path: `/${config.restNamespace}${path}`,
      headers: config.restNonce ? { "X-WP-Nonce": config.restNonce } : undefined,
      ...options,
    });
  } catch (error) {
    if (error instanceof Response) {
      let body: unknown = null;
      try {
        body = await error.clone().json();
      } catch {
        try {
          body = await error.text();
        } catch {
          body = null;
        }
      }

      throw new Error(
        getErrorMessage(
          body,
          `WordPress REST request failed (${error.status} ${error.statusText || "error"}).`,
        ),
      );
    }

    throw new Error(getErrorMessage(error, `WordPress REST request failed for ${path}.`));
  }
}

export function getStatus() {
  return apiFetch<PluginStatus>("/status", { method: "GET" });
}

export function generateImage(request: GenerateRequest) {
  return apiFetch<GenerationJob>("/generate", {
    method: "POST",
    data: request,
  });
}

export function getGenerationJob(jobId: string) {
  return apiFetch<GenerationJob>(`/generate/${encodeURIComponent(jobId)}`, { method: "GET" });
}
