import { Request, Response } from "express";
import PropertyService from "../services/propertyService";
import { PropertyModel } from "../models/propertyModel";
import { ScoringService } from "../services/scoringService";
import { DeduplicationService } from "../services/deduplicationService";
import ExcelJS from "exceljs";

const scoringService = new ScoringService();
const deduplicationService = new DeduplicationService();

export const AnalyticsController = {
    /** GET /dashboard/analytics — Página principal analytics */
    async page(req: Request, res: Response): Promise<void> {
        try {
            const analytics = await PropertyService.getAnalytics();
            res.render("dashboard/analytics", {
                title: "Analytics",
                analytics,
                user: (req as any).user,
            });
        } catch (error) {
            console.error("Error analytics page:", error);
            res.status(500).render("error", { message: "Error cargando analytics", user: (req as any).user });
        }
    },

    /** GET /api/analytics — Datos JSON para Ajax */
    async data(req: Request, res: Response): Promise<void> {
        try {
            const analytics = await PropertyService.getAnalytics();
            res.json({ success: true, ...analytics });
        } catch (error) {
            res.status(500).json({ success: false, error: (error as Error).message });
        }
    },

    /** POST /api/analytics/score — Re-calcular todos los scores */
    async runScoring(req: Request, res: Response): Promise<void> {
        try {
            const count = await scoringService.scoreAll();
            res.json({ success: true, scored: count });
        } catch (error) {
            res.status(500).json({ success: false, error: (error as Error).message });
        }
    },

    /** POST /api/analytics/dedup — Ejecutar deduplicación */
    async runDeduplicate(req: Request, res: Response): Promise<void> {
        try {
            await deduplicationService.resetDuplicates();
            const result = await deduplicationService.runDeduplication();
            res.json({ success: true, ...result });
        } catch (error) {
            res.status(500).json({ success: false, error: (error as Error).message });
        }
    },

    /** GET /api/properties/export/xlsx — Exportar propiedades a Excel */
    async exportXlsx(req: Request, res: Response): Promise<void> {
        try {
            const properties = await PropertyModel.findAll();
            const workbook = new ExcelJS.Workbook();
            workbook.creator = "Captaja Inmobiliaria";
            workbook.created = new Date();

            const sheet = workbook.addWorksheet("Propiedades", {
                pageSetup: { paperSize: 9, orientation: "landscape" },
            });

            // Cabeceras con estilo
            sheet.columns = [
                { header: "ID", key: "id", width: 8 },
                { header: "Título", key: "title", width: 45 },
                { header: "Portal", key: "source", width: 14 },
                { header: "Tipo", key: "property_type", width: 12 },
                { header: "Municipio", key: "municipality", width: 18 },
                { header: "Ubicación", key: "location", width: 30 },
                { header: "Precio (€)", key: "price", width: 14 },
                { header: "€/m²", key: "price_per_m2", width: 10 },
                { header: "Score", key: "score", width: 8 },
                { header: "Habitaciones", key: "rooms", width: 14 },
                { header: "m²", key: "size_m2", width: 10 },
                { header: "Duplicado", key: "is_duplicate", width: 12 },
                { header: "URL", key: "url", width: 50 },
                { header: "Actualizado", key: "updated_at", width: 18 },
            ];

            // Estilo de cabecera
            const headerRow = sheet.getRow(1);
            headerRow.eachCell(cell => {
                cell.fill = { type: "pattern", pattern: "solid", fgColor: { argb: "FF1F497D" } };
                cell.font = { bold: true, color: { argb: "FFFFFFFF" }, size: 11 };
                cell.alignment = { vertical: "middle", horizontal: "center" };
                cell.border = {
                    bottom: { style: "medium", color: { argb: "FF1F497D" } },
                };
            });
            headerRow.height = 22;

            // Datos
            for (const p of properties) {
                const row = sheet.addRow({
                    id: p.id,
                    title: p.title,
                    source: p.source,
                    property_type: p.property_type,
                    municipality: p.municipality,
                    location: p.location,
                    price: p.price,
                    price_per_m2: (p as any).price_per_m2 || "",
                    score: (p as any).score ? Number((p as any).score).toFixed(1) : "",
                    rooms: p.rooms || "",
                    size_m2: p.size_m2 || "",
                    is_duplicate: (p as any).is_duplicate ? "Sí" : "No",
                    url: p.url,
                    updated_at: (p.last_seen_at || p.updated_at)
                        ? new Date(p.last_seen_at || p.updated_at!).toLocaleDateString("es-ES")
                        : "",
                });

                // Formato de precio
                row.getCell("price").numFmt = '#,##0 "€"';
                row.getCell("price_per_m2").numFmt = '#,##0 "€"';

                // Color score
                const scoreVal = (p as any).score ? Number((p as any).score) : 0;
                const scoreCell = row.getCell("score");
                if (scoreVal >= 7) {
                    scoreCell.fill = { type: "pattern", pattern: "solid", fgColor: { argb: "FF70AD47" } };
                    scoreCell.font = { color: { argb: "FFFFFFFF" } };
                } else if (scoreVal >= 5) {
                    scoreCell.fill = { type: "pattern", pattern: "solid", fgColor: { argb: "FFFFC000" } };
                } else if (scoreVal > 0) {
                    scoreCell.fill = { type: "pattern", pattern: "solid", fgColor: { argb: "FFFF0000" } };
                    scoreCell.font = { color: { argb: "FFFFFFFF" } };
                }

                // URL como hipervínculo
                if (p.url) {
                    row.getCell("url").value = { text: "Ver anuncio", hyperlink: p.url };
                    row.getCell("url").font = { color: { argb: "FF0563C1" }, underline: true };
                }

                // Filas alternas
                if (row.number % 2 === 0) {
                    row.eachCell({ includeEmpty: false }, cell => {
                        if (!cell.fill || (cell.fill as any).fgColor?.argb === "FFFFFFFF") {
                            cell.fill = { type: "pattern", pattern: "solid", fgColor: { argb: "FFF2F2F2" } };
                        }
                    });
                }
            }

            // Auto-filtro
            sheet.autoFilter = {
                from: "A1",
                to: `${String.fromCharCode(64 + sheet.columns.length)}1`,
            };

            // Congelar fila cabecera
            sheet.views = [{ state: "frozen", xSplit: 0, ySplit: 1 }];

            // Enviar
            const filename = `propiedades_lliria_${new Date().toISOString().slice(0, 10)}.xlsx`;
            res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            res.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
            await workbook.xlsx.write(res);
            res.end();
        } catch (error) {
            console.error("Error exportando Excel:", error);
            res.status(500).json({ success: false, error: (error as Error).message });
        }
    },
};
