import * as cheerio from "cheerio";
import { Property } from "../types/property";
import { PlaywrightBaseScraper } from "./playwrightBaseScraper";

/**
 * Scraper para Tecnocasa España (franquicia inmobiliaria)
 * La página es una SPA Vue.js; Playwright ejecuta el JS y espera a que se rendericen las tarjetas.
 * URL: https://www.tecnocasa.es/venta/piso/comunidad-valenciana/valencia/{slug}.html
 */
export class TecnocasaScraper extends PlaywrightBaseScraper {
    // Esperar a .app-container (Vue app ready) o a cualquier tarjeta de propiedad
    protected waitForSelector = '.app-container [class*="estate"], .app-container [class*="card"], .app-container article';
    protected pageTimeoutMs = 45000;

    constructor() { super("https://www.tecnocasa.es", "Tecnocasa"); }

    async scrape(): Promise<Property[]> {
        const zones = await this.getActiveZones();
        const slugs = zones.length > 0 ? zones.map(z => z.slug) : ["lliria"];

        const properties: Property[] = [];
        const seenUrls = new Set<string>();

        for (const slug of slugs) {
            const operationPath = this._operationType === "rent" ? "alquiler" : "venta";
            const url = `${this.baseUrl}/${operationPath}/piso/comunidad-valenciana/valencia/${slug}.html`;
            const html = await this.fetchHtmlPlaywright(url, this.waitForSelector);
            if (!html) continue;
            const $ = cheerio.load(html);

            // Buscar tarjetas de propiedad con selectores genéricos (Vue renderiza clases dinámicas)
            const cardSel = [
                '[class*="estate-card"]',
                '[class*="property-card"]',
                '[class*="search-card"]',
                '.result-card',
                'article[class*="card"]',
            ].join(', ');

            $(cardSel).each((_i, el) => {
                try {
                    const title = this.sanitizeText(
                        $(el).find('h2, h3, [class*="title"], [class*="heading"]').first().text() ||
                        "Propiedad Tecnocasa"
                    );
                    const priceRaw = this.sanitizeText(
                        $(el).find('[class*="price"], [class*="precio"], [class*="cost"]').first().text()
                    );
                    const price = this.parsePrice(priceRaw);
                    const href =
                        $(el).find('a[href*="/inmueble"], a[href*="/venta"], a[href*="/alquiler"]').first().attr('href') ||
                        $(el).find('a[href]').first().attr('href') || '';
                    const absUrl = href.startsWith('http') ? href : `${this.baseUrl}${href}`;
                    const location = this.sanitizeText(
                        $(el).find('[class*="location"], [class*="address"], [class*="city"]').first().text() || slug
                    );

                    let rooms = 0, size_m2 = 0;
                    const infoText = $(el).text();
                    const rMatch = infoText.match(/(\d+)\s*(?:hab|dorm)/i);
                    if (rMatch) rooms = parseInt(rMatch[1]);
                    const sMatch = infoText.match(/(\d+)\s*m[²2]/i);
                    if (sMatch) size_m2 = parseInt(sMatch[1]);

                    const image_url = $(el).find('img').first().attr('src') || '';

                    if (price > 0 && href && !seenUrls.has(absUrl)) {
                        seenUrls.add(absUrl);
                        properties.push({
                            title, price, location,
                            municipality: this.detectMunicipality(location + ' ' + slug, zones),
                            property_type: this.normalizeType(title),
                            operation_type: this._operationType,
                            rooms, size_m2, url: absUrl,
                            source: this.sourceName, image_url,
                        });
                    }
                } catch { /* skip */ }
            });
        }
        return this.validateResults(properties);
    }
}
