// src/pages/Reportes/ReporteListadoDistribucionPage.tsx
import React, { useState, useCallback, useMemo } from 'react';
import {
  Box, Typography, Paper, CircularProgress, Alert, Button
} from '@mui/material';
import { DataGrid, type GridColDef, GridFooterContainer, GridFooter } from '@mui/x-data-grid'; // No necesitas type Theme aquí
import { esES } from '@mui/x-data-grid/locales';
import reportesService from '../../services/Reportes/reportesService';
import type { ListadoDistribucionDistribuidoresResponseDto } from '../../models/dtos/Reportes/ListadoDistribucionDistribuidoresResponseDto';
import SeleccionaReporteListadoDistribucion from './SeleccionaReporteListadoDistribucion';
import { usePermissions } from '../../hooks/usePermissions';
import * as XLSX from 'xlsx';
import axios from 'axios';

const ReporteListadoDistribucionPage: React.FC = () => {
  const [reportData, setReportData] = useState<ListadoDistribucionDistribuidoresResponseDto | null>(null);
  const [loading, setLoading] = useState(false);
  const [loadingPdf, setLoadingPdf] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [apiErrorParams, setApiErrorParams] = useState<string | null>(null);
  const [showParamSelector, setShowParamSelector] = useState(true);
  const [currentParams, setCurrentParams] = useState<{
    idDistribuidor: number;
    idPublicacion: number;
    fechaDesde: string;
    fechaHasta: string;
    nombrePublicacion?: string;
    nombreDistribuidor?: string;
  } | null>(null);
  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR002");

  // --- ESTADO PARA TOTALES CALCULADOS (PARA EL FOOTER DEL DETALLE) ---
  const [totalesDetalle, setTotalesDetalle] = useState({
    llevados: 0,
    devueltos: 0,
    ventaNeta: 0,
    promedioGeneralVentaNeta: 0,
    porcentajeDevolucionGeneral: 0,
  });

  const [totalesPromedios, setTotalesPromedios] = useState({
    cantDias: 0,
    promLlevados: 0,
    promDevueltos: 0,
    promVentas: 0,
    porcentajeDevolucionGeneral: 0,
  });


  const handleGenerarReporte = useCallback(async (params: {
    idDistribuidor: number;
    idPublicacion: number;
    fechaDesde: string;
    fechaHasta: string;
  }) => {
    if (!puedeVerReporte) {
      setError("No tiene permiso para generar este reporte.");
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    setApiErrorParams(null);
    setReportData(null);
    setTotalesDetalle({ llevados: 0, devueltos: 0, ventaNeta: 0, promedioGeneralVentaNeta: 0, porcentajeDevolucionGeneral: 0 });
    setTotalesPromedios({ cantDias: 0, promLlevados: 0, promDevueltos: 0, promVentas: 0, porcentajeDevolucionGeneral: 0 });


    const pubService = (await import('../../services/Distribucion/publicacionService')).default;
    const distService = (await import('../../services/Distribucion/distribuidorService')).default;
    const [pubData, distData] = await Promise.all([
      pubService.getPublicacionById(params.idPublicacion),
      distService.getDistribuidorById(params.idDistribuidor)
    ]);

    setCurrentParams({
      ...params,
      nombrePublicacion: pubData.nombre,
      nombreDistribuidor: distData.nombre
    });

    try {
      const data = await reportesService.getListadoDistribucionDistribuidores(params);

      let acumuladoVentaNeta = 0;
      let diasConVenta = 0;

      const detalleConCalculos = data.detalleSimple.map((item, index) => {
        const llevados = item.llevados || 0;
        const devueltos = item.devueltos || 0;
        const ventaNeta = llevados - devueltos;
        if (llevados > 0) diasConVenta++; // O si ventaNeta > 0, dependiendo de la definición de "día con actividad"
        acumuladoVentaNeta += ventaNeta;

        return {
          ...item,
          id: `simple-${index}`,
          ventaNeta: ventaNeta,
          promedio: diasConVenta > 0 ? acumuladoVentaNeta / diasConVenta : 0, // Promedio acumulativo hasta esa fila
          porcentajeDevolucion: llevados > 0 ? (devueltos / llevados) * 100 : 0,
        };
      });

      const totalLlevadosDetalle = detalleConCalculos.reduce((sum, item) => sum + (item.llevados || 0), 0);
      const totalDevueltosDetalle = detalleConCalculos.reduce((sum, item) => sum + (item.devueltos || 0), 0);
      const totalVentaNetaDetalle = totalLlevadosDetalle - totalDevueltosDetalle;

      setTotalesDetalle({
        llevados: totalLlevadosDetalle,
        devueltos: totalDevueltosDetalle,
        ventaNeta: totalVentaNetaDetalle,
        promedioGeneralVentaNeta: diasConVenta > 0 ? totalVentaNetaDetalle / diasConVenta : 0,
        porcentajeDevolucionGeneral: totalLlevadosDetalle > 0 ? (totalDevueltosDetalle / totalLlevadosDetalle) * 100 : 0
      });


      const promediosConCalculos = data.promediosPorDia.map((item, index) => ({
        ...item,
        id: `prom-${index}`,
        porcentajeDevolucion: item.promedio_Llevados > 0 ? (item.promedio_Devueltos / item.promedio_Llevados) * 100 : 0,
      }));

      const totalDiasPromedios = promediosConCalculos.reduce((sum, item) => sum + (item.cant || 0), 0);
      const countPromedios = promediosConCalculos.length;

      // LÓGICA DE PROMEDIO DE PROMEDIOS
      if (countPromedios > 0) {
        const sumPromLlevados = promediosConCalculos.reduce((sum, item) => sum + (item.promedio_Llevados || 0), 0);
        const sumPromDevueltos = promediosConCalculos.reduce((sum, item) => sum + (item.promedio_Devueltos || 0), 0);
        const sumPromVentas = promediosConCalculos.reduce((sum, item) => sum + (item.promedio_Ventas || 0), 0);
        const sumPorcDevolucion = promediosConCalculos.reduce((sum, item) => sum + (item.porcentajeDevolucion || 0), 0);

        setTotalesPromedios({
          cantDias: totalDiasPromedios,
          promLlevados: sumPromLlevados / countPromedios,
          promDevueltos: sumPromDevueltos / countPromedios,
          promVentas: sumPromVentas / countPromedios,
          porcentajeDevolucionGeneral: sumPorcDevolucion / countPromedios,
        });
      }

      setReportData({ detalleSimple: detalleConCalculos, promediosPorDia: promediosConCalculos });

      if (detalleConCalculos.length === 0 && promediosConCalculos.length === 0) {
        setError("No se encontraron datos para los parámetros seleccionados.");
      }
      setShowParamSelector(false);
    } catch (err: any) {
      const message = axios.isAxiosError(err) && err.response?.data?.message
        ? err.response.data.message
        : 'Ocurrió un error al generar el reporte.';
      setApiErrorParams(message);
    } finally {
      setLoading(false);
    }
  }, []);

  const handleVolverAParametros = useCallback(() => {
    setShowParamSelector(true);
    setReportData(null);
    setError(null);
    setApiErrorParams(null);
    setCurrentParams(null);
  }, []);

  const handleExportToExcel = useCallback(() => {
    if (!reportData || (!reportData.detalleSimple?.length && !reportData.promediosPorDia?.length)) {
      alert("No hay datos para exportar.");
      return;
    }
    const wb = XLSX.utils.book_new();

    if (reportData.detalleSimple?.length) {
      const simpleToExport = reportData.detalleSimple.map(({ id, ...rest }) => ({ // Excluir saldoAcumulado del excel de detalle
        "Día": rest.dia,
        "Llevados": rest.llevados,
        "Devueltos": rest.devueltos,
        "Venta Neta": (rest.llevados || 0) - (rest.devueltos || 0),
        "Promedio": (rest as any).promedio, // Ya calculado
        "% Devolución": (rest as any).porcentajeDevolucion, // Ya calculado
      }));
      // Fila de totales para detalle
      simpleToExport.push({
        "Día": 0, // Usar 0 para cumplir con el tipo number requerido
        "Llevados": totalesDetalle.llevados,
        "Devueltos": totalesDetalle.devueltos,
        "Venta Neta": totalesDetalle.ventaNeta,
        "Promedio": totalesDetalle.promedioGeneralVentaNeta, // Usar el promedio general calculado
        "% Devolución": totalesDetalle.porcentajeDevolucionGeneral,
      });
      const wsSimple = XLSX.utils.json_to_sheet(simpleToExport);
      XLSX.utils.book_append_sheet(wb, wsSimple, "DetalleDiario");
    }

    if (reportData.promediosPorDia?.length) {
      const promediosToExport = reportData.promediosPorDia.map(({ id, ...rest }) => ({
        "Día Semana": rest.dia,
        "Cant. Días": rest.cant,
        "Prom. Llevados": rest.promedio_Llevados,
        "Prom. Devueltos": rest.promedio_Devueltos,
        "Prom. Ventas": rest.promedio_Ventas,
        "% Devolución": (rest as any).porcentajeDevolucion, // Ya calculado
      }));
      // Fila de totales para promedios
      promediosToExport.push({
        "Día Semana": "General",
        "Cant. Días": totalesPromedios.cantDias,
        "Prom. Llevados": totalesPromedios.promLlevados,
        "Prom. Devueltos": totalesPromedios.promDevueltos,
        "Prom. Ventas": totalesPromedios.promVentas,
        "% Devolución": totalesPromedios.porcentajeDevolucionGeneral,
      });
      const wsPromedios = XLSX.utils.json_to_sheet(promediosToExport);
      XLSX.utils.book_append_sheet(wb, wsPromedios, "PromediosPorDiaSemana");
    }

    let fileName = "ListadoDistribucionDistribuidores";
    if (currentParams) {
      fileName += `_${currentParams.nombrePublicacion?.replace(/\s+/g, '') ?? `Pub${currentParams.idPublicacion}`}`;
      fileName += `_Dist${currentParams.nombreDistribuidor?.replace(/\s+/g, '') ?? currentParams.idDistribuidor}`;
      fileName += `_${currentParams.fechaDesde}_a_${currentParams.fechaHasta}`;
    }
    fileName += ".xlsx";
    XLSX.writeFile(wb, fileName);
  }, [reportData, currentParams, totalesDetalle, totalesPromedios]);

  const handleGenerarYAbrirPdf = useCallback(async () => {
    if (!currentParams) {
      setError("Primero debe generar el reporte en pantalla o seleccionar parámetros.");
      return;
    }
    setLoadingPdf(true);
    setError(null);
    try {
      const blob = await reportesService.getListadoDistribucionDistribuidoresPdf(currentParams);
      if (blob.type === "application/json") {
        const text = await blob.text();
        const msg = JSON.parse(text).message ?? "Error inesperado al generar PDF.";
        setError(msg);
      } else {
        const url = URL.createObjectURL(blob);
        const w = window.open(url, '_blank');
        if (!w) alert("Permite popups para ver el PDF.");
      }
    } catch {
      setError('Ocurrió un error al generar el PDF.');
    } finally {
      setLoadingPdf(false);
    }
  }, [currentParams]);

  const columnsDetalle: GridColDef[] = [
    { field: 'dia', headerName: 'Día', type: 'number', width: 70, align: 'right', headerAlign: 'right', sortable: false }, // Usar width fijo para columnas pequeñas
    { field: 'llevados', headerName: 'Llevados', type: 'number', flex: 1, minWidth: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'devueltos', headerName: 'Devueltos', type: 'number', flex: 1, minWidth: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => value != null ? Number(value).toLocaleString('es-AR') : '0' },
    { field: 'ventaNeta', headerName: 'Venta Neta', type: 'number', flex: 1, minWidth: 110, align: 'right', headerAlign: 'right', valueGetter: (_value, row) => (row.llevados || 0) - (row.devueltos || 0), valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'promedio', headerName: 'Promedio', type: 'number', flex: 1, minWidth: 110, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR', { minimumFractionDigits: 3, maximumFractionDigits: 3 }) },
    { field: 'porcentajeDevolucion', headerName: '% Devolución', type: 'number', flex: 1, minWidth: 110, align: 'right', headerAlign: 'right', valueFormatter: (value) => `${Number(value).toLocaleString('es-AR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}%` },
  ];

  const columnsPromedios: GridColDef[] = [
    { field: 'dia', headerName: 'Día Semana', width: 140, flex: 1.2 }, // Un poco más de espacio para el nombre del día
    { field: 'cant', headerName: 'Cant. Días', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'promedio_Llevados', headerName: 'Prom. Llevados', type: 'number', flex: 1, minWidth: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'promedio_Devueltos', headerName: 'Prom. Devueltos', type: 'number', flex: 1, minWidth: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'promedio_Ventas', headerName: 'Prom. Ventas', type: 'number', flex: 1, minWidth: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'porcentajeDevolucion', headerName: '% Devolución', type: 'number', flex: 1, minWidth: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => `${Number(value).toLocaleString('es-AR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}%` },
  ];

  const rowsDetalle = useMemo(() => reportData?.detalleSimple ?? [], [reportData]);
  const rowsPromedios = useMemo(() => reportData?.promediosPorDia ?? [], [reportData]);

  // --- Custom Footer para Detalle Diario ---
  const CustomFooterDetalle = () => (
    <GridFooterContainer
      sx={{
        // Asegurar que el contenedor pueda usar todo el ancho
        // y que los items internos puedan distribuirse.
        // justifyContent: 'space-between' // Esto podría ayudar
      }}
    >
      {/* Contenedor para los elementos del footer por defecto (paginación, etc.) */}
      <Box sx={{
        // flexGrow: 1, // Originalmente teníamos esto, puede ser muy agresivo
        display: 'flex', // Para alinear los items del paginador por defecto
        alignItems: 'center',
        // Intenta darle un ancho mínimo o un flex-basis para que tenga espacio antes que los totales
        minWidth: '400px', // AJUSTA ESTE VALOR según lo que necesites
        flexShrink: 0, // Evita que se encoja demasiado si los totales son muy anchos
      }}>
        <GridFooter sx={{
          borderTop: 'none',
          // '& .MuiTablePagination-toolbar': { // Para los elementos dentro del paginador
          //   flexWrap: 'wrap', // Permitir que los elementos internos del paginador se envuelvan
          //   justifyContent: 'flex-start',
          // },
          // '& .MuiTablePagination-spacer': { // El espaciador puede ser un problema
          //   display: 'none', // Prueba quitándolo
          // }
        }} />
      </Box>
      {/* Contenedor para tus totales, alineado a la derecha */}
      <Box sx={{
        p: 1,
        display: 'flex',
        alignItems: 'center',
        fontWeight: 'bold',
        marginLeft: 'auto', // Empuja a la derecha
        flexShrink: 1, // Permite que este se encoja si es necesario, pero no demasiado
        overflowX: 'auto', // Si los totales son muchos, que tengan su propio scroll
        whiteSpace: 'nowrap', // Evitar que los textos de totales se partan
      }}>
        {/* Mantén esta estructura, pero quizás necesitas jugar con los minWidth/flex de los Typography */}
        <Typography variant="subtitle2" sx={{ flexBasis: columnsPromedios[0].width || 'auto', minWidth: columnsPromedios[0].width || 'auto', textAlign: 'right', fontWeight: 'bold' }}>Generales:</Typography>
        <Typography variant="subtitle2" sx={{ minWidth: columnsDetalle[1].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold', mr: 1 }}>{totalesDetalle.llevados.toLocaleString('es-AR')}</Typography>
        <Typography variant="subtitle2" sx={{ minWidth: columnsDetalle[2].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold', mr: 1 }}>{totalesDetalle.devueltos.toLocaleString('es-AR')}</Typography>
        <Typography variant="subtitle2" sx={{ minWidth: columnsDetalle[3].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold', mr: 1 }}>{totalesDetalle.ventaNeta.toLocaleString('es-AR')}</Typography>
        <Typography variant="subtitle2" sx={{ minWidth: columnsDetalle[4].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold', mr: 1 }}>{totalesDetalle.promedioGeneralVentaNeta.toLocaleString('es-AR', { minimumFractionDigits: 3, maximumFractionDigits: 3 })}</Typography>
        <Typography variant="subtitle2" sx={{ minWidth: columnsDetalle[5].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold' }}>{totalesDetalle.porcentajeDevolucionGeneral.toLocaleString('es-AR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}%</Typography>
      </Box>
    </GridFooterContainer>
  );

  // --- Custom Footer para Promedios por Día (Ajustado para flex) ---
  const CustomFooterPromedios = () => (
    <GridFooterContainer sx={{ /* justifyContent: 'space-between' */ }}>
      <Box sx={{
        // flexGrow: 1, 
        display: 'flex',
        alignItems: 'center',
        minWidth: '400px', // AJUSTA ESTE VALOR
        flexShrink: 0,
      }}>
        <GridFooter sx={{ borderTop: 'none' }} />
      </Box>
      <Box sx={{
        p: 1,
        display: 'flex',
        alignItems: 'center',
        fontWeight: 'bold',
        marginLeft: 'auto',
        flexShrink: 1,
        overflowX: 'auto',
        whiteSpace: 'nowrap',
      }}>
        <Typography variant="subtitle2" sx={{ flexBasis: columnsPromedios[0].width || 'auto', minWidth: columnsPromedios[0].width || 'auto', textAlign: 'right', fontWeight: 'bold' }}>Generales:</Typography>
        <Typography variant="subtitle2" sx={{ width: columnsPromedios[1].width || 'auto', textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{totalesPromedios.cantDias.toLocaleString('es-AR')}</Typography>
        <Typography variant="subtitle2" sx={{ flex: columnsPromedios[2].flex, minWidth: columnsPromedios[2].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{totalesPromedios.promLlevados.toLocaleString('es-AR', { maximumFractionDigits: 0 })}</Typography>
        <Typography variant="subtitle2" sx={{ flex: columnsPromedios[3].flex, minWidth: columnsPromedios[3].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{totalesPromedios.promDevueltos.toLocaleString('es-AR', { maximumFractionDigits: 0 })}</Typography>
        <Typography variant="subtitle2" sx={{ flex: columnsPromedios[4].flex, minWidth: columnsPromedios[4].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{totalesPromedios.promVentas.toLocaleString('es-AR', { maximumFractionDigits: 0 })}</Typography>
        <Typography variant="subtitle2" sx={{ flex: columnsPromedios[5].flex, minWidth: columnsPromedios[5].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold' }}>{totalesPromedios.porcentajeDevolucionGeneral.toLocaleString('es-AR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}%</Typography>
      </Box>
    </GridFooterContainer>
  );


  if (showParamSelector) {
    if (!loading && !puedeVerReporte) {
      return <Alert severity="error" sx={{ m: 2 }}>No tiene permiso para acceder a este reporte.</Alert>;
    }
    return (
      <Box sx={{ p: 2, display: 'flex', justifyContent: 'center', mt: 2 }}>
        <Paper sx={{ width: '100%', maxWidth: 600 }} elevation={3}>
          <SeleccionaReporteListadoDistribucion
            onGenerarReporte={handleGenerarReporte}
            onCancel={handleVolverAParametros}
            isLoading={loading}
            apiErrorMessage={apiErrorParams}
          />
        </Paper>
      </Box>
    );
  }

  return (
    <Box sx={{ p: 2 }}>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2, flexWrap: 'wrap', gap: 1 }}>
        <Typography variant="h5">Reporte: Listado Distribución ({currentParams?.nombreDistribuidor})</Typography>
        <Box sx={{ display: 'flex', gap: 1 }}>
          <Button onClick={handleGenerarYAbrirPdf} variant="contained" disabled={loadingPdf || !reportData || !!error} size="small">
            {loadingPdf ? <CircularProgress size={20} color="inherit" /> : "Abrir PDF"}
          </Button>
          <Button onClick={handleExportToExcel} variant="outlined" disabled={!reportData || !!error} size="small">
            Exportar a Excel
          </Button>
          <Button onClick={handleVolverAParametros} variant="outlined" color="secondary" size="small">
            Nuevos Parámetros
          </Button>
        </Box>
      </Box>
      <Typography variant="subtitle1" gutterBottom>
        Publicación: {currentParams?.nombrePublicacion} |
        Fechas: {currentParams?.fechaDesde} al {currentParams?.fechaHasta}
      </Typography>


      {loading && <Box sx={{ textAlign: 'center', my: 2 }}><CircularProgress /></Box>}
      {error && !loading && <Alert severity="error" sx={{ my: 2 }}>{error}</Alert>}

      {!loading && !error && reportData && (
        <>
          <Typography variant="h6" gutterBottom sx={{ mt: 2 }}>Detalle Diario</Typography>
          {rowsDetalle.length > 0 ? (
            <Paper sx={{ height: 400, width: '100%', mb: 3 }}> {/* Ajusta altura según necesites */}
              <DataGrid
                rows={rowsDetalle}
                columns={columnsDetalle}
                localeText={esES.components.MuiDataGrid.defaultProps.localeText}
                density="compact"
                slots={{ footer: CustomFooterDetalle }}
              />
            </Paper>
          ) : (<Typography sx={{ fontStyle: 'italic' }}>No hay datos de detalle diario.</Typography>)}

          <Typography variant="h6" gutterBottom sx={{ mt: 2 }}>Promedios por Día de Semana</Typography>
          {rowsPromedios.length > 0 ? (
            <Paper sx={{ height: 400, width: '100%' }}> {/* Ajusta altura según necesites */}
              <DataGrid
                rows={rowsPromedios}
                columns={columnsPromedios}
                localeText={esES.components.MuiDataGrid.defaultProps.localeText}
                density="compact"
                slots={{ footer: CustomFooterPromedios }}
              />
            </Paper>
          ) : (<Typography sx={{ fontStyle: 'italic' }}>No hay datos de promedios por día.</Typography>)}
        </>
      )}
      {!loading && !error && (!reportData || ((!reportData.detalleSimple || reportData.detalleSimple.length === 0) && (!reportData.promediosPorDia || reportData.promediosPorDia.length === 0))) &&
        (<Typography>No se encontraron datos para los criterios seleccionados.</Typography>)}
    </Box>
  );
};

export default ReporteListadoDistribucionPage;