import React, { useState, useCallback } from 'react';
import {
  Box, Typography, Paper, CircularProgress, Alert, Button
} from '@mui/material';
import { DataGrid, type GridColDef, GridFooterContainer, GridFooter } from '@mui/x-data-grid';
import { esES } from '@mui/x-data-grid/locales'; // Importación para localización
import reportesService from '../../services/Reportes/reportesService';
import type { ListadoDistribucionCanillasResponseDto } from '../../models/dtos/Reportes/ListadoDistribucionCanillasResponseDto';
import type { ListadoDistribucionCanillasSimpleDto } from '../../models/dtos/Reportes/ListadoDistribucionCanillasSimpleDto';
import type { ListadoDistribucionCanillasPromedioDiaDto } from '../../models/dtos/Reportes/ListadoDistribucionCanillasPromedioDiaDto';
// Asegúrate que esta ruta es correcta
import SeleccionaReporteListadoDistribucionCanillas from './SeleccionaReporteListadoDistribucionCanillas';
import * as XLSX from 'xlsx';

// Interfaces extendidas para los datos con campos calculados para el DataGrid
interface DetalleDiarioCanillasExtendido extends ListadoDistribucionCanillasSimpleDto {
  id: string;
  ventaNeta: number;
  promedio: number; // Promedio acumulativo de Venta Neta
  porcentajeDevolucion: number;
}

interface PromedioDiaCanillasExtendido extends ListadoDistribucionCanillasPromedioDiaDto {
  id: string;
  porcentajeDevolucion: number;
}

const ReporteListadoDistribucionCanillasPage: React.FC = () => {
  const [reportData, setReportData] = useState<ListadoDistribucionCanillasResponseDto | null>(null);
  const [detalleDiarioCalculado, setDetalleDiarioCalculado] = useState<DetalleDiarioCanillasExtendido[]>([]);
  const [promediosPorDiaCalculado, setPromediosPorDiaCalculado] = useState<PromedioDiaCanillasExtendido[]>([]);

  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<{
    idPublicacion: number;
    fechaDesde: string;
    fechaHasta: string;
    nombrePublicacion?: string;
  } | null>(null);

  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: {
    idPublicacion: number;
    fechaDesde: string;
    fechaHasta: string;
  }) => {
    setLoading(true);
    setError(null);
    setApiErrorParams(null);
    setReportData(null);
    setDetalleDiarioCalculado([]);
    setPromediosPorDiaCalculado([]);
    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 pubData = await pubService.getPublicacionById(params.idPublicacion);

    setCurrentParams({ ...params, nombrePublicacion: pubData?.nombre }); // Asumiendo que pubData es la tupla

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

      let acumuladoVentaNeta = 0;
      let diasConActividadDetalle = 0;
      let ultimoPromedioDetalle = 0;

      const detalleCalculadoLocal = data.detalleSimple.map((item, index) => {
        const llevados = item.llevados || 0;
        const devueltos = item.devueltos || 0;
        const ventaNeta = llevados - devueltos;

        if (llevados > 0) {
          diasConActividadDetalle++;
          acumuladoVentaNeta += ventaNeta;
        }
        const promedioActual = diasConActividadDetalle > 0 ? acumuladoVentaNeta / diasConActividadDetalle : 0;
        ultimoPromedioDetalle = promedioActual;

        return {
          ...item,
          id: `simple-can-${index}`, // o simple-dist-${index}
          ventaNeta: ventaNeta,
          promedio: promedioActual,
          porcentajeDevolucion: llevados > 0 ? (devueltos / llevados) * 100 : 0, // Esto es % Devolución real
        };
      });
      setDetalleDiarioCalculado(detalleCalculadoLocal);

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

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


      // --- Cálculos para promedios y sus totales ---
      const promediosCalculadoLocal = data.promediosPorDia.map((item, index) => {
        const promLlevados = item.promedio_Llevados || 0;
        const promDevueltos = item.promedio_Devueltos || 0;
        const promVentas = item.promedio_Ventas || 0;
        return {
          ...item,
          id: `prom-can-${index}`,
          porcentajeColumnaPDF: promLlevados > 0 ? (promVentas / promLlevados) * 100 : 0,
          porcentajeDevolucion: promLlevados > 0 ? (promDevueltos / promLlevados) * 100 : 0,
        };
      });
      setPromediosPorDiaCalculado(promediosCalculadoLocal);

      const totalDiasProm = promediosCalculadoLocal.reduce((sum, item) => sum + (item.cant || 0), 0);
      const totalPonderadoLlevados = promediosCalculadoLocal.reduce((sum, item) => sum + ((item.promedio_Llevados || 0) * (item.cant || 0)), 0);
      const totalPonderadoDevueltos = promediosCalculadoLocal.reduce((sum, item) => sum + ((item.promedio_Devueltos || 0) * (item.cant || 0)), 0);
      const totalPonderadoVentas = promediosCalculadoLocal.reduce((sum, item) => sum + ((item.promedio_Ventas || 0) * (item.cant || 0)), 0);

      const promGeneralLlevados = totalDiasProm > 0 ? totalPonderadoLlevados / totalDiasProm : 0;
      const promGeneralDevueltos = totalDiasProm > 0 ? totalPonderadoDevueltos / totalDiasProm : 0;

      setTotalesPromedios({
        cantDias: totalDiasProm,
        promLlevados: promGeneralLlevados,
        promDevueltos: promGeneralDevueltos,
        promVentas: totalDiasProm > 0 ? totalPonderadoVentas / totalDiasProm : 0,
        porcentajeDevolucionGeneral: promGeneralLlevados > 0 ? (promGeneralDevueltos / promGeneralLlevados) * 100 : 0,
      });

      setReportData({ detalleSimple: detalleCalculadoLocal, promediosPorDia: promediosCalculadoLocal });

      if (detalleCalculadoLocal.length === 0 && promediosCalculadoLocal.length === 0) {
        setError("No se encontraron datos para los parámetros seleccionados.");
      }
      setShowParamSelector(false);
    } catch (err: any) {
      // ... (manejo de errores)
    } finally {
      setLoading(false);
    }
  }, []);

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

  const handleExportToExcel = useCallback(() => {
    if (!detalleDiarioCalculado.length && !promediosPorDiaCalculado.length) {
      alert("No hay datos para exportar.");
      return;
    }
    const wb = XLSX.utils.book_new();

    if (detalleDiarioCalculado.length) {
      const simpleToExport = detalleDiarioCalculado.map(({ id, ...rest }) => ({
        "Día": rest.dia,
        "Llevados": rest.llevados,
        "Devueltos": rest.devueltos,
        "Venta Neta": rest.ventaNeta,
        "Promedio": rest.promedio,
        "% Devolución": rest.porcentajeDevolucion,
      }));
      simpleToExport.push({
        "Día": 0, "Llevados": totalesDetalle.llevados, "Devueltos": totalesDetalle.devueltos,
        "Venta Neta": totalesDetalle.ventaNeta, "Promedio": totalesDetalle.promedioGeneralVentaNeta,
        "% Devolución": totalesDetalle.porcentajeDevolucionGeneral,
      });
      const wsSimple = XLSX.utils.json_to_sheet(simpleToExport);
      XLSX.utils.book_append_sheet(wb, wsSimple, "DetalleDiarioCanillitas");
    }

    if (promediosPorDiaCalculado.length) {
      const promediosToExport = promediosPorDiaCalculado.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.porcentajeDevolucion,
      }));
      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, "PromediosCanillitas");
    }

    let fileName = "ListadoDistribucionCanillitas";
    if (currentParams) {
      fileName += `_${currentParams.nombrePublicacion?.replace(/\s+/g, '') ?? `Pub${currentParams.idPublicacion}`}`;
      fileName += `_${currentParams.fechaDesde}_a_${currentParams.fechaHasta}`;
    }
    fileName += ".xlsx";
    XLSX.writeFile(wb, fileName);
  }, [detalleDiarioCalculado, promediosPorDiaCalculado, 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.getListadoDistribucionCanillasPdf(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 },
    { field: 'llevados', headerName: 'Llevados', type: 'number', flex: 0.7, minWidth: 90, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'devueltos', headerName: 'Devueltos', type: 'number', flex: 0.7, minWidth: 90, align: 'right', headerAlign: 'right', valueFormatter: (value) => value != null ? Number(value).toLocaleString('es-AR') : '0' },
    { field: 'ventaNeta', headerName: 'Venta Neta', type: 'number', flex: 0.8, minWidth: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'promedio', headerName: 'Promedio', type: 'number', flex: 0.8, minWidth: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR', { maximumFractionDigits: 0 }) },
    { field: 'porcentajeDevolucion', headerName: '% Devolución', type: 'number', flex: 0.8, minWidth: 110, align: 'right', headerAlign: 'right', valueFormatter: (value) => `${Number(value).toLocaleString('es-AR', { maximumFractionDigits: 2 })}%` },
  ];

  const columnsPromedios: GridColDef[] = [
    { field: 'dia', headerName: 'Día Semana', width: 140, flex: 1 },
    { 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: 0.8, minWidth: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'promedio_Devueltos', headerName: 'Prom. Devueltos', type: 'number', flex: 0.8, minWidth: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'promedio_Ventas', headerName: 'Prom. Ventas', type: 'number', flex: 0.8, minWidth: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => Number(value).toLocaleString('es-AR') },
    { field: 'porcentajeDevolucion', headerName: '% Devolución', type: 'number', flex: 0.8, minWidth: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => `${Number(value).toLocaleString('es-AR', { maximumFractionDigits: 2 })}%` },
  ];



  // --- Custom Footer para Detalle Diario ---
  const CustomFooterDetalle = () => (
    <GridFooterContainer sx={{ justifyContent: 'space-between', alignItems: 'center', width: '100%' }}>
      {/* Contenedor para los elementos del footer por defecto (paginación, etc.) */}
      <Box sx={{ display: 'flex', alignItems: 'center', flexShrink: 0 }}> {/* Permitir que se encoja un poco si es necesario */}
        <GridFooter sx={{ borderTop: 'none' }} />
      </Box>
      {/* Contenedor para tus totales */}
      <Box sx={{ p: 1, display: 'flex', alignItems: 'center', fontWeight: 'bold', whiteSpace: 'nowrap', overflowX: 'auto' }}>
        <Typography variant="subtitle2" sx={{ minWidth: columnsPromedios[0].width || 'auto', textAlign: 'right', fontWeight: 'bold' }}>General:</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', { maximumFractionDigits: 0 })}</Typography>
        <Typography variant="subtitle2" sx={{ minWidth: columnsDetalle[5].minWidth || 'auto', textAlign: 'right', fontWeight: 'bold' }}>{totalesDetalle.porcentajeDevolucionGeneral.toLocaleString('es-AR', { maximumFractionDigits: 2 })}%</Typography>
      </Box>
    </GridFooterContainer>
  );

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

  if (showParamSelector) {
    return (
      <Box sx={{ p: 2, display: 'flex', justifyContent: 'center', mt: 2 }}>
        <Paper sx={{ width: '100%', maxWidth: 600 }} elevation={3}>
          <SeleccionaReporteListadoDistribucionCanillas
            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 Canillitas</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>
          {detalleDiarioCalculado.length > 0 ? (
            <Paper sx={{ height: 450, width: '100%', mb: 3, '& .MuiDataGrid-footerContainer': { minHeight: '52px' } }}>
              <DataGrid
                rows={detalleDiarioCalculado} // Usar los datos calculados
                columns={columnsDetalle}
                localeText={esES.components.MuiDataGrid.defaultProps.localeText}
                density="compact"
                slots={{ footer: CustomFooterDetalle }}
                hideFooterSelectedRowCount
              />
            </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>
          {promediosPorDiaCalculado.length > 0 ? (
            <Paper sx={{ height: 360, width: '100%', '& .MuiDataGrid-footerContainer': { minHeight: '52px' } }}>
              <DataGrid
                rows={promediosPorDiaCalculado} // Usar los datos calculados
                columns={columnsPromedios}
                localeText={esES.components.MuiDataGrid.defaultProps.localeText}
                density="compact"
                slots={{ footer: CustomFooterPromedios }}
                hideFooterSelectedRowCount
                sx={{
                  '& .MuiTablePagination-root': { // Oculta el paginador por defecto
                    display: 'none',
                  },
                }}
              />
            </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 ReporteListadoDistribucionCanillasPage; // Asegúrate de que el nombre del archivo coincida con este export