import * as cheerio from "cheerio";
import { Property } from "../types/property";
import { BaseScraper } from "./baseScraper";

/**
 * Scraper para SpainHouses (portal enfocado en compradores extranjeros)
 * URL: https://www.spainhouses.net/en/buy/houses-for-sale-in-lliria.html
 * Paginación: ?page=2
 */
export class SpainHousesScraper extends BaseScraper {
    private readonly MAX_PAGES = 3;
    constructor() { super("https://www.spainhouses.net", "SpainHouses"); }

    async scrape(): Promise<Property[]> {
        const zones = await this.getActiveZones();
        const targets = zones.length > 0
            ? zones.map(z => z.slug)
            : ["lliria"];

        const properties: Property[] = [];
        const seenUrls = new Set<string>();

        for (const slug of targets) {
            const zone = zones.find(z => z.slug === slug);
            const zoneName = zone?.name ?? slug;

            for (let page = 1; page <= this.MAX_PAGES; page++) {
                const baseUrl = `${this.baseUrl}/en/buy/houses-for-sale-in-${slug}.html`;
                const url = page === 1 ? baseUrl : `${baseUrl}?page=${page}`;
                const html = await this.fetchHtml(url);
                if (!html || html.length < 5000) break;
                const $ = cheerio.load(html);

                let found = 0;
                $("article, .property-item, [class*='property'], [class*='listing'], [class*='PropertyCard']").each((_i, el) => {
                    try {
                        const title = this.sanitizeText($(el).find("h2, h3, [class*='title']").first().text() || "Property");
                        const priceRaw = $(el).find("[class*='price'], .price").first().text();
                        const price = this.parsePrice(priceRaw);
                        const href = $(el).find("a").attr("href") || "";
                        const url2 = href.startsWith("http") ? href : `${this.baseUrl}${href}`;
                        const location = this.sanitizeText($(el).find("[class*='location'], .location").first().text());
                        const rooms = parseInt($(el).find("[class*='bedroom'], [class*='room']").first().text()) || 0;
                        const size_m2 = parseInt($(el).find("[class*='size'], [class*='m2']").first().text()) || 0;
                        const image_url = $(el).find("img").attr("src") || "";

                        // Validar que el título o localización menciona alguna zona activa
                        const textToCheck = (title + " " + location).toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
                        const inZone = zones.some(z => {
                            const zn = z.name.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
                            return textToCheck.includes(zn) || textToCheck.includes(z.slug);
                        });
                        if (!inZone && zones.length > 0) return;

                        if (price > 0 && href && !seenUrls.has(url2)) {
                            seenUrls.add(url2);
                            found++;
                            properties.push({
                                title, price, location: location || zoneName,
                                municipality: this.detectMunicipality(title + " " + location, zones, zoneName),
                                property_type: this.normalizeType(title),
                                rooms, size_m2, url: url2, source: this.sourceName, image_url,
                            });
                        }
                    } catch { /* skip */ }
                });

                if (found < 3) break;
            }
        }
        return this.validateResults(properties);
    }
}
