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';
import { esES } from '@mui/x-data-grid/locales';
import reportesService from '../../services/Reportes/reportesService';
import type { ListadoDistCanMensualDiariosDto } from '../../models/dtos/Reportes/ListadoDistCanMensualDiariosDto';
import type { ListadoDistCanMensualPubDto } from '../../models/dtos/Reportes/ListadoDistCanMensualPubDto';
import SeleccionaReporteListadoDistMensual, { type TipoListadoDistMensual } from './SeleccionaReporteListadoDistMensual';
import { usePermissions } from '../../hooks/usePermissions';
import * as XLSX from 'xlsx';
import axios from 'axios';

// Interfaces para DataGrid (añadiendo 'id')
interface GridDiariosItem extends ListadoDistCanMensualDiariosDto { id: string; }
interface GridPubItem extends ListadoDistCanMensualPubDto { id: string; }


const ReporteListadoDistMensualPage: React.FC = () => {
  const [reporteDiariosData, setReporteDiariosData] = useState<GridDiariosItem[]>([]);
  const [reportePubData, setReportePubData] = useState<GridPubItem[]>([]);
  const [currentReportVariant, setCurrentReportVariant] = useState<TipoListadoDistMensual | 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<{
    fechaDesde: string;
    fechaHasta: string;
    esAccionista: boolean;
    tipoReporte: TipoListadoDistMensual;
    nombreTipoVendedor?: string;
    mesAnio?: string;
  } | null>(null);

  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR009"); // Asumiendo RR009 para este reporte

  const currencyFormatter = (value?: number | null) => value != null ? value.toLocaleString('es-AR', { style: 'currency', currency: 'ARS' }) : '-';
  const numberFormatter = (value?: number | null) => value != null ? Number(value).toLocaleString('es-AR') : '-';

  const handleGenerarReporte = useCallback(async (params: {
    fechaDesde: string;
    fechaHasta: string;
    esAccionista: boolean;
    tipoReporte: TipoListadoDistMensual;
  }) => {
    if (!puedeVerReporte) {
      setError("No tiene permiso para generar este reporte.");
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    setApiErrorParams(null);
    setReporteDiariosData([]);
    setReportePubData([]);
    setCurrentReportVariant(params.tipoReporte);

    const mesAnioStr = new Date(params.fechaDesde + 'T00:00:00').toLocaleDateString('es-AR', { month: 'long', year: 'numeric', timeZone: 'UTC' });
    setCurrentParams({ ...params, nombreTipoVendedor: params.esAccionista ? "Accionistas" : "Canillitas", mesAnio: mesAnioStr });

    try {
      if (params.tipoReporte === 'diarios') {
        const data = await reportesService.getListadoDistMensualDiarios(params);
        setReporteDiariosData(data.map((item, i) => ({ ...item, id: `diario-${item.canilla}-${i}` })));
        if (data.length === 0) setError("No se encontraron datos para la variante 'Desglose por Diarios'.");
      } else { // 'publicaciones'
        const data = await reportesService.getListadoDistMensualPorPublicacion(params);
        setReportePubData(data.map((item, i) => ({ ...item, id: `pub-${item.canilla}-${item.publicacion}-${i}` })));
        if (data.length === 0) setError("No se encontraron datos para la variante 'Desglose por Publicación'.");
      }
      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);
    }
  }, [puedeVerReporte]);

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

  const handleExportToExcel = useCallback(() => {
    if (reporteDiariosData.length === 0 && reportePubData.length === 0) {
      alert("No hay datos para exportar."); return;
    }
    const wb = XLSX.utils.book_new();
    let fileName = "ListadoDistMensual";
    if (currentParams) {
      fileName += `_${currentParams.nombreTipoVendedor?.replace(/\s+/g, '')}`;
      fileName += `_${currentParams.mesAnio?.replace(/\s+/g, '-').replace('/', '-')}`;
    }

    if (currentReportVariant === 'diarios' && reporteDiariosData.length > 0) {
      const data = reporteDiariosData.map(({ id, ...r }) => ({
        "Canillita": r.canilla, "El Día (Cant.)": r.elDia, "El Plata (Cant.)": r.elPlata,
        "Total Vendidos": r.vendidos, "Imp. El Día": r.importeElDia, "Imp. El Plata": r.importeElPlata,
        "Importe Total": r.importeTotal
      }));
      const totalesDiarios = {
        "Canillita": "TOTALES", "El Día (Cant.)": reporteDiariosData.reduce((s, i) => s + (i.elDia ?? 0), 0),
        "El Plata (Cant.)": reporteDiariosData.reduce((s, i) => s + (i.elPlata ?? 0), 0),
        "Total Vendidos": reporteDiariosData.reduce((s, i) => s + (i.vendidos ?? 0), 0),
        "Imp. El Día": reporteDiariosData.reduce((s, i) => s + (i.importeElDia ?? 0), 0),
        "Imp. El Plata": reporteDiariosData.reduce((s, i) => s + (i.importeElPlata ?? 0), 0),
        "Importe Total": reporteDiariosData.reduce((s, i) => s + (i.importeTotal ?? 0), 0)
      };
      data.push(totalesDiarios);
      const ws = XLSX.utils.json_to_sheet(data);
      const headers = Object.keys(data[0] || {});
      ws['!cols'] = headers.map(h => ({ wch: Math.max(...data.map(row => (row as any)[h]?.toString().length ?? 0), h.length) + 2 }));
      XLSX.utils.book_append_sheet(wb, ws, "Desglose Diarios");
      fileName += "_Diarios.xlsx";

    } else if (currentReportVariant === 'publicaciones' && reportePubData.length > 0) {
      // --- INICIO DE CAMBIOS PARA TOTALES EN EXCEL DE PUBLICACIONES ---
      const dataAgrupadaParaExcel: any[] = [];
      const canillitasUnicos = [...new Set(reportePubData.map(item => item.canilla))];

      canillitasUnicos.sort().forEach(nombreCanillita => {
        const itemsDelCanillita = reportePubData.filter(item => item.canilla === nombreCanillita);
        itemsDelCanillita.forEach(item => {
          dataAgrupadaParaExcel.push({
            "Canillita": item.canilla,
            "Publicación": item.publicacion,
            "Llevados": item.totalCantSalida,
            "Devueltos": item.totalCantEntrada,
            "A Rendir": item.totalRendir
          });
        });
        // Fila de Total por Canillita
        const totalLlevadosCanillita = itemsDelCanillita.reduce((sum, item) => sum + (item.totalCantSalida ?? 0), 0);
        const totalDevueltosCanillita = itemsDelCanillita.reduce((sum, item) => sum + (item.totalCantEntrada ?? 0), 0);
        const totalRendirCanillita = itemsDelCanillita.reduce((sum, item) => sum + (item.totalRendir ?? 0), 0);
        dataAgrupadaParaExcel.push({
          "Canillita": `Total ${nombreCanillita}`,
          "Publicación": "",
          "Llevados": totalLlevadosCanillita,
          "Devueltos": totalDevueltosCanillita,
          "A Rendir": totalRendirCanillita,
        });
        dataAgrupadaParaExcel.push({}); // Fila vacía para separar
      });

      // Fila de Total General
      const totalGeneralLlevados = reportePubData.reduce((sum, item) => sum + (item.totalCantSalida ?? 0), 0);
      const totalGeneralDevueltos = reportePubData.reduce((sum, item) => sum + (item.totalCantEntrada ?? 0), 0);
      const totalGeneralRendir = reportePubData.reduce((sum, item) => sum + (item.totalRendir ?? 0), 0);
      dataAgrupadaParaExcel.push({
        "Canillita": "TOTAL GENERAL",
        "Publicación": "",
        "Llevados": totalGeneralLlevados,
        "Devueltos": totalGeneralDevueltos,
        "A Rendir": totalGeneralRendir,
      });

      const ws = XLSX.utils.json_to_sheet(dataAgrupadaParaExcel);
      const headers = ["Canillita", "Publicación", "Llevados", "Devueltos", "A Rendir"]; // Definir orden
      ws['!cols'] = headers.map(h => ({ wch: Math.max(...dataAgrupadaParaExcel.map(row => (row as any)[h]?.toString().length ?? 0), h.length) + 2 }));
      XLSX.utils.book_append_sheet(wb, ws, "Desglose Publicaciones");
      fileName += "_Publicaciones.xlsx";
    }

    if (wb.SheetNames.length > 0) XLSX.writeFile(wb, fileName);
    else alert("No hay datos para la variante seleccionada para exportar.");

  }, [reporteDiariosData, reportePubData, currentReportVariant, currentParams]);

  const handleGenerarYAbrirPdf = useCallback(async () => {
    if (!currentParams) { setError("Seleccione parámetros."); return; }
    if (!puedeVerReporte) { setError("Sin permiso para PDF."); return; }
    setLoadingPdf(true); setError(null);
    try {
      let blob;
      if (currentParams.tipoReporte === 'diarios') {
        blob = await reportesService.getListadoDistMensualDiariosPdf(currentParams);
      } else {
        blob = await reportesService.getListadoDistMensualPorPublicacionPdf(currentParams);
      }
      if (blob.type === "application/json") {
        const text = await blob.text();
        const msg = JSON.parse(text).message ?? "Error inesperado al generar PDF.";
        setError(msg);
        setLoadingPdf(false); // Asegurar que se detenga el loader
        return;
      }
      const url = URL.createObjectURL(blob);
      const w = window.open(url, '_blank');
      if (!w) alert("Permita popups para ver el PDF.");
    } catch (err: any) {
      const message = axios.isAxiosError(err) && err.response?.data?.message
        ? err.response.data.message
        : 'Ocurrió un error al generar el PDF.';
      setError(message);
    } finally {
      setLoadingPdf(false);
    }
  }, [currentParams, puedeVerReporte]);

  const FooterSimple = () => (<GridFooterContainer><GridFooter /></GridFooterContainer>);

  const totalGeneralDiarios = useMemo(() => {
    if (reporteDiariosData.length === 0) return null;
    return {
      elDia: reporteDiariosData.reduce((s, i) => s + (i.elDia ?? 0), 0),
      elPlata: reporteDiariosData.reduce((s, i) => s + (i.elPlata ?? 0), 0),
      vendidos: reporteDiariosData.reduce((s, i) => s + (i.vendidos ?? 0), 0),
      importeElDia: reporteDiariosData.reduce((s, i) => s + (i.importeElDia ?? 0), 0),
      importeElPlata: reporteDiariosData.reduce((s, i) => s + (i.importeElPlata ?? 0), 0),
      importeTotal: reporteDiariosData.reduce((s, i) => s + (i.importeTotal ?? 0), 0)
    };
  }, [reporteDiariosData]);

  // eslint-disable-next-line react/display-name
  const FooterDiarios = () => {
    if (!totalGeneralDiarios) return <GridFooterContainer><GridFooter sx={{ borderTop: 'none' }} /></GridFooterContainer>;
    return (
      <GridFooterContainer sx={{
        display: 'flex',
        justifyContent: 'space-between', // Separa la paginación (izquierda) de los totales (derecha)
        alignItems: 'center',
        width: '100%',
        borderTop: (theme) => `1px solid ${theme.palette.divider}`,
        minHeight: '52px', // Altura estándar para el footer
        // No es necesario p: aquí si los hijos lo manejan o el GridFooterContainer lo aplica por defecto
      }}>
        {/* Box para la paginación estándar */}
        <Box sx={{
          display: 'flex',
          alignItems: 'center',
          flexShrink: 0, // Evita que este box se encoja si los totales son anchos
          overflow: 'hidden', // Para asegurar que no desborde si el contenido interno es muy ancho
          px: 1, // Padding horizontal para el contenedor de la paginación
          // Considera un flexGrow o un width/maxWidth si necesitas más control sobre el espacio de la paginación
          // Ejemplo: flexGrow: 1, maxWidth: 'calc(100% - 250px)' (para dejar espacio a los totales)
        }}>
          <GridFooter
            sx={{
              borderTop: 'none', // Quitar el borde superior del GridFooter interno
              width: 'auto', // Permite que el GridFooter se ajuste a su contenido (paginador)
              '& .MuiToolbar-root': { // Ajustar padding del toolbar de paginación
                paddingLeft: 0, // O un valor pequeño si es necesario
                paddingRight: 0,
              },
              // Mantenemos oculto el contador de filas seleccionadas si no lo queremos
              '& .MuiDataGrid-selectedRowCount': { display: 'none' },
            }}
          />
        </Box>
        {/* Box para los totales personalizados */}
        <Box sx={{
          display: 'flex',
          alignItems: 'center',
          fontWeight: 'bold',
          whiteSpace: 'nowrap', // Evita que los totales hagan salto de línea
          overflowX: 'auto',   // Scroll DENTRO de este Box si los totales son muy anchos
          px: 2, // Padding horizontal para el contenedor de los totales (ajusta pr:2 de tu ejemplo)
          flexShrink: 1, // Permitir que este contenedor se encoja si la paginación necesita más espacio
        }}>
          <Typography variant="subtitle2" sx={{ width: columnsDiarios[0].width, textAlign: 'right', fontWeight: 'bold', pr: 1 }}>TOTALES:</Typography>
          <Typography variant="subtitle2" sx={{ width: columnsDiarios[1].width, textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{numberFormatter(totalGeneralDiarios.elDia)}</Typography>
          <Typography variant="subtitle2" sx={{ width: columnsDiarios[2].width, textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{numberFormatter(totalGeneralDiarios.elPlata)}</Typography>
          <Typography variant="subtitle2" sx={{ width: columnsDiarios[3].width, textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{numberFormatter(totalGeneralDiarios.vendidos)}</Typography>
          <Typography variant="subtitle2" sx={{ width: columnsDiarios[4].width, textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{currencyFormatter(totalGeneralDiarios.importeElDia)}</Typography>
          <Typography variant="subtitle2" sx={{ width: columnsDiarios[5].width, textAlign: 'right', fontWeight: 'bold', pr: 1 }}>{currencyFormatter(totalGeneralDiarios.importeElPlata)}</Typography>
          <Typography variant="subtitle2" sx={{ width: columnsDiarios[6].width, textAlign: 'right', fontWeight: 'bold' }}>{currencyFormatter(totalGeneralDiarios.importeTotal)}</Typography>
        </Box>
      </GridFooterContainer>
    );
  };

  const columnsDiarios: GridColDef<GridDiariosItem>[] = [
    { field: 'canilla', headerName: 'Nombre', width: 250, flex: 1.5 },
    { field: 'elDia', headerName: 'El Día (Cant)', type: 'number', width: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberFormatter(value as number) },
    { field: 'elPlata', headerName: 'El Plata (Cant)', type: 'number', width: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberFormatter(value as number) },
    { field: 'vendidos', headerName: 'Total Vendidos', type: 'number', width: 130, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberFormatter(value as number) },
    { field: 'importeElDia', headerName: 'Imp. El Día', type: 'number', width: 150, align: 'right', headerAlign: 'right', valueFormatter: (value) => currencyFormatter(value as number) },
    { field: 'importeElPlata', headerName: 'Imp. El Plata', type: 'number', width: 150, align: 'right', headerAlign: 'right', valueFormatter: (value) => currencyFormatter(value as number) },
    { field: 'importeTotal', headerName: 'Importe Total', type: 'number', width: 160, align: 'right', headerAlign: 'right', valueFormatter: (value) => currencyFormatter(value as number) },
  ];
  const columnsPublicaciones: GridColDef<GridPubItem>[] = [
    { field: 'canilla', headerName: 'Canillita', width: 250, flex: 1.2 },
    { field: 'publicacion', headerName: 'Publicación', width: 200, flex: 1 },
    { field: 'totalCantSalida', headerName: 'Llevados', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberFormatter(value as number) },
    { field: 'totalCantEntrada', headerName: 'Devueltos', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberFormatter(value as number) },
    { field: 'totalRendir', headerName: 'A Rendir', type: 'number', width: 150, align: 'right', headerAlign: 'right', valueFormatter: (value) => currencyFormatter(value as number) },
  ];

  const rowsDiarios = useMemo(() => reporteDiariosData, [reporteDiariosData]);
  const rowsPubs = useMemo(() => reportePubData, [reportePubData]);

  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}>
          <SeleccionaReporteListadoDistMensual
            onGenerarReporte={handleGenerarReporte}
            isLoading={loading}
            apiErrorMessage={apiErrorParams}
          />
        </Paper>
      </Box>
    );
  }

  if (!loading && !puedeVerReporte && !showParamSelector) {
    return (
      <Box sx={{ p: 2 }}>
        <Alert severity="error" sx={{ m: 2 }}>No tiene permiso para ver este reporte.</Alert>
        <Button onClick={handleVolverAParametros} variant="outlined" color="secondary" size="small">
          Volver
        </Button>
      </Box>
    );
  }

  const renderReportContent = () => {
    if (loading) return <Box sx={{ display: 'flex', justifyContent: 'center', my: 2 }}><CircularProgress /></Box>;
    if (error && !loading) return <Alert severity="info" sx={{ my: 2 }}>{error}</Alert>;

    if (currentReportVariant === 'diarios') {
      if (reporteDiariosData.length === 0) return <Typography sx={{ mt: 2, fontStyle: 'italic' }}>No hay datos para la variante "Desglose por Diarios".</Typography>;
      return (
        <Paper sx={{ height: 'calc(100vh - 320px)', width: '100%', mt: 2 }}>
          <DataGrid
            rows={rowsDiarios}
            columns={columnsDiarios}
            localeText={esES.components.MuiDataGrid.defaultProps.localeText}
            slots={{ footer: FooterDiarios }}
            density="compact"
            hideFooterSelectedRowCount
            disableRowSelectionOnClick
            initialState={{
              pagination: { paginationModel: { pageSize: 100 } },
            }}
            pageSizeOptions={[25, 50, 100]}
          />
        </Paper>
      );
    }
    if (currentReportVariant === 'publicaciones') {
      if (reportePubData.length === 0) return <Typography sx={{ mt: 2, fontStyle: 'italic' }}>No hay datos para la variante "Desglose por Publicación".</Typography>;
      return (
        <Paper sx={{ height: 'calc(100vh - 320px)', width: '100%', mt: 2 }}>
          <DataGrid
            rows={rowsPubs}
            columns={columnsPublicaciones}
            localeText={esES.components.MuiDataGrid.defaultProps.localeText}
            slots={{ footer: FooterSimple }} // Para esta tabla, un footer simple sin totales complejos por ahora
            density="compact"
            initialState={{
              pagination: { paginationModel: { pageSize: 100 } },
            }}
            pageSizeOptions={[25, 50, 100]}
            disableRowSelectionOnClick
          />
        </Paper>
      );
    }
    return null;
  };

  return (
    <Box sx={{ p: 2 }}>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2, flexWrap: 'wrap', gap: 1 }}>
        <Typography variant="h5">Listado Distribución Mensual ({currentParams?.nombreTipoVendedor})</Typography>
        <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
          <Button onClick={handleGenerarYAbrirPdf} variant="contained" disabled={loadingPdf || (reporteDiariosData.length === 0 && reportePubData.length === 0) || !!error} size="small">
            {loadingPdf ? <CircularProgress size={20} color="inherit" /> : "Abrir PDF"}
          </Button>
          <Button onClick={handleExportToExcel} variant="outlined" disabled={(reporteDiariosData.length === 0 && reportePubData.length === 0) || !!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>
        Mes: {currentParams?.mesAnio || '-'}
      </Typography>
      {renderReportContent()}
    </Box>
  );
};

export default ReporteListadoDistMensualPage;