const WP_URL = process.env.NEXT_PUBLIC_WORDPRESS_URL?.replace(/\/$/, "");
const STORE_API = `${WP_URL}/wp-json/wc/store/v1`;

let _noncePromise: Promise<string> | null = null;

export async function fetchStoreNonce(): Promise<string> {
  const res = await fetch(`${WP_URL}/wp-json/sigma/v1/store-nonce`);
  if (!res.ok) throw new Error("Failed to fetch nonce");
  const body = stripScript(await res.text());
  return JSON.parse(body).nonce;
}

export function getStoreNonce(): Promise<string> {
  if (!_noncePromise) {
    _noncePromise = fetchStoreNonce().catch((e) => {
      _noncePromise = null;
      throw e;
    });
  }
  return _noncePromise;
}

function stripScript(body: string): string {
  let clean = body.replace(/<script[\s\S]*?<\/script>/g, "");
  // Strip Google JSON vulnerability prefix prepended by some servers
  clean = clean.replace(/^\)\]\}'\n?/, "");
  // If multiple JSON values are concatenated, keep only the last object
  const objRe = /\{(.|\n)*\}/g;
  const matches = [...clean.matchAll(objRe)];
  if (matches.length > 0) return matches[matches.length - 1][0];
  return clean;
}

export type StoreApiHeaders = Record<string, string>;

export async function storeApiHeaders(): Promise<StoreApiHeaders> {
  const nonce = await getStoreNonce();
  const headers: StoreApiHeaders = {
    "Content-Type": "application/json",
    Nonce: nonce,
  };
  const cartToken = localStorage.getItem("sigma-cart-token");
  if (cartToken) {
    headers["Cart-Token"] = cartToken;
  }
  return headers;
}

function saveCartToken(res: Response): void {
  const token = res.headers.get("Cart-Token");
  if (token) {
    localStorage.setItem("sigma-cart-token", token);
  }
}

export interface CartItem {
  key: string;
  id: number;
  name: string;
  quantity: number;
  quantity_limits: {
    minimum: number;
    maximum: number;
    multiple_of: number;
    editable: boolean;
  };
  prices: {
    price: string;
    regular_price: string;
    sale_price: string;
    currency_code: string;
    currency_symbol: string;
    currency_minor_unit: number;
  };
  totals: {
    line_subtotal: string;
    line_total: string;
  };
  images: Array<{ src: string; alt: string }>;
}

export interface CartTotals {
  total_items: string;
  total_discount: string;
  total_price: string;
  total_tax: string;
  currency_code: string;
  currency_symbol: string;
  currency_minor_unit: number;
  currency_prefix: string;
  currency_suffix: string;
}

export interface CartCoupon {
  code: string;
  totals: { total_discount: string; total_discount_tax: string };
}

export interface CartResponse {
  items: CartItem[];
  coupons: CartCoupon[];
  totals: CartTotals;
  needs_payment: boolean;
  needs_shipping: boolean;
  items_count: number;
  payment_methods: string[];
  billing_address: Record<string, string>;
  shipping_address: Record<string, string>;
  errors: string[];
}

async function storeApiFetch<T>(
  method: string,
  path: string,
  body?: unknown,
): Promise<T> {
  const headers = await storeApiHeaders();
  const init: RequestInit = { method, headers };
  if (body !== undefined) {
    init.body = JSON.stringify(body);
  }
  const res = await fetch(`${STORE_API}${path}`, init);
  saveCartToken(res);
  const text = stripScript(await res.text());
  if (!res.ok) {
    let msg: string;
    try {
      const err = JSON.parse(text);
      msg = err.message || err.code || res.statusText;
    } catch {
      msg = text || res.statusText;
    }
    throw new Error(msg);
  }
  return JSON.parse(text);
}

export async function addItem(
  id: number,
  quantity = 1,
  variation?: Record<string, string>,
): Promise<CartResponse> {
  return storeApiFetch<CartResponse>("POST", "/cart/add-item", {
    id,
    quantity,
    ...(variation ? { variation } : {}),
  });
}

export async function updateQuantity(
  itemKey: string,
  quantity: number,
): Promise<CartResponse> {
  return storeApiFetch<CartResponse>("POST", "/cart/update-item", {
    key: itemKey,
    quantity,
  });
}

export async function removeItem(itemKey: string): Promise<CartResponse> {
  return storeApiFetch<CartResponse>("POST", "/cart/remove-item", {
    key: itemKey,
  });
}

export async function getCart(): Promise<CartResponse> {
  return storeApiFetch<CartResponse>("GET", "/cart");
}

export async function applyCoupon(code: string): Promise<CartResponse> {
  return storeApiFetch<CartResponse>("POST", "/cart/apply-coupon", { code });
}

export async function removeCoupon(code: string): Promise<CartResponse> {
  return storeApiFetch<CartResponse>("POST", "/cart/remove-coupon", { code });
}

export interface CheckoutResponse {
  order_id: number;
  status: string;
  order_key: string;
  customer_note: string;
  payment_result?: {
    payment_status: string;
    redirect_url?: string;
    transaction_id?: string;
    message?: string;
  };
}

export async function checkout(data: {
  billing_address: Record<string, string>;
  shipping_address?: Record<string, string>;
  payment_method?: string;
  payment_data?: Array<{ key: string; value: string }>;
  customer_note?: string;
  extensions?: Record<string, Record<string, string>>;
}): Promise<CheckoutResponse> {
  console.log("=== CHECKOUT PAYLOAD ===", JSON.stringify(data, null, 2));
  return storeApiFetch<CheckoutResponse>("POST", "/checkout", data);
}

export function clearCartSession(): void {
  localStorage.removeItem("sigma-cart-token");
  _noncePromise = null;
}

export async function fetchAnetPublicConfig(): Promise<{
  apiLoginId: string;
  enabled: boolean;
  environment: string;
  formType: string;
  testMode: boolean;
  usesSandbox: boolean;
}> {
  const res = await fetch(`${WP_URL}/wp-json/sigma/v1/anet-public-config`);
  if (!res.ok) throw new Error("Failed to fetch Authorize.net config");
  const text = stripScript(await res.text());
  return JSON.parse(text);
}
