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 type { Theme } from '@mui/material/styles';
import { esES } from '@mui/x-data-grid/locales';
import reportesService from '../../services/Reportes/reportesService';
import type { ComparativaConsumoBobinasDto } from '../../models/dtos/Reportes/ComparativaConsumoBobinasDto';
import SeleccionaReporteComparativaConsumoBobinas from './SeleccionaReporteComparativaConsumoBobinas';
import { usePermissions } from '../../hooks/usePermissions';
import * as XLSX from 'xlsx';
import axios from 'axios';

// Interfaz extendida para DataGrid
interface ComparativaConsumoBobinasDataGridDto extends ComparativaConsumoBobinasDto {
  id: string;
}

const ReporteComparativaConsumoBobinasPage: React.FC = () => {
  const [reportData, setReportData] = useState<ComparativaConsumoBobinasDataGridDto[]>([]); // Usar tipo extendido
  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<{
    fechaInicioMesA: string; fechaFinMesA: string;
    fechaInicioMesB: string; fechaFinMesB: string;
    idPlanta?: number | null; consolidado: boolean;
    nombrePlanta?: string;
    mesA?: string;
    mesB?: string;
  } | null>(null);
  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR007");

  const numberLocaleFormatter = (value: number | null | undefined) =>
    value != null ? Number(value).toLocaleString('es-AR') : '';

  const handleGenerarReporte = useCallback(async (params: {
    fechaInicioMesA: string; fechaFinMesA: string;
    fechaInicioMesB: string; fechaFinMesB: string;
    idPlanta?: number | null; consolidado: boolean;
  }) => {
    if (!puedeVerReporte) {
      setError("No tiene permiso para generar este reporte.");
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    setApiErrorParams(null);
    setReportData([]);

    let plantaNombre = "Consolidado";
    if (!params.consolidado && params.idPlanta) {
      const plantaService = (await import('../../services/Impresion/plantaService')).default;
      const plantaData = await plantaService.getPlantaById(params.idPlanta);
      plantaNombre = plantaData?.nombre ?? "N/A";
    }
    // Formatear nombres de meses para el PDF
    const formatMonthYear = (dateString: string) => {
      const date = new Date(dateString + 'T00:00:00'); // Asegurar que se parsea como local
      return date.toLocaleDateString('es-AR', { month: 'long', year: 'numeric', timeZone: 'UTC' });
    };

    setCurrentParams({
      ...params,
      nombrePlanta: plantaNombre,
      mesA: formatMonthYear(params.fechaInicioMesA),
      mesB: formatMonthYear(params.fechaInicioMesB)
    });

    try {
      const data = await reportesService.getComparativaConsumoBobinas(params);
      const dataWithIds = data.map((item, index) => ({ ...item, id: `${item.tipoBobina}-${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 }) => rest).map(item => ({
      "Tipo Bobina": item.tipoBobina,
      "Cant. Mes A": item.bobinasUtilizadasMesA,
      "Cant. Mes B": item.bobinasUtilizadasMesB,
      "Dif. Cant.": item.diferenciaBobinasUtilizadas,
      "Kg Mes A": item.kilosUtilizadosMesA,
      "Kg Mes B": item.kilosUtilizadosMesB,
      "Dif. Kg": item.diferenciaKilosUtilizados,
    }));

    const totales = dataToExport.reduce((acc, row) => {
      acc.cantA += Number(row["Cant. Mes A"]); acc.cantB += Number(row["Cant. Mes B"]);
      acc.difCant += Number(row["Dif. Cant."]); acc.kgA += Number(row["Kg Mes A"]);
      acc.kgB += Number(row["Kg Mes B"]); acc.difKg += Number(row["Dif. Kg"]);
      return acc;
    }, { cantA: 0, cantB: 0, difCant: 0, kgA: 0, kgB: 0, difKg: 0 });

    dataToExport.push({
      "Tipo Bobina": "TOTALES", "Cant. Mes A": totales.cantA, "Cant. Mes B": totales.cantB,
      "Dif. Cant.": totales.difCant, "Kg Mes A": totales.kgA, "Kg Mes B": totales.kgB,
      "Dif. Kg": totales.difKg,
    });

    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, "ComparativaConsumo");
    let fileName = "ReporteComparativaConsumoBobinas";
    if (currentParams) {
      fileName += `_${currentParams.consolidado ? 'Consolidado' : `Planta${currentParams.idPlanta}`}`;
      fileName += `_${currentParams.fechaInicioMesA}_vs_${currentParams.fechaInicioMesB}`;
    }
    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.getComparativaConsumoBobinasPdf(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 columns: GridColDef<ComparativaConsumoBobinasDataGridDto>[] = [ // Tipar con la interfaz correcta
    { field: 'tipoBobina', headerName: 'Tipo Bobina', width: 250, flex: 1.5 },
    { field: 'bobinasUtilizadasMesA', headerName: 'Cant. Mes A', type: 'number', width: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'bobinasUtilizadasMesB', headerName: 'Cant. Mes B', type: 'number', width: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'diferenciaBobinasUtilizadas', headerName: 'Dif. Cant.', type: 'number', width: 110, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'kilosUtilizadosMesA', headerName: 'Kg Mes A', type: 'number', width: 120, align: 'right', headerAlign: 'right', cellClassName: 'separator-left', headerClassName: 'separator-left', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'kilosUtilizadosMesB', headerName: 'Kg Mes B', type: 'number', width: 120, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'diferenciaKilosUtilizados', headerName: 'Dif. Kg', type: 'number', width: 110, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
  ];

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

  // Calcular totales para el footer
  const totalesGenerales = useMemo(() => {
    if (reportData.length === 0) return null;
    return {
      bobinasUtilizadasMesA: reportData.reduce((sum, item) => sum + item.bobinasUtilizadasMesA, 0),
      bobinasUtilizadasMesB: reportData.reduce((sum, item) => sum + item.bobinasUtilizadasMesB, 0),
      diferenciaBobinasUtilizadas: reportData.reduce((sum, item) => sum + item.diferenciaBobinasUtilizadas, 0),
      kilosUtilizadosMesA: reportData.reduce((sum, item) => sum + item.kilosUtilizadosMesA, 0),
      kilosUtilizadosMesB: reportData.reduce((sum, item) => sum + item.kilosUtilizadosMesB, 0),
      diferenciaKilosUtilizados: reportData.reduce((sum, item) => sum + item.diferenciaKilosUtilizados, 0),
    };
  }, [reportData]);


  // eslint-disable-next-line react/display-name
  const CustomFooter = () => {
    if (!totalesGenerales) return null;

    const getCellStyle = (field: (typeof columns)[number]['field'] | 'label', isLabel: boolean = false) => {
      const colConfig = columns.find(c => c.field === field);
      // Ajustar anchos para los totales para que sean más compactos
      let targetWidth: number | string = 'auto';
      let targetMinWidth: number | string = 'auto';

      if (isLabel) {
        targetWidth = colConfig?.width ? Math.max(80, colConfig.width * 0.5) : 100; // Más corto para "TOTALES:"
        targetMinWidth = 80;
      } else if (colConfig) {
        targetWidth = colConfig.width ? Math.max(70, colConfig.width * 0.75) : 90; // 75% del ancho de columna, mínimo 70
        targetMinWidth = 70;
      }

      const style: React.CSSProperties = {
        minWidth: targetMinWidth,
        width: targetWidth,
        textAlign: isLabel ? 'left' : (colConfig?.align || 'right') as 'left' | 'right' | 'center',
        paddingRight: isLabel ? 1 : (field === 'diferenciaKilosUtilizados' ? 0 : 1), // pr en theme units
        fontWeight: 'bold',
        whiteSpace: 'nowrap',
      };

      // Aplicar el separador si es la columna 'kilosUtilizadosMesA'
      if (field === 'kilosUtilizadosMesA') {
        style.borderLeft = `2px solid grey`; // O theme.palette.divider
        style.paddingLeft = '8px'; // Espacio después del separador
      }
      return style;
    };

    return (
      <GridFooterContainer sx={{
        display: 'flex',
        justifyContent: 'space-between',
        alignItems: 'center',
        width: '100%',
        borderTop: (theme) => `1px solid ${theme.palette.divider}`,
        minHeight: '52px',
      }}>
        <Box sx={{
          display: 'flex',
          alignItems: 'center',
          flexShrink: 0,
          overflow: 'hidden',
          px: 1,
        }}>
          <GridFooter
            sx={{
              borderTop: 'none',
              width: 'auto',
              '& .MuiToolbar-root': {
                paddingLeft: 0,
                paddingRight: 0,
              },
              '& .MuiDataGrid-selectedRowCount': { display: 'none' },
            }}
          />
        </Box>

        <Box sx={{
          display: 'flex',
          alignItems: 'center',
          fontWeight: 'bold',
          whiteSpace: 'nowrap',
          overflowX: 'auto',
          px: 1,
          flexShrink: 1,
        }}>
          <Typography variant="subtitle2" sx={getCellStyle('label', true)}>TOTALES:</Typography>
          <Typography variant="subtitle2" sx={getCellStyle('bobinasUtilizadasMesA')}>{numberLocaleFormatter(totalesGenerales.bobinasUtilizadasMesA)}</Typography>
          <Typography variant="subtitle2" sx={getCellStyle('bobinasUtilizadasMesB')}>{numberLocaleFormatter(totalesGenerales.bobinasUtilizadasMesB)}</Typography>
          <Typography variant="subtitle2" sx={getCellStyle('diferenciaBobinasUtilizadas')}>{numberLocaleFormatter(totalesGenerales.diferenciaBobinasUtilizadas)}</Typography>
          <Typography variant="subtitle2" sx={getCellStyle('kilosUtilizadosMesA')}>{numberLocaleFormatter(totalesGenerales.kilosUtilizadosMesA)}</Typography>
          <Typography variant="subtitle2" sx={getCellStyle('kilosUtilizadosMesB')}>{numberLocaleFormatter(totalesGenerales.kilosUtilizadosMesB)}</Typography>
          <Typography variant="subtitle2" sx={getCellStyle('diferenciaKilosUtilizados')}>{numberLocaleFormatter(totalesGenerales.diferenciaKilosUtilizados)}</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}>
          <SeleccionaReporteComparativaConsumoBobinas
            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: Comparativa Consumo de Bobinas</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="info" sx={{ my: 2 }}>{error}</Alert>}

      {!loading && !error && reportData.length > 0 && (
        <Paper sx={{
          width: '100%',
          mt: 2,
          '& .separator-left': {
            borderLeft: (theme: Theme) => `2px solid ${theme.palette.divider}`,
          },
        }}>
          <DataGrid
            rows={rows}
            columns={columns}
            localeText={esES.components.MuiDataGrid.defaultProps.localeText}
            slots={{ footer: CustomFooter }}
            density="compact"
            sx={{ height: 'calc(100vh - 300px)' }} // Ajusta esta altura según sea necesario
            initialState={{
              pagination: {
                paginationModel: { pageSize: 10, page: 0 },
              },
            }}
            pageSizeOptions={[5, 10, 25, 50]}
            disableRowSelectionOnClick
          // hideFooterSelectedRowCount // Ya se maneja en CustomFooter
          />
        </Paper>
      )}
      {!loading && !error && reportData.length === 0 && currentParams && (<Typography sx={{ mt: 2, fontStyle: 'italic' }}>No se encontraron datos para los criterios seleccionados.</Typography>)}
    </Box>
  );
};

export default ReporteComparativaConsumoBobinasPage;