import * as cheerio from "cheerio";
import type { FetchContext, NormalizedQuery, Offer, OfferAttribute, StoreAdapter } from "../core/types.js";
import { inStockFromText, lazyImageUrl, validPrice } from "./util.js";

// EUAutodalas.lv — server-rendered results at /meklesana-rezervesdalas?keyword=<q>
// (same autoteile-net platform family as rd24; media on euautoteile.de). Was open at the
// original probe, moved behind a Cloudflare managed challenge by M2 → onDemand (walled)
// store, fetched by navigating the resident headful browser (BrowserHub.fetchPageHtml).
// Live-verified 2026-07-12: warm browser on the residential IP passes non-interactively
// (200, "148 rezultāti" for W71252); noVNC solve is the cold-session fallback.
//
// Price extraction: the markup carries decorative `0,00 €` elements (spec §M1 warning) —
// we read the clean decimal from `.product_listing_price_banner_wrapper[data-price]`
// instead of any price text. Fixture: fixtures/euautodalas/W71252.html (2026-07-12).

const HOME = "https://www.euautodalas.lv";

const SEARCH_URL = (q: string) => `${HOME}/meklesana-rezervesdalas?keyword=${encodeURIComponent(q)}`;

const SELECTORS = {
  card: ".cat_items .cat_item",
  titleLink: "a.name",
  art: ".art", // "Produktu skaits: <nr>" then "OEM numurs: …" then "Stav: …"
  brandImg: ".i_firm img", // alt = "MANN-FILTER W 712/52" (brand + part number)
  priceWrapper: ".product_listing_price_banner_wrapper", // data-price="8.43", clean decimal
  availability: ".i_del .i_del-text",
  image: ".image img",
};

export const euautodalas: StoreAdapter = {
  id: "euautodalas",
  displayName: "EUAutodalas.lv",
  storeHomepage: HOME,
  enabled: true,
  fetchMode: "onDemand",
  timeoutMs: 45000, // navigation + possible challenge auto-clear wait + one re-navigation

  async fetchRaw(q: NormalizedQuery, ctx: FetchContext): Promise<string> {
    // Walled: navigate the resident Chrome to the results page (see header comment).
    // The site normalizes the part number itself (W712/52 → W71252), so canonical is fine.
    return ctx.browser.fetchPageHtml(this.id, SEARCH_URL(q.canonical), {
      waitForSelector: SELECTORS.card,
    });
  },

  parse(html: string): Offer[] {
    const $ = cheerio.load(html);
    const offers: Offer[] = [];

    $(SELECTORS.card).each((_, el) => {
      const card = $(el);

      const link = card.find(SELECTORS.titleLink).first();
      const url = link.attr("href") ?? "";
      // Anchor text is two <br>-separated lines: a spec line ("Eļļas filtrs: Augstums:
      // 92mm, Ø: 76mm, ar atgriezējvārstu") and "Rezerves daļu ražotājs: <BRAND> <nr>".
      const linkText = link.text().replace(/\s+/g, " ").trim();
      const [specLine = ""] = linkText.split(/Rezerves daļu ražotājs:/);
      const title = specLine.trim().replace(/,\s*$/, "");

      const artText = card.find(SELECTORS.art).text();
      const partNumber = artText.match(/Produktu skaits:\s*([^\n]+)/)?.[1]?.trim() ?? "";

      // Brand image alt is "<brand> <part number>" — strip the number suffix.
      const brandAlt = (card.find(SELECTORS.brandImg).attr("alt") ?? "").trim();
      const brand =
        partNumber && brandAlt.endsWith(partNumber)
          ? brandAlt.slice(0, -partNumber.length).trim() || null
          : brandAlt || null;

      const priceEur = Number(card.find(SELECTORS.priceWrapper).attr("data-price"));
      if (!partNumber || !validPrice(priceEur)) return;

      // The spec line doubles as the attribute list: "Category: Label: value, Label:
      // value, flag". Flag-style entries go in value with label "" (types.ts convention).
      const attributes: OfferAttribute[] = [];
      const specBody = title.includes(":") ? title.slice(title.indexOf(":") + 1) : "";
      for (const part of specBody.split(",")) {
        const piece = part.trim();
        if (!piece) continue;
        const m = piece.match(/^([^:]+):\s*(.+)$/);
        if (m?.[1] && m[2]) attributes.push({ label: m[1].trim(), value: m[2].trim() });
        else attributes.push({ label: "", value: piece });
      }

      const imageUrl = lazyImageUrl(card.find(SELECTORS.image).first(), "src");

      const availability = card.find(SELECTORS.availability).first().text().trim() || null;

      offers.push({
        store: euautodalas.id,
        brand,
        partNumber,
        title,
        priceEur,
        inStock: inStockFromText(availability),
        availability,
        deliveryNote: null,
        url,
        imageUrl,
        attributes,
      });
    });

    return offers;
  },
};
