import * as cheerio from "cheerio";
import { Property } from "../types/property";
import { BaseScraper } from "./baseScraper";

export class TrovatScraper extends BaseScraper {
  constructor() { super("https://casas.trovit.es", "Trovit"); }

  /**
   * Extrae el adId del parámetro de URL de seguimiento de Trovit/Thribee.
   * Ej: "https://clk.thribee.com/?...&adId=trovit-ES-XXXXXXX&..."  → "trovit-ES-XXXXXXX"
   */
  private extractAdId(href: string): string | null {
    try {
      const params = new URL(href).searchParams;
      return params.get("adId");
    } catch {
      return null;
    }
  }

  /** Genera un ID único apartir de la URL canonical del portal externo */
  private urlToId(href: string): string {
    try { return new URL(href).pathname.replace(/\/+$/, "").split("/").pop() || href.slice(-20); }
    catch { return href.slice(-20); }
  }

  /** Normalizador sin tildes para comparar textos */
  private norm(s: string): string {
    return s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
  }

  async scrape(): Promise<Property[]> {
    const zones = await this.getActiveZones();
    const properties: Property[] = [];
    const seenIds = new Set<string>();

    for (const zone of zones) {
      // Intentar dos formatos de URL: el path nuevo y el antiguo con query-string
      const urlsToTry = [
        `${this.baseUrl}/casas/${encodeURIComponent(this.norm(zone.name))}/`,
        `${this.baseUrl}/houses?what=${encodeURIComponent(zone.name)}&country=es&type=1`,
      ];

      let html: string | null = null;
      for (const url of urlsToTry) {
        html = await this.fetchHtml(url);
        if (html && html.length > 2000) break; // respuesta válida
      }
      if (!html) { console.log(`[Trovit] Sin respuesta para ${zone.name}`); continue; }

      const $ = cheerio.load(html);

      // Selectores ordenados de más a menos específico
      const itemSel = [
        "article[class*='Snippet']",
        "article[class*='snippet']",
        ".t-snippet",
        "article",
        ".article--homes",
        ".listing-item",
        ".result-item",
        "[class*='card'][class*='home']",
        "[class*='card'][class*='result']",
      ].join(", ");

      let found = 0;
      $(itemSel).each((_i, el) => {
        const fullText = $(el).text();

        // ---- Buscar URL: prioridad tracking Trovit, fallback enlace directo al portal
        const thribeeHref = $(el).find("a[href*='thribee.com'], a[href*='trovit']").first().attr("href") || "";
        const fallbackHref = $(el).find("a[href*='/casas/'], a[href*='/vivienda/'], a[href*='/inmueble/'], a[href*='/propiedad/']").first().attr("href")
          || $(el).find("a[href*='idealista'], a[href*='fotocasa'], a[href*='habitaclia'], a[href*='pisos.com']").first().attr("href")
          || $(el).find("a[href]").first().attr("href")
          || "";

        let itemId: string;
        let canonicalUrl: string;

        if (thribeeHref) {
          const adId = this.extractAdId(thribeeHref);
          if (!adId) return;
          itemId = adId;
          canonicalUrl = `${this.baseUrl}/detail/${adId}`;
        } else if (fallbackHref) {
          itemId = this.urlToId(fallbackHref);
          canonicalUrl = fallbackHref.startsWith("http") ? fallbackHref : `${this.baseUrl}${fallbackHref}`;
        } else {
          return; // sin URL utilizable
        }

        if (seenIds.has(itemId)) return;

        // Precio — requerido
        const priceRaw = $(el).find("[class*='price'], .price, [class*='Price']").first().text() || fullText;
        const price = this.parsePrice(priceRaw);
        if (price <= 0) return;

        // Título
        const titleEl = $(el).find("h2, h3, .title, [class*='title'], [class*='Title']").first().text().trim();
        const linkText = $(el).find("a").first().text().trim().split("\n")[0];
        const title = this.sanitizeText(titleEl || linkText || `Propiedad en ${zone.name}`);

        // Ubicación
        const locationText = $(el).find(".location, .address, [class*='location'], [class*='Location']").first().text().trim();
        const location = this.sanitizeText(locationText || zone.name);

        seenIds.add(itemId);
        found++;
        properties.push({
          title: title.slice(0, 200),
          price,
          location,
          municipality: this.detectMunicipality(fullText + " " + title + " " + location, zones, zone.name),
          property_type: this.normalizeType(title),
          url: canonicalUrl,
          source: this.sourceName,
        });
      });

      console.log(`[Trovit] ${zone.name} → ${found} propiedades`);
    }
    return this.validateResults(properties);
  }
}
