export interface SubmitNewProductsArgs {
  products: Array<Record<string, unknown>>;
  environment: "dev" | "prod";
  useTestDataSource: boolean;
  employeeId?: number;
}

export interface SubmitNewProductsResponse {
  success: boolean;
  message?: string;
  data?: unknown;
  error?: unknown;
}

export interface CreateProductCategoryArgs {
  masterCatId: string | number;
  name: string;
  environment?: "dev" | "prod";
  image?: string;
  nameForCustoms?: string;
  taxCodeId?: string | number;
}

export interface CreateProductCategoryResponse {
  success: boolean;
  message?: string;
  data?: unknown;
  error?: unknown;
  category?: unknown;
}

// Always use relative URLs - proxied by Vite in dev and Caddy in production
// Frontend calls /apiv2/* -> Caddy transforms to /api/* -> proxies to www.acherryontop.com
const DEV_ENDPOINT = "/apiv2-test/product/setup_new";
const DEV_CREATE_CATEGORY_ENDPOINT = "/apiv2-test/prod_cat/new";
const PROD_ENDPOINT = "/apiv2/product/setup_new";
const PROD_CREATE_CATEGORY_ENDPOINT = "/apiv2/prod_cat/new";

const isHtmlResponse = (payload: string) => {
  const trimmed = payload.trim();
  return trimmed.startsWith("<!DOCTYPE html") || trimmed.startsWith("<html");
};

export async function submitNewProducts({
  products,
  environment,
  useTestDataSource,
}: SubmitNewProductsArgs): Promise<SubmitNewProductsResponse> {
  const baseUrl = environment === "dev" ? DEV_ENDPOINT : PROD_ENDPOINT;
  const targetUrl = useTestDataSource ? `${baseUrl}?use_test_data_source=1` : baseUrl;

  const payload = new URLSearchParams();
  const serializedProducts = JSON.stringify(products);
  payload.append("products", serializedProducts);

  let response: Response;

  const fetchOptions: RequestInit = {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
    },
    body: payload,
  };

  // Authentication strategy depends on endpoint
  if (environment === "dev") {
    // Test endpoint: Use auth token in request body
    const authToken = import.meta.env.VITE_APIV2_AUTH_TOKEN;
    if (authToken) {
      payload.append("auth", authToken);
      fetchOptions.body = payload;
    }
  } else {
    // Prod endpoint: Use cookies (proxied in both dev and production)
    fetchOptions.credentials = "include";
  }

  try {
    response = await fetch(targetUrl, fetchOptions);
  } catch (networkError) {
    throw new Error(networkError instanceof Error ? networkError.message : "Network request failed");
  }

  const rawBody = await response.text();

  if (isHtmlResponse(rawBody)) {
    throw new Error("Backend authentication required. Please ensure you are logged into the backend system.");
  }

  let parsed: unknown;
  try {
    parsed = JSON.parse(rawBody);
  } catch {
    const message = `Unexpected response from backend (${response.status}).`;
    throw new Error(message);
  }

  if (!parsed || typeof parsed !== "object") {
    throw new Error("Empty response from backend");
  }

  const parsedResponse = parsed as SubmitNewProductsResponse & Record<string, unknown>;
  const extraFields = parsedResponse as Record<string, unknown>;
  const normalizedResponse: SubmitNewProductsResponse = {
    success: Boolean(parsedResponse.success),
    message: typeof parsedResponse.message === "string" ? parsedResponse.message : undefined,
    data: parsedResponse.data,
    error: parsedResponse.error ?? extraFields.errors ?? extraFields.error_msg,
  };

  if (!response.ok || !normalizedResponse.success) {
    return normalizedResponse;
  }

  return normalizedResponse;
}

export async function createProductCategory({
  masterCatId,
  name,
  environment = "prod",
  image,
  nameForCustoms,
  taxCodeId,
}: CreateProductCategoryArgs): Promise<CreateProductCategoryResponse> {
  const targetUrl = environment === "dev" ? DEV_CREATE_CATEGORY_ENDPOINT : PROD_CREATE_CATEGORY_ENDPOINT;

  const payload = new URLSearchParams();
  payload.append("master_cat_id", masterCatId.toString());
  payload.append("name", name);

  if (nameForCustoms) {
    payload.append("name_for_customs", nameForCustoms);
  }

  if (image) {
    payload.append("image", image);
  }

  if (typeof taxCodeId !== "undefined" && taxCodeId !== null) {
    payload.append("tax_code_id", taxCodeId.toString());
  }

  let response: Response;

  const fetchOptions: RequestInit = {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
    },
    body: payload,
  };

  // Authentication strategy depends on endpoint
  if (environment === "dev") {
    // Test endpoint: Use auth token in request body
    const authToken = import.meta.env.VITE_APIV2_AUTH_TOKEN;
    if (authToken) {
      payload.append("auth", authToken);
      fetchOptions.body = payload;
    }
  } else {
    // Prod endpoint: Use cookies (proxied in both dev and production)
    fetchOptions.credentials = "include";
  }

  try {
    response = await fetch(targetUrl, fetchOptions);
  } catch (networkError) {
    throw new Error(networkError instanceof Error ? networkError.message : "Network request failed");
  }

  const rawBody = await response.text();

  if (isHtmlResponse(rawBody)) {
    throw new Error("Backend authentication required. Please ensure you are logged into the backend system.");
  }

  let parsed: unknown;
  try {
    parsed = JSON.parse(rawBody);
  } catch {
    const message = `Unexpected response from backend (${response.status}).`;
    throw new Error(message);
  }

  if (!parsed || typeof parsed !== "object") {
    throw new Error("Empty response from backend");
  }

  const parsedRecord = parsed as Record<string, unknown>;
  const normalizedResponse: CreateProductCategoryResponse = {
    success: Boolean(parsedRecord.success ?? parsedRecord.status ?? parsedRecord.result),
    message: typeof parsedRecord.message === "string" ? parsedRecord.message : undefined,
    data: parsedRecord.data ?? parsedRecord.category ?? parsedRecord.result,
    error: parsedRecord.error ?? parsedRecord.errors ?? parsedRecord.error_msg,
    category: parsedRecord.category,
  };

  if (!response.ok || !normalizedResponse.success) {
    return normalizedResponse;
  }

  return normalizedResponse;
}
