import * as cheerio from "cheerio";
import { Property } from "../types/property";
import { BaseScraper } from "./baseScraper";

/**
 * Scraper para Globaliza (portal inmobiliario con fuerte presencia en Comunidad Valenciana)
 * URL: https://www.globaliza.com/venta/viviendas/{slug}
 * Paginación: ?paginaAnuncios=2
 */
export class GlobalizaScraper extends BaseScraper {
    private readonly MAX_PAGES = 4;
    constructor() { super("https://www.globaliza.com", "Globaliza"); }

    async scrape(): Promise<Property[]> {
        const zones = await this.getActiveZones();
        const operationPath = this._operationType === "rent" ? "alquiler" : "venta";
        const targets = zones.length > 0
            ? zones
                .filter(z => (z as any).globaliza_slug != null)
                .map(z => ({ baseUrl: `${this.baseUrl}/${operationPath}/viviendas/${(z as any).globaliza_slug}`, zone: z }))
            : [{ baseUrl: `${this.baseUrl}/${operationPath}/viviendas/lliria`, zone: { name: "Llíria", slug: "lliria" } as any }];

        const properties: Property[] = [];
        const seenUrls = new Set<string>();

        for (const { baseUrl, zone } of targets) {
            for (let page = 1; page <= this.MAX_PAGES; page++) {
                const url = page === 1 ? baseUrl : `${baseUrl}?paginaAnuncios=${page}`;
                const html = await this.fetchHtml(url);
                if (!html || html.length < 3000) break;
                const $ = cheerio.load(html);

                let found = 0;
                $("h2 a[href*='/inmueble/'], h2 a[href*='/globaliza.com/inmueble/']").each((_i, el) => {
                    const href = $(el).attr("href") || "";
                    const url2 = href.startsWith("http") ? href : `${this.baseUrl}${href}`;
                    if (!url2 || !url2.includes("/inmueble/") || seenUrls.has(url2)) return;

                    const title = this.sanitizeText($(el).text());
                    if (!title || title.length < 3) return;

                    const card = $(el).closest("article, li, .sr-item, .property-item, .listing-item, [class*='inmueble']");
                    const rawBlock = card.length ? card.text() : $(el).parent().parent().parent().text();
                    // Venta suele usar "150.000 €", pero alquiler usa también
                    // "980 €" o "1.200 €". La regex anterior exigía 2-3
                    // dígitos antes del separador y descartaba todos esos casos.
                    const priceMatch = rawBlock.match(
                        /(?:\d{1,3}(?:[.,\s]\d{3})+|\d{2,8})(?:,\d{2})?\s*€/u
                    );
                    const price = priceMatch ? this.parsePrice(priceMatch[0]) : 0;
                    const image_url = card.find("img").attr("src") || card.find("img").attr("data-src") || "";

                    if (price > 0) {
                        // Intentar detectar el municipio real desde el título.
                        // Fallback a zone.name cuando el título no menciona ciudad:
                        // así nunca se descarta un anuncio activo por falta de coincidencia.
                        const detectedMuni = this.detectMunicipality(title, zones, zone.name);
                        seenUrls.add(url2);
                        found++;
                        properties.push({
                            title, price,
                            location: detectedMuni,
                            municipality: detectedMuni,
                            property_type: this.normalizeType(title),
                            operation_type: this._operationType,
                            url: url2, source: this.sourceName, image_url,
                        });
                    }
                });

                if (found < 2) break; // Sin más resultados en esta página
            }
        }
        return this.validateResults(properties);
    }
}

