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 { ConsumoBobinasPublicacionDto } from '../../models/dtos/Reportes/ConsumoBobinasPublicacionDto';
import SeleccionaReporteConsumoBobinasPublicacion from './SeleccionaReporteConsumoBobinasPublicacion';
import { usePermissions } from '../../hooks/usePermissions';
import * as XLSX from 'xlsx';
import axios from 'axios';

const ReporteConsumoBobinasPublicacionPage: React.FC = () => {
  const [reportData, setReportData] = useState<ConsumoBobinasPublicacionDto[]>([]);
  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;
    nombrePublicacion?: string; // Mantenido para nombre de archivo, no afecta al título DataGrid
  } | null>(null);
  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR007");

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

    try {
      const data = await reportesService.getConsumoBobinasPorPublicacion(params);
      const dataWithIds = data.map((item, index) => ({ ...item, id: `${item.nombrePlanta}-${item.nombrePublicacion}-${index}` }));
      setReportData(dataWithIds);

      if (dataWithIds.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([]);
    setError(null);
    setApiErrorParams(null);
    setCurrentParams(null);
  }, []);

  const handleExportToExcel = useCallback(() => {
    if (reportData.length === 0) {
      alert("No hay datos para exportar.");
      return;
    }
    const dataToExport = reportData.map(({ ...rest }) => ({
      "Planta": rest.nombrePlanta,
      "Publicación": rest.nombrePublicacion,
      "Total Kilos": rest.totalKilos,
      "Cantidad Bobinas": rest.cantidadBobinas,
    }));

    const totalGeneralKilos = reportData.reduce((sum, item) => sum + item.totalKilos, 0);
    const totalGeneralBobinas = reportData.reduce((sum, item) => sum + item.cantidadBobinas, 0);

    dataToExport.push({
      "Planta": "TOTAL GENERAL",
      "Publicación": "", // Celda vacía para alineación
      "Total Kilos": totalGeneralKilos,
      "Cantidad Bobinas": totalGeneralBobinas,
    });


    const ws = XLSX.utils.json_to_sheet(dataToExport);
    const headers = Object.keys(dataToExport[0] || {});
    ws['!cols'] = headers.map(h => {
      const maxLen = Math.max(...dataToExport.map(row => (row as any)[h]?.toString().length ?? 0), h.length);
      return { wch: maxLen + 2 };
    });
    ws['!freeze'] = { xSplit: 0, ySplit: 1 };

    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "ConsumoBobinasPublicacion");
    let fileName = "ReporteConsumoBobinasPublicacion";
    if (currentParams) {
      fileName += `_${currentParams.fechaDesde}_a_${currentParams.fechaHasta}`;
    }
    fileName += ".xlsx";
    XLSX.writeFile(wb, fileName);
  }, [reportData, currentParams]);

  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.getConsumoBobinasPorPublicacionPdf(currentParams); // solo fechaDesde, fechaHasta
      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 columns: GridColDef[] = [
    { field: 'nombrePlanta', headerName: 'Planta', width: 200, flex: 1 },
    { field: 'nombrePublicacion', headerName: 'Publicación', width: 250, flex: 1.5 },
    {
      field: 'totalKilos',
      headerName: 'Total Kilos',
      type: 'number',
      width: 150,
      align: 'right',
      headerAlign: 'right',
      valueFormatter: (value) => value != null ? Number(value).toLocaleString('es-AR') : '',
      flex: 0.8
    },
    {
      field: 'cantidadBobinas',
      headerName: 'Cant. Bobinas',
      type: 'number',
      width: 150,
      align: 'right',
      headerAlign: 'right',
      valueFormatter: (value) => value != null ? Number(value).toLocaleString('es-AR') : '',
      flex: 0.8
    },
  ];

  const rows = useMemo(() => reportData, [reportData]);

  const totalGeneralKilos = useMemo(() =>
    reportData.reduce((sum, item) => sum + item.totalKilos, 0),
    [reportData]);
  const totalGeneralBobinas = useMemo(() =>
    reportData.reduce((sum, item) => sum + item.cantidadBobinas, 0),
    [reportData]);

  // eslint-disable-next-line react/display-name
  const CustomFooter = () => {
    // Podrías añadir una condición para no renderizar si no hay datos/totales
    // if (totalGeneralKilos === 0 && totalGeneralBobinas === 0) return null;

    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={{ mr: 1, fontWeight: 'bold' }}>TOTALES:</Typography>
          <Typography variant="subtitle2" sx={{ mr: 2, minWidth: '80px', textAlign: 'right', fontWeight: 'bold' }}>
            Kg: {totalGeneralKilos.toLocaleString('es-AR')}
          </Typography>
          <Typography variant="subtitle2" sx={{ minWidth: '80px', textAlign: 'right', fontWeight: 'bold' }}>
            Cant: {totalGeneralBobinas.toLocaleString('es-AR')}
          </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}>
          <SeleccionaReporteConsumoBobinasPublicacion
            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: Consumo de Bobinas por Publicación</Typography>
        <Box sx={{ display: 'flex', gap: 1 }}>
          <Button onClick={handleGenerarYAbrirPdf} variant="contained" disabled={loadingPdf || reportData.length === 0 || !!error} size="small">
            {loadingPdf ? <CircularProgress size={20} color="inherit" /> : "Abrir PDF"}
          </Button>
          <Button onClick={handleExportToExcel} variant="outlined" disabled={reportData.length === 0 || !!error} size="small">
            Exportar a Excel
          </Button>
          <Button onClick={handleVolverAParametros} variant="outlined" color="secondary" size="small">
            Nuevos Parámetros
          </Button>
        </Box>
      </Box>

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

      {!loading && !error && reportData.length > 0 && (
        <Paper sx={{
          height: 'calc(100vh - 380px)', // Ajustar altura para dar espacio al footer
          width: '100%',
          mt: 2,
          '& .MuiDataGrid-footerContainer': { // Asegurar que el contenedor del footer tenga suficiente espacio
            minHeight: '52px', // o el alto que necesite tu CustomFooter
          }
        }}>
          <DataGrid
            rows={rows}
            columns={columns}
            localeText={esES.components.MuiDataGrid.defaultProps.localeText}
            slots={{ footer: CustomFooter }}
            density="compact"
          // pageSizeOptions={[10, 25, 50]} // Descomentar si deseas que el usuario cambie el tamaño de página
          // initialState={{
          //   pagination: {
          //     paginationModel: { pageSize: 25, page: 0 },
          //   },
          // }}
          // autoHeight // Si se usa autoHeight, el `height` del Paper no aplicará scroll a la tabla
          />
        </Paper>
      )}
      {!loading && !error && reportData.length === 0 && (<Typography>No se encontraron datos para los criterios seleccionados.</Typography>)}
    </Box>
  );
};

export default ReporteConsumoBobinasPublicacionPage;