import React, { useEffect, useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { ReportsAPI } from "@/apis/ReportsAPI";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { Checkbox } from "@/components/ui/checkbox";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Loader2, BarChart3, Search, ChevronLeft, ChevronRight } from "lucide-react";
import {
    BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer,
    PieChart, Pie, Cell, Legend,
} from "recharts";
import KpiCard from "./KpiCard";
import InfoTooltip from "./InfoTooltip";

const DIMENSION_OPTIONS = [
    { value: "none", label: "Total" },
    { value: "channel", label: "Canal" },
    { value: "segment", label: "Segmento" },
    { value: "line", label: "Línea" },
    { value: "sku", label: "SKU" },
    { value: "seller", label: "Ejecutiva" },
    { value: "sale_type", label: "Tipo de venta" },
    { value: "payment_method", label: "Medio de pago" },
];

// Drill-down: canal -> línea -> segmento -> SKU, siguiendo el orden
// "total, canal, segmento, línea, sku" pedido en la minuta.
const DRILL_NEXT = { channel: "line", line: "segment", segment: "sku" };

const FILTER_KEY_BY_DIMENSION = { channel: "channel", line: "line", segment: "segment" };

const COMPARE_OPTIONS = [
    { value: "none", label: "Sin comparación" },
    { value: "previous_period", label: "Período anterior" },
    { value: "previous_year", label: "Año anterior" },
];

const FILTER_LABELS = { channel: "Canal", segment: "Segmento", line: "Línea" };

const COLUMN_TOOLTIPS = {
    units: "Cantidad de unidades vendidas en esta fila. No aplica a Medio de pago (vive a nivel de venta, no de producto).",
    net_amount: "Venta bruta menos IVA estimado (19% de respaldo si el producto no tiene una tasa propia).",
    gross_amount: "Total cobrado al cliente, con IVA incluido, tal como quedó registrado en la venta.",
    estimated_margin: "Venta neta menos el costo actual del producto. Es estimado: no usa el costo histórico al momento de la venta.",
    share_percent: "Participación de esta fila sobre el total de venta bruta del período (todas las filas suman 100%).",
    variation: "Variación porcentual de la venta neta de esta fila contra el mismo valor en el período de comparación elegido.",
};

const COLORS = ["#3b82f6", "#10b981", "#f59e0b", "#ef4444", "#8b5cf6", "#ec4899", "#06b6d4", "#84cc16"];

const PAGE_SIZE = 10;

/**
 * Análisis de Ventas (minuta 2026-08-20, feedback de Felipe Videla): "ventas
 * por línea, en unidades y pesos (netos), y segmento, hombre/mujer, etc;
 * debería ser total, canal, segmento, línea, sku". Reemplaza la idea de un
 * reporte fijo por cada combinación con una sola tabla de dimensión
 * configurable, drill-down y comparación contra el período/año anterior.
 */
export default function SalesCubeReport({ companyId, companies = [], dateRange, onDataReady }) {
    const [selectedCompanies, setSelectedCompanies] = useState(companyId ? [companyId] : []);
    const [dimension, setDimension] = useState("line");
    const [compare, setCompare] = useState("previous_period");
    const [filters, setFilters] = useState({});
    const [drillStack, setDrillStack] = useState([]);
    const [searchTerm, setSearchTerm] = useState("");
    const [currentPage, setCurrentPage] = useState(1);

    useEffect(() => {
        if (companyId && selectedCompanies.length === 0) {
            setSelectedCompanies([companyId]);
        }
    }, [companyId, selectedCompanies.length]);

    const idcompanies = selectedCompanies.length > 0 ? selectedCompanies : (companyId ? [companyId] : []);
    const dimensionLabel = DIMENSION_OPTIONS.find((d) => d.value === dimension)?.label ?? dimension;

    // UX (2026-09-05): "sku" es la única dimensión con cardinalidad alta
    // (puede haber miles de productos distintos), así que paginamos y
    // buscamos en el servidor solo para ella; el resto de dimensiones
    // tiene pocas filas y se sigue filtrando/paginando en el cliente.
    const isServerPaginated = dimension === "sku";

    // Debounce de la búsqueda antes de disparar la consulta al backend,
    // para no llamar a la API por cada tecla escrita.
    const [debouncedSearch, setDebouncedSearch] = useState("");
    useEffect(() => {
        const handle = setTimeout(() => setDebouncedSearch(searchTerm), 350);
        return () => clearTimeout(handle);
    }, [searchTerm]);

    const { data, isLoading, isFetching } = useQuery({
        queryKey: [
            "sales-cube", idcompanies, dateRange, dimension, filters, compare,
            isServerPaginated ? debouncedSearch : null,
            isServerPaginated ? currentPage : null,
        ],
        queryFn: () => ReportsAPI.getSalesCube(
            idcompanies, dateRange.startDate, dateRange.endDate, dimension, filters, compare,
            isServerPaginated ? debouncedSearch : undefined,
            isServerPaginated ? currentPage : undefined,
            isServerPaginated ? PAGE_SIZE : undefined,
        ),
        enabled: idcompanies.length > 0,
    });

    const rows = data?.rows ?? [];
    const topRows = data?.top_rows ?? rows.slice(0, 10);
    const totals = data?.totals ?? null;
    const comparison = data?.comparison ?? null;
    const meta = data?.meta ?? null;

    useEffect(() => {
        if (rows.length > 0) {
            onDataReady({
                title: `Análisis de Ventas — ${dimensionLabel}`,
                fileName: `analisis_ventas_${dimension}`,
                sheetName: "Análisis de Ventas",
                data: rows.map((row) => ({
                    [dimensionLabel]: row.dimension_label,
                    Unidades: row.units,
                    "Venta neta": row.net_amount,
                    "Venta bruta": row.gross_amount,
                    Descuento: row.discount_amount,
                    "Margen estimado": row.estimated_margin,
                    "Participación %": row.share_percent,
                    "Ticket promedio": row.avg_ticket,
                })),
                columns: [dimensionLabel, "Unidades", "Venta neta", "Venta bruta", "Margen estimado", "Participación %"],
                rows: rows.map((row) => [
                    row.dimension_label,
                    row.units ?? "-",
                    row.net_amount,
                    row.gross_amount,
                    row.estimated_margin ?? "-",
                    row.share_percent,
                ]),
            });
        }
    }, [rows, dimension, dimensionLabel, onDataReady]);

    const toggleCompany = (id) => {
        setSelectedCompanies((prev) => (prev.includes(id) ? prev.filter((c) => c !== id) : [...prev, id]));
    };

    const handleDrill = (row) => {
        const nextDimension = DRILL_NEXT[dimension];
        const filterKey = FILTER_KEY_BY_DIMENSION[dimension];
        if (!nextDimension || !filterKey) return;

        setDrillStack((prev) => [...prev, { dimension, filters }]);
        setFilters((prev) => ({ ...prev, [filterKey]: row.dimension_label }));
        setDimension(nextDimension);
    };

    const handleDrillUp = () => {
        const prevState = drillStack[drillStack.length - 1];
        if (!prevState) return;
        setDimension(prevState.dimension);
        setFilters(prevState.filters);
        setDrillStack((prev) => prev.slice(0, -1));
    };

    const handleClearFilters = () => {
        setFilters({});
        setDrillStack([]);
    };

    const chartData = useMemo(
        () => topRows.map((r) => ({ name: r.dimension_label, value: r.net_amount, share: r.share_percent })),
        [topRows],
    );

    // Con paginado server-side, `rows` ya viene filtrada/paginada desde el
    // backend; con paginado client-side, se filtra/pagina aquí sobre el
    // listado completo que trae la API.
    const filteredRows = useMemo(() => {
        if (isServerPaginated) return rows;
        const term = searchTerm.trim().toLowerCase();
        if (!term) return rows;
        return rows.filter((row) => row.dimension_label?.toLowerCase().includes(term));
    }, [rows, searchTerm, isServerPaginated]);

    const noDataAtAll = isServerPaginated ? (totals?.sales_count ?? 0) === 0 : rows.length === 0;
    const totalCount = isServerPaginated ? (meta?.total ?? rows.length) : filteredRows.length;
    const totalPages = Math.max(1, Math.ceil(totalCount / PAGE_SIZE));
    const safeCurrentPage = Math.min(currentPage, totalPages);
    const paginatedRows = useMemo(
        () => (isServerPaginated ? rows : filteredRows.slice((safeCurrentPage - 1) * PAGE_SIZE, safeCurrentPage * PAGE_SIZE)),
        [filteredRows, safeCurrentPage, isServerPaginated, rows],
    );

    useEffect(() => {
        setCurrentPage(1);
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [
        dimension,
        JSON.stringify(filters),
        JSON.stringify(idcompanies),
        dateRange.startDate,
        dateRange.endDate,
        compare,
        isServerPaginated ? debouncedSearch : searchTerm,
    ]);

    if (isLoading && !data) {
        return (
            <div className="p-8 text-center">
                <Loader2 className="w-8 h-8 animate-spin mx-auto text-blue-600" />
            </div>
        );
    }

    return (
        <div className="p-6 space-y-6">
            <Card>
                <CardContent className="pt-6 space-y-4">
                    <div className="grid md:grid-cols-3 gap-4">
                        <div>
                            <Label className="flex items-center gap-1">
                                Dimensión
                                <InfoTooltip text="Define por qué agrupar las ventas de la tabla y los gráficos: canal, segmento, línea, SKU, ejecutiva, tipo de venta o medio de pago. Al elegir 'Canal', 'Línea' o 'Segmento' puedes hacer clic en una fila para bajar de nivel (drill-down)." />
                            </Label>
                            <Select
                                value={dimension}
                                onValueChange={(value) => {
                                    setDimension(value);
                                    setDrillStack([]);
                                }}
                            >
                                <SelectTrigger><SelectValue /></SelectTrigger>
                                <SelectContent>
                                    {DIMENSION_OPTIONS.map((opt) => (
                                        <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                        <div>
                            <Label className="flex items-center gap-1">
                                Comparar contra
                                <InfoTooltip text="Agrega una columna de variación % comparando la venta neta de cada fila contra el período inmediatamente anterior o contra el mismo período del año pasado." />
                            </Label>
                            <Select value={compare} onValueChange={setCompare}>
                                <SelectTrigger><SelectValue /></SelectTrigger>
                                <SelectContent>
                                    {COMPARE_OPTIONS.map((opt) => (
                                        <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                        </div>
                        {(drillStack.length > 0 || Object.keys(filters).length > 0) && (
                            <div className="flex items-end">
                                <Button variant="outline" onClick={drillStack.length > 0 ? handleDrillUp : handleClearFilters}>
                                    {drillStack.length > 0 ? "Volver al nivel anterior" : "Quitar filtros"}
                                </Button>
                            </div>
                        )}
                    </div>

                    {companies.length > 1 && (
                        <div>
                            <Label className="flex items-center gap-1">
                                Empresas a consolidar (canal)
                                <InfoTooltip text="Marca varias empresas para sumar sus ventas en la tabla y los gráficos, tratándolas como un solo total." />
                            </Label>
                            <div className="flex flex-wrap gap-4 mt-2">
                                {companies.map((company) => (
                                    <label key={company.id} className="flex items-center gap-2 text-sm">
                                        <Checkbox
                                            checked={selectedCompanies.includes(company.id)}
                                            onCheckedChange={() => toggleCompany(company.id)}
                                        />
                                        {company.name}
                                    </label>
                                ))}
                            </div>
                        </div>
                    )}

                    {Object.keys(filters).length > 0 && (
                        <div className="flex flex-wrap gap-2">
                            {Object.entries(filters).map(([key, value]) => (
                                <Badge key={key} variant="outline">{FILTER_LABELS[key] ?? key}: {value}</Badge>
                            ))}
                        </div>
                    )}
                </CardContent>
            </Card>

            {totals && (
                <div className="grid md:grid-cols-4 gap-4">
                    <KpiCard
                        label="Venta neta"
                        value={totals.net_amount}
                        format="currency"
                        color="blue"
                        tooltip={COLUMN_TOOLTIPS.net_amount}
                        previousPeriodVariationPercent={comparison?.variation_percent}
                    />
                    <KpiCard label="Unidades vendidas" value={totals.units} format="number" color="emerald" tooltip={COLUMN_TOOLTIPS.units} />
                    <KpiCard label="Ticket promedio" value={totals.avg_ticket} format="currency" color="amber" tooltip="Venta bruta total dividida por la cantidad de ventas del período (o de líneas vendidas, según la dimensión)." />
                    <KpiCard label="Margen estimado" value={totals.estimated_margin} format="currency" color="purple" tooltip={COLUMN_TOOLTIPS.estimated_margin} />
                </div>
            )}

            <div className="grid md:grid-cols-2 gap-4">
                <Card>
                    <CardHeader>
                        <CardTitle className="text-base flex items-center gap-1">
                            Top 10 por venta neta
                            <InfoTooltip text={`Las 10 filas de "${dimensionLabel}" con mayor venta neta del período, ordenadas de mayor a menor.`} />
                        </CardTitle>
                    </CardHeader>
                    <CardContent>
                        {chartData.length === 0 ? (
                            <p className="text-sm text-gray-500 py-8 text-center">Sin datos en este período</p>
                        ) : (
                            <ResponsiveContainer width="100%" height={280}>
                                <BarChart data={chartData} layout="vertical" margin={{ left: 24 }}>
                                    <CartesianGrid strokeDasharray="3 3" />
                                    <XAxis type="number" tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`} fontSize={11} />
                                    <YAxis type="category" dataKey="name" width={120} fontSize={11} />
                                    <Tooltip formatter={(v) => [`$${Number(v).toLocaleString()}`, "Venta neta"]} />
                                    <Bar dataKey="value" fill="#3b82f6" radius={[0, 4, 4, 0]} />
                                </BarChart>
                            </ResponsiveContainer>
                        )}
                    </CardContent>
                </Card>
                <Card>
                    <CardHeader>
                        <CardTitle className="text-base flex items-center gap-1">
                            Participación
                            <InfoTooltip text={`Peso relativo de cada "${dimensionLabel}" (top 10) sobre el total de venta neta mostrado en el gráfico.`} />
                        </CardTitle>
                    </CardHeader>
                    <CardContent>
                        {chartData.length === 0 ? (
                            <p className="text-sm text-gray-500 py-8 text-center">Sin datos en este período</p>
                        ) : (
                            <ResponsiveContainer width="100%" height={280}>
                                <PieChart>
                                    <Pie
                                        data={chartData}
                                        dataKey="value"
                                        nameKey="name"
                                        innerRadius={55}
                                        outerRadius={85}
                                        paddingAngle={3}
                                        label={({ share }) => (share !== null && share !== undefined ? `${share.toFixed(1)}%` : "")}
                                        labelLine={false}
                                        fontSize={11}
                                    >
                                        {chartData.map((_entry, index) => (
                                            <Cell key={index} fill={COLORS[index % COLORS.length]} />
                                        ))}
                                    </Pie>
                                    <Tooltip
                                        formatter={(value, _name, entry) => [
                                            `$${Number(value).toLocaleString()} (${entry?.payload?.share !== undefined && entry?.payload?.share !== null ? entry.payload.share.toFixed(1) : "0.0"}%)`,
                                            "Venta neta",
                                        ]}
                                    />
                                    <Legend formatter={(value) => <span className="text-xs">{value}</span>} />
                                </PieChart>
                            </ResponsiveContainer>
                        )}
                    </CardContent>
                </Card>
            </div>

            <Card>
                <CardHeader>
                    <div className="flex flex-wrap items-center justify-between gap-3">
                        <CardTitle className="flex items-center gap-1">
                            Detalle por {dimensionLabel}
                            <InfoTooltip text="Haz clic en una fila para bajar de nivel (drill-down) cuando la dimensión sea Canal, Línea o Segmento. Usa 'Volver al nivel anterior' para deshacer." />
                        </CardTitle>
                        {!noDataAtAll && (
                            <div className="relative w-full sm:w-64">
                                <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
                                <Input
                                    type="text"
                                    placeholder={`Buscar ${dimensionLabel.toLowerCase()}...`}
                                    value={searchTerm}
                                    onChange={(e) => setSearchTerm(e.target.value)}
                                    className="pl-8"
                                />
                                {isServerPaginated && isFetching && (
                                    <Loader2 className="absolute right-2.5 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 animate-spin" />
                                )}
                            </div>
                        )}
                    </div>
                </CardHeader>
                <CardContent>
                    {noDataAtAll ? (
                        <div className="text-center py-8 text-gray-500">
                            <BarChart3 className="w-12 h-12 mx-auto mb-3 text-gray-400" />
                            <p>No hay ventas en este período</p>
                        </div>
                    ) : filteredRows.length === 0 ? (
                        <div className="text-center py-8 text-gray-500">
                            <Search className="w-12 h-12 mx-auto mb-3 text-gray-400" />
                            <p>No se encontraron resultados para "{searchTerm}"</p>
                        </div>
                    ) : (
                        <div className="overflow-x-auto">
                            <table className="w-full">
                                <thead className="bg-gray-50 border-b">
                                    <tr>
                                        <th className="text-left p-3 text-sm font-semibold">{dimensionLabel}</th>
                                        <th className="text-right p-3 text-sm font-semibold">
                                            <span className="inline-flex items-center gap-1 justify-end w-full">
                                                Unidades
                                                <InfoTooltip text={COLUMN_TOOLTIPS.units} />
                                            </span>
                                        </th>
                                        <th className="text-right p-3 text-sm font-semibold">
                                            <span className="inline-flex items-center gap-1 justify-end w-full">
                                                Venta neta
                                                <InfoTooltip text={COLUMN_TOOLTIPS.net_amount} />
                                            </span>
                                        </th>
                                        <th className="text-right p-3 text-sm font-semibold">
                                            <span className="inline-flex items-center gap-1 justify-end w-full">
                                                Venta bruta
                                                <InfoTooltip text={COLUMN_TOOLTIPS.gross_amount} />
                                            </span>
                                        </th>
                                        <th className="text-right p-3 text-sm font-semibold">
                                            <span className="inline-flex items-center gap-1 justify-end w-full">
                                                Margen est.
                                                <InfoTooltip text={COLUMN_TOOLTIPS.estimated_margin} />
                                            </span>
                                        </th>
                                        <th className="text-right p-3 text-sm font-semibold">
                                            <span className="inline-flex items-center gap-1 justify-end w-full">
                                                Participación
                                                <InfoTooltip text={COLUMN_TOOLTIPS.share_percent} />
                                            </span>
                                        </th>
                                        {comparison && (
                                            <th className="text-right p-3 text-sm font-semibold">
                                                <span className="inline-flex items-center gap-1 justify-end w-full">
                                                    Variación
                                                    <InfoTooltip text={COLUMN_TOOLTIPS.variation} />
                                                </span>
                                            </th>
                                        )}
                                    </tr>
                                </thead>
                                <tbody>
                                    {paginatedRows.map((row) => {
                                        const canDrill = Boolean(DRILL_NEXT[dimension]);
                                        return (
                                            <tr
                                                key={row.dimension_key}
                                                className={`border-b hover:bg-gray-50 ${canDrill ? "cursor-pointer" : ""}`}
                                                onClick={() => canDrill && handleDrill(row)}
                                                title={canDrill ? `Ver ${DIMENSION_OPTIONS.find((d) => d.value === DRILL_NEXT[dimension])?.label} de ${row.dimension_label}` : undefined}
                                            >
                                                <td className="p-3">{row.dimension_label}</td>
                                                <td className="p-3 text-right">{row.units !== null ? Number(row.units).toLocaleString() : "—"}</td>
                                                <td className="p-3 text-right font-semibold">${Math.round(row.net_amount).toLocaleString()}</td>
                                                <td className="p-3 text-right">${Math.round(row.gross_amount).toLocaleString()}</td>
                                                <td className="p-3 text-right">
                                                    {row.estimated_margin !== null ? `$${Math.round(row.estimated_margin).toLocaleString()}` : "—"}
                                                </td>
                                                <td className="p-3 text-right">{row.share_percent.toFixed(1)}%</td>
                                                {comparison && (
                                                    <td
                                                        className={`p-3 text-right ${
                                                            row.variation_percent > 0
                                                                ? "text-emerald-600"
                                                                : row.variation_percent < 0
                                                                    ? "text-red-600"
                                                                    : "text-gray-500"
                                                        }`}
                                                    >
                                                        {row.variation_percent !== null && row.variation_percent !== undefined
                                                            ? `${row.variation_percent > 0 ? "+" : ""}${row.variation_percent.toFixed(1)}%`
                                                            : "—"}
                                                    </td>
                                                )}
                                            </tr>
                                        );
                                    })}
                                </tbody>
                            </table>
                        </div>
                    )}
                    {totalCount > 0 && (
                        <div className="flex flex-wrap items-center justify-between gap-3 pt-4">
                            <p className="text-sm text-gray-500">
                                Mostrando {(safeCurrentPage - 1) * PAGE_SIZE + 1}–
                                {Math.min(safeCurrentPage * PAGE_SIZE, totalCount)} de {totalCount}
                            </p>
                            <div className="flex items-center gap-2">
                                <Button
                                    variant="outline"
                                    size="sm"
                                    onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
                                    disabled={safeCurrentPage <= 1}
                                >
                                    <ChevronLeft className="w-4 h-4" />
                                </Button>
                                <span className="text-sm text-gray-600">
                                    Página {safeCurrentPage} de {totalPages}
                                </span>
                                <Button
                                    variant="outline"
                                    size="sm"
                                    onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
                                    disabled={safeCurrentPage >= totalPages}
                                >
                                    <ChevronRight className="w-4 h-4" />
                                </Button>
                            </div>
                        </div>
                    )}
                </CardContent>
            </Card>
        </div>
    );
}
