import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
import { ContainerRegistrationKeys } from "@medusajs/framework/utils";

interface MerchantProduct {
  id: string;
  title: string;
  description: string;
  link: string;
  image_link: string;
  price: string;
  availability: "in stock" | "out of stock";
  brand: string;
  condition: string;
  shipping_weight?: string;
}

function escapeCSVField(field: string): string {
  if (!field) return "";
  if (field.includes(",") || field.includes('"') || field.includes("\n")) {
    return `"${field.replace(/"/g, '""')}"`;
  }
  return field;
}

function toCSVRow(product: MerchantProduct): string {
  return [
    escapeCSVField(product.id),
    escapeCSVField(product.title),
    escapeCSVField(product.description),
    escapeCSVField(product.link),
    escapeCSVField(product.image_link),
    escapeCSVField(product.price),
    escapeCSVField(product.availability),
    escapeCSVField(product.brand),
    escapeCSVField(product.condition),
    escapeCSVField(product.shipping_weight || ""),
  ].join(",");
}

async function getAllMedusaProducts(container: any): Promise<any[]> {
  try {
    const query = container.resolve(ContainerRegistrationKeys.QUERY);

    const { data } = await query.graph({
      entity: "product",
      fields: [
        "id",
        "title",
        "handle",
        "description",
        "images.url",
        "variants.id",
      ],
      filters: {
        status: "published",
      },
      pagination: { take: 1000, skip: 0 },
    });

    console.log("[google-merchant-feed] Fetched", data?.length || 0, "products");
    return data || [];
  } catch (error) {
    console.error("[google-merchant-feed] Error fetching products:", error);
    return [];
  }
}

async function getSanityProductPrices(handles: string[]): Promise<Map<string, number>> {
  const prices = new Map<string, number>();

  if (!handles || handles.length === 0) {
    return prices;
  }

  try {
    // Fetch all Sanity products in batch to get prices
    const query = `*[_type == "product" && slug.current in $handles]{
      "handle": slug.current,
      priceCents
    }`;

    const projectId = process.env.SANITY_PROJECT_ID;
    const dataset = process.env.SANITY_DATASET || "production";
    const apiVersion = "v2023-08-01"; // Fixed version

    console.log("[google-merchant-feed] Sanity config:", { projectId, dataset, apiVersion });
    console.log("[google-merchant-feed] Fetching prices for handles:", handles.slice(0, 3), "...");

    if (!projectId) {
      console.warn("[google-merchant-feed] SANITY_PROJECT_ID not set, skipping Sanity prices");
      return prices;
    }

    const url = new URL(`https://${projectId}.api.sanity.io/${apiVersion}/data/query/${dataset}`);
    url.searchParams.set("query", query);
    url.searchParams.set("$handles", JSON.stringify(handles));

    console.log("[google-merchant-feed] Sanity URL:", url.toString().split("?")[0]);

    const response = await fetch(url.toString());
    console.log("[google-merchant-feed] Sanity response status:", response.status);

    if (!response.ok) {
      const errorText = await response.text();
      console.warn(`[google-merchant-feed] Sanity fetch failed (${response.status}):`, errorText);
      return prices;
    }

    const result = (await response.json()) as { result?: Array<{ handle: string; priceCents: number }> };
    console.log("[google-merchant-feed] Sanity result:", result.result?.length || 0, "products");

    if (result.result && Array.isArray(result.result)) {
      for (const product of result.result) {
        if (product.handle && product.priceCents) {
          prices.set(product.handle, product.priceCents);
        }
      }
    }

    console.log("[google-merchant-feed] Fetched prices for", prices.size, "products from Sanity");
  } catch (error) {
    console.error("[google-merchant-feed] Error fetching Sanity prices:", error);
  }

  return prices;
}

function convertToMerchantProduct(
  medusaProduct: any,
  siteUrl: string,
  sanityPrices: Map<string, number>
): MerchantProduct | null {
  try {
    const handle = medusaProduct.handle || "";
    if (!handle) return null;

    // Get price from Sanity if available
    let price = sanityPrices.get(handle) || 0;
    if (price > 0) {
      console.log(`[google-merchant-feed] Found price for ${handle}: ${price} centimes (from Sanity)`);
    }

    // Format price: convert centimes to EUR
    const priceEUR = price > 0 ? `${(price / 100).toFixed(2)} EUR` : "";

    const description = (medusaProduct.description || "")
      .replace(/\n/g, " ")
      .trim()
      .substring(0, 5000) || "Produit personnalisé Stylunique";

    const imageUrl =
      Array.isArray(medusaProduct.images) && medusaProduct.images.length > 0
        ? medusaProduct.images[0].url || ""
        : "";

    const availability: "in stock" | "out of stock" =
      medusaProduct.variants && medusaProduct.variants.length > 0 ? "in stock" : "out of stock";

    return {
      id: medusaProduct.id,
      title: medusaProduct.title?.substring(0, 150) || "",
      description,
      link: `${siteUrl}/produits/${handle}`,
      image_link: imageUrl,
      price: priceEUR,
      availability,
      brand: "Stylunique",
      condition: "new",
      shipping_weight: "0.5 kg",
    };
  } catch (error) {
    console.warn(`[google-merchant-feed] Error converting product (${medusaProduct.id}):`, error);
    return null;
  }
}

export async function GET(req: MedusaRequest, res: MedusaResponse) {
  try {
    const siteUrl = process.env.STOREFRONT_URL || "https://stylunique.fr";

    const products = await getAllMedusaProducts(req.scope);

    // Get handles to fetch prices from Sanity
    const handles = products.map((p: any) => p.handle).filter(Boolean);
    const sanityPrices = await getSanityProductPrices(handles);

    const merchantProducts: MerchantProduct[] = [];
    for (const product of products) {
      const converted = convertToMerchantProduct(product, siteUrl, sanityPrices);
      if (converted) {
        merchantProducts.push(converted);
      }
    }

    if (merchantProducts.length === 0) {
      const csv = "id,title,description,link,image_link,price,availability,brand,condition,shipping_weight";
      return res
        .header("Content-Type", "text/csv; charset=utf-8")
        .header("Content-Disposition", 'attachment; filename="stylunique-products.csv"')
        .header("Cache-Control", "public, max-age=300, s-maxage=3600")
        .status(200)
        .send(csv);
    }

    const csvRows = [
      "id,title,description,link,image_link,price,availability,brand,condition,shipping_weight",
      ...merchantProducts.map(toCSVRow),
    ];
    const csv = csvRows.join("\n");

    return res
      .header("Content-Type", "text/csv; charset=utf-8")
      .header("Content-Disposition", 'attachment; filename="stylunique-products.csv"')
      .header("Cache-Control", "public, max-age=300, s-maxage=3600")
      .status(200)
      .send(csv);
  } catch (error) {
    console.error("[google-merchant-feed] Error generating feed:", error);
    return res.status(500).json({ error: "Failed to generate merchant feed" });
  }
}
