import type {
  CatalogProvider,
  Product,
  ProductFilters,
  ProductVariant,
} from "@/lib/headless/types";

type MedusaImage = {
  url?: string | null;
};

type MedusaTag = {
  value?: string | null;
};

type MedusaCategory = {
  name?: string | null;
};

type MedusaCollection = {
  title?: string | null;
};

type MedusaCalculatedPrice = {
  calculated_amount?: number | null;
  original_amount?: number | null;
  currency_code?: string | null;
};

type MedusaVariant = {
  id: string;
  title?: string | null;
  sku?: string | null;
  manage_inventory?: boolean | null;
  allow_backorder?: boolean | null;
  inventory_quantity?: number | null;
  calculated_price?: MedusaCalculatedPrice | null;
  options?: Array<{
    value?: string | null;
    option?: {
      title?: string | null;
    } | null;
  }> | null;
};

type MedusaProduct = {
  id: string;
  handle?: string | null;
  title?: string | null;
  subtitle?: string | null;
  description?: string | null;
  thumbnail?: string | null;
  external_id?: string | null;
  metadata?: Record<string, unknown> | null;
  images?: MedusaImage[] | null;
  tags?: MedusaTag[] | null;
  categories?: MedusaCategory[] | null;
  collection?: MedusaCollection | null;
  variants?: MedusaVariant[] | null;
};

type MedusaProductsResponse = {
  products: MedusaProduct[];
  count?: number;
  limit?: number;
  offset?: number;
};

type LegacyMeta = {
  category: string;
  collection: string;
  brand: string;
  ageRange: string;
  featured: boolean;
  isNew: boolean;
  fallbackImage: string;
  fallbackThumbnail: string;
};

const legacyProductMeta: Record<string, LegacyMeta> = {
  "toy-story-5-rex": {
    "category": "Figuras",
    "collection": "Toy Story",
    "brand": "Disney Pixar",
    "ageRange": "3+",
    "featured": true,
    "isNew": true,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-001-toy-story-5-rex.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-001-toy-story-5-rex.webp"
  },
  "toy-story-5-buzz-lightyear": {
    "category": "Figuras",
    "collection": "Toy Story",
    "brand": "Disney Pixar",
    "ageRange": "3+",
    "featured": true,
    "isNew": true,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-002-toy-story-5-buzz-lightyear.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-002-toy-story-5-buzz-lightyear.webp"
  },
  "toy-story-5-jessie": {
    "category": "Figuras",
    "collection": "Toy Story",
    "brand": "Disney Pixar",
    "ageRange": "3+",
    "featured": true,
    "isNew": true,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-003-toy-story-5-jessie.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-003-toy-story-5-jessie.webp"
  },
  "toy-story-5-woody": {
    "category": "Figuras",
    "collection": "Toy Story",
    "brand": "Disney Pixar",
    "ageRange": "3+",
    "featured": true,
    "isNew": true,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-004-toy-story-5-woody.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-004-toy-story-5-woody.webp"
  },
  "intensamente-furia": {
    "category": "Peluches",
    "collection": "Intensamente",
    "brand": "Disney",
    "ageRange": "3+",
    "featured": true,
    "isNew": true,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-005-intensamente-furia.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-005-intensamente-furia.webp"
  },
  "intensamente-tristeza": {
    "category": "Peluches",
    "collection": "Intensamente",
    "brand": "Disney",
    "ageRange": "3+",
    "featured": true,
    "isNew": true,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-006-intensamente-tristeza.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-006-intensamente-tristeza.webp"
  },
  "minnie-y-mickey-mouse": {
    "category": "Peluches",
    "collection": "Mickey & Minnie",
    "brand": "Disney",
    "ageRange": "3+",
    "featured": true,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-007-minnie-y-mickey-mouse.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-007-minnie-y-mickey-mouse.webp"
  },
  "angel-lilo-y-stitch": {
    "category": "Peluches",
    "collection": "Lilo & Stitch",
    "brand": "Disney",
    "ageRange": "3+",
    "featured": true,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-008-angel-lilo-y-stitch.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-008-angel-lilo-y-stitch.webp"
  },
  "mochilas-disney-coleccion-marvel": {
    "category": "Mochilas",
    "collection": "Marvel",
    "brand": "Marvel",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-009-mochilas-disney-coleccion-marvel.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-009-mochilas-disney-coleccion-marvel.webp"
  },
  "mochila-ligera-y-resistente-al-agua-de-disney-frozen-mochila-escolar-y-de-viaje-con-multiples-compa": {
    "category": "Mochilas",
    "collection": "Frozen",
    "brand": "Disney",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-010-mochila-ligera-y-resistente-al-agua-de-d.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-010-mochila-ligera-y-resistente-al-agua-de-d.webp"
  },
  "mochila-escolar-de-spider-man-de-disney-moda-estudiantil-libro-de-gran-capacidad-mochila-ligera": {
    "category": "Mochilas",
    "collection": "Marvel",
    "brand": "Marvel",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-011-mochila-escolar-de-spider-man-de-disney-.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-011-mochila-escolar-de-spider-man-de-disney-.webp"
  },
  "disney-mochila-de-poliester-ultraligera-y-transpirable-de-gran-tamano-y-multiples-colores-dimension": {
    "category": "Mochilas",
    "collection": "Disney",
    "brand": "Disney",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-012-disney-mochila-de-poliester-ultraligera-.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-012-disney-mochila-de-poliester-ultraligera-.webp"
  },
  "mochila-pequena-bob-esponja": {
    "category": "Mochilas",
    "collection": "Bob Esponja",
    "brand": "Disney",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-013-mochila-pequena-bob-esponja.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-013-mochila-pequena-bob-esponja.webp"
  },
  "mochila-casual-de-gran-capacidad-con-estampado-de-bob-esponja-unisex-bolsa-escolar-de-dibujos-anim": {
    "category": "Mochilas",
    "collection": "Bob Esponja",
    "brand": "Disney",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-014-mochila-casual-de-gran-capacidad-con-est.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-014-mochila-casual-de-gran-capacidad-con-est.webp"
  },
  "mochila-escolar-estilo-britanico-de-disney-con-proteccion-de-la-columna-vertebral-nueva-mochila-de": {
    "category": "Mochilas",
    "collection": "Disney",
    "brand": "Disney",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-015-mochila-escolar-estilo-britanico-de-disn.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-015-mochila-escolar-estilo-britanico-de-disn.webp"
  },
  "disney-mochila-iron-man-de-poliester-ultraligera-y-transpirable-de-gran-tamano-dimensiones-46-cm-x": {
    "category": "Mochilas",
    "collection": "Marvel",
    "brand": "Marvel",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-016-disney-mochila-iron-man-de-poliester-ult.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-016-disney-mochila-iron-man-de-poliester-ult.webp"
  },
  "mochila-de-disney-marvel-capitan-america-de-gran-capacidad-ligera-y-resistente-a-salpicaduras-par": {
    "category": "Mochilas",
    "collection": "Marvel",
    "brand": "Marvel",
    "ageRange": "6+",
    "featured": false,
    "isNew": false,
    "fallbackImage": "https://shop.cruzcloud.net/images/products/ari-017-mochila-de-disney-marvel-capitan-america.webp",
    "fallbackThumbnail": "https://shop.cruzcloud.net/images/thumbnails/ari-017-mochila-de-disney-marvel-capitan-america.webp"
  }
};

function backendUrl(): string {
  const value = process.env.MEDUSA_BACKEND_URL;
  if (!value) {
    throw new Error("MEDUSA_BACKEND_URL no está configurado.");
  }
  return value.replace(/\/$/, "");
}

function regionId(): string {
  const value = process.env.MEDUSA_REGION_ID;
  if (!value) {
    throw new Error("MEDUSA_REGION_ID no está configurado.");
  }
  return value;
}

async function medusaFetch<T>(
  path: string,
  searchParams?: URLSearchParams,
): Promise<T> {
  const url = new URL(`${backendUrl()}${path}`);

  if (searchParams) {
    searchParams.forEach((value, key) => {
      url.searchParams.append(key, value);
    });
  }

  const publishableKey = process.env.MEDUSA_PUBLISHABLE_KEY;

  const response = await fetch(url, {
    headers: publishableKey
      ? { "x-publishable-api-key": publishableKey }
      : undefined,
    next: {
      revalidate: 60,
      tags: ["medusa-products"],
    },
  });

  if (!response.ok) {
    const body = await response.text().catch(() => "");
    throw new Error(
      `Medusa respondió HTTP ${response.status}: ${body.slice(0, 300)}`,
    );
  }

  return (await response.json()) as T;
}

function stringMetadata(
  metadata: Record<string, unknown> | null | undefined,
  key: string,
): string {
  const value = metadata?.[key];
  return typeof value === "string" ? value : "";
}

function booleanMetadata(
  metadata: Record<string, unknown> | null | undefined,
  key: string,
): boolean {
  const value = metadata?.[key];
  return value === true || value === "true";
}

function normalizeCurrency(value?: string | null): string {
  return (value || "COP").toUpperCase();
}

function mapVariant(variant: MedusaVariant): ProductVariant {
  const option = variant.options?.[0];

  const available =
    variant.allow_backorder === true ||
    variant.manage_inventory === false ||
    (variant.inventory_quantity ?? 0) > 0;

  return {
    id: variant.id,
    name: option?.option?.title || "Presentación",
    value: option?.value || variant.title || "Estándar",
    available,
  };
}

function mapProduct(product: MedusaProduct): Product {
  const slug = product.handle || product.id;
  const legacy = legacyProductMeta[slug];

  const variant = product.variants?.[0];
  const calculated = variant?.calculated_price;

  const category =
    product.categories?.[0]?.name ||
    stringMetadata(product.metadata, "category") ||
    legacy?.category ||
    "Variedades";

  const collection =
    product.collection?.title ||
    stringMetadata(product.metadata, "collection") ||
    legacy?.collection ||
    "";

  const brand =
    stringMetadata(product.metadata, "brand") ||
    legacy?.brand ||
    "ARI Shopping";

  const ageRange =
    stringMetadata(product.metadata, "ageRange") ||
    legacy?.ageRange ||
    "Todas";

  const images = [
    ...(product.images || [])
      .map((image) => image.url || "")
      .filter(Boolean),
  ];

  if (images.length === 0 && legacy?.fallbackImage) {
    images.push(legacy.fallbackImage);
  }

  const thumbnail =
    product.thumbnail ||
    images[0] ||
    legacy?.fallbackThumbnail ||
    "/images/brand/logo-ari.png";

  const price =
    typeof calculated?.calculated_amount === "number"
      ? calculated.calculated_amount
      : null;

  const original =
    typeof calculated?.original_amount === "number"
      ? calculated.original_amount
      : null;

  const compareAtPrice =
    original !== null && price !== null && original > price
      ? original
      : null;

  const available =
    !variant ||
    variant.allow_backorder === true ||
    variant.manage_inventory === false ||
    (variant.inventory_quantity ?? 0) > 0;

  const tags = (product.tags || [])
    .map((tag) => tag.value || "")
    .filter(Boolean);

  return {
    id: product.external_id || product.id,
    slug,
    name: product.title || "Producto ARI Shopping",
    shortDescription:
      product.subtitle ||
      product.title ||
      "Producto ARI Shopping",
    description:
      product.description ||
      "Producto disponible para confirmación de inventario con ARI Shopping.",
    category,
    collection,
    brand,
    ageRange,
    price,
    compareAtPrice,
    currency: normalizeCurrency(calculated?.currency_code),
    priceLabel: price === null ? "Consultar disponibilidad" : "",
    available,
    featured:
      booleanMetadata(product.metadata, "featured") ||
      legacy?.featured ||
      false,
    isNew:
      booleanMetadata(product.metadata, "isNew") ||
      legacy?.isNew ||
      false,
    image: images[0] || thumbnail,
    thumbnail,
    images: images.length > 0 ? images : [thumbnail],
    tags,
    variants: (product.variants || []).map(mapVariant),
  };
}

function matchesFilters(
  product: Product,
  filters?: ProductFilters,
): boolean {
  if (!filters) return true;

  const query = filters.query?.trim().toLocaleLowerCase("es");
  if (
    query &&
    ![
      product.name,
      product.shortDescription,
      product.description,
      product.category,
      product.collection,
      product.brand,
      ...product.tags,
    ]
      .join(" ")
      .toLocaleLowerCase("es")
      .includes(query)
  ) {
    return false;
  }

  if (
    filters.category &&
    filters.category !== "Todos" &&
    product.category !== filters.category
  ) {
    return false;
  }

  if (
    filters.collection &&
    product.collection !== filters.collection
  ) {
    return false;
  }

  if (
    filters.brand &&
    filters.brand !== "Todas" &&
    product.brand !== filters.brand
  ) {
    return false;
  }

  if (
    filters.ageRange &&
    filters.ageRange !== "Todas" &&
    product.ageRange !== filters.ageRange
  ) {
    return false;
  }

  if (
    typeof filters.minPrice === "number" &&
    product.price !== null &&
    product.price < filters.minPrice
  ) {
    return false;
  }

  if (
    typeof filters.maxPrice === "number" &&
    product.price !== null &&
    product.price > filters.maxPrice
  ) {
    return false;
  }

  return true;
}

async function fetchProducts(
  filters?: ProductFilters,
  limit = 100,
): Promise<Product[]> {
  const params = new URLSearchParams({
    limit: String(limit),
    // El validador de /store/products no acepta currency_code (400
    // "Unrecognized fields"); el precio calculado solo se resuelve con
    // region_id.
    region_id: regionId(),
    fields:
      "+metadata,+images,+tags,+categories,+collection,+variants.inventory_quantity,+variants.calculated_price,+variants.options",
  });

  if (filters?.query) {
    params.set("q", filters.query);
  }

  const response = await medusaFetch<MedusaProductsResponse>(
    "/store/products",
    params,
  );

  return response.products
    .map(mapProduct)
    .filter((product) => matchesFilters(product, filters));
}

export const medusaCatalogProvider: CatalogProvider = {
  async getProducts(filters) {
    return fetchProducts(filters);
  },

  async getProductBySlug(slug) {
    const params = new URLSearchParams({
      handle: slug,
      limit: "1",
      // El validador de /store/products no acepta currency_code (400
      // "Unrecognized fields"); el precio calculado solo se resuelve con
      // region_id.
      region_id: regionId(),
      fields:
        "+metadata,+images,+tags,+categories,+collection,+variants.inventory_quantity,+variants.calculated_price,+variants.options",
    });

    const response = await medusaFetch<MedusaProductsResponse>(
      "/store/products",
      params,
    );

    const product = response.products[0];
    return product ? mapProduct(product) : null;
  },

  async searchProducts(query, limit = 8) {
    return fetchProducts({ query }, limit);
  },
};
