import { Request, Response } from "express";
import { PortalModel } from "../models/portalModel";
import pool from "../config/db";
import { RowDataPacket } from "mysql2";
import { supportsScraperOperation } from "../scrapers/capabilities";

export const portalController = {
    async getAll(_req: Request, res: Response): Promise<void> {
        try {
            const portals = await PortalModel.findAll();
            res.json(portals);
        } catch (err) {
            res.status(500).json({ error: "Error al obtener portales" });
        }
    },

    async create(req: Request, res: Response): Promise<void> {
        try {
            const { name, slug, scraper_class, active } = req.body;
            if (!name || !scraper_class) {
                res.status(400).json({ error: "name y scraper_class son obligatorios" });
                return;
            }
            const id = await PortalModel.create({ name, slug: slug || "", scraper_class, active: active ?? 1 });
            res.json({ success: true, id });
        } catch (err) {
            res.status(500).json({ error: "Error al crear portal" });
        }
    },

    async toggle(req: Request, res: Response): Promise<void> {
        try {
            const id = parseInt(req.params.id);
            await PortalModel.toggleActive(id);
            const portal = await PortalModel.findById(id);
            res.json({ success: true, active: portal?.active });
        } catch (err) {
            res.status(500).json({ error: "Error al cambiar estado del portal" });
        }
    },

    async remove(req: Request, res: Response): Promise<void> {
        try {
            const id = parseInt(req.params.id);
            const portal = await PortalModel.findById(id);
            if (!portal) { res.status(404).json({ error: "Portal no encontrado" }); return; }
            await PortalModel.deleteById(id);
            res.json({ success: true });
        } catch (err) {
            res.status(500).json({ error: "Error al eliminar portal" });
        }
    },

    async health(_req: Request, res: Response): Promise<void> {
        try {
            const portals = await PortalModel.findAll();
            const [latestRunRows] = await pool.query<RowDataPacket[]>(
                `SELECT r.* FROM scraping_portal_runs r
                  JOIN (
                    SELECT portal, operation_type, MAX(id) AS id
                      FROM scraping_portal_runs
                     GROUP BY portal, operation_type
                  ) latest ON latest.id = r.id`
            );
            const latestRuns = new Map<string, any>(
                latestRunRows.map(run => [`${run.portal}:${run.operation_type}`, run])
            );
            const data: any[] = [];
            for (const p of portals) {
                const [saleRows] = await pool.query<RowDataPacket[]>(
                    `SELECT COUNT(*) AS total,
                            SUM(CASE WHEN COALESCE(last_seen_at, updated_at) >= DATE_SUB(NOW(), INTERVAL 24 HOUR) THEN 1 ELSE 0 END) AS last24h,
                            MAX(COALESCE(last_seen_at, updated_at)) AS last_seen
                     FROM properties
                     WHERE deleted_at IS NULL AND source = ? AND operation_type = 'sale'`,
                    [p.name]
                );
                const [rentRows] = await pool.query<RowDataPacket[]>(
                    `SELECT COUNT(*) AS total,
                            SUM(CASE WHEN COALESCE(last_seen_at, updated_at) >= DATE_SUB(NOW(), INTERVAL 24 HOUR) THEN 1 ELSE 0 END) AS last24h,
                            MAX(COALESCE(last_seen_at, updated_at)) AS last_seen
                     FROM properties
                     WHERE deleted_at IS NULL AND source = ? AND operation_type = 'rent'`,
                    [p.name]
                );
                const sale = saleRows[0] || { total: 0, last24h: 0, last_seen: null };
                const rent = rentRows[0] || { total: 0, last24h: 0, last_seen: null };
                const saleRun = latestRuns.get(`${p.name}:sale`) || null;
                const rentRun = latestRuns.get(`${p.name}:rent`) || null;

                const diagnose = (op: "sale" | "rent", stats: any, run: any): string => {
                    if (!p.active) return "Portal inactivo";
                    if (!supportsScraperOperation(p.scraper_class, op)) return "Operación no soportada";
                    if (run?.status === "error") return `Última ejecución con error: ${run.error || "sin detalle"}`;
                    if (run?.status === "empty") return "Última ejecución sin resultados";
                    if (Number(stats.total) === 0) {
                        if (op === "rent" && Number(sale.total) > 0) {
                            return "Sin alquileres: revisar URL/slugs de alquiler o bloqueo anti-bot";
                        }
                        return "Sin datos históricos";
                    }
                    if (Number(stats.last24h) === 0) return "Sin actualizaciones últimas 24h (revisar scraper/bloqueo)";
                    return "Salud OK";
                };

                data.push({
                    portal_id: p.id,
                    portal: p.name,
                    slug: p.slug,
                    active: p.active,
                    sale: {
                        total: Number(sale.total || 0),
                        last24h: Number(sale.last24h || 0),
                        last_seen: sale.last_seen || null,
                        diagnosis: diagnose("sale", sale, saleRun),
                        last_run: saleRun,
                    },
                    rent: {
                        total: Number(rent.total || 0),
                        last24h: Number(rent.last24h || 0),
                        last_seen: rent.last_seen || null,
                        diagnosis: diagnose("rent", rent, rentRun),
                        last_run: rentRun,
                    },
                });
            }
            res.json({ success: true, data });
        } catch (err) {
            res.status(500).json({ success: false, error: "Error al calcular salud de scrapers" });
        }
    },
};
