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'; // Importaciones para DataGrid
import { esES } from '@mui/x-data-grid/locales'; // Para localización
import reportesService from '../../services/Reportes/reportesService';
import type { MovimientoBobinasDto } from '../../models/dtos/Reportes/MovimientoBobinasDto';
import { usePermissions } from '../../hooks/usePermissions';
import SeleccionaReporteMovimientoBobinas from './SeleccionaReporteMovimientoBobinas';
import * as XLSX from 'xlsx';
import axios from 'axios';

// Definición de la interfaz extendida para DataGrid (con 'id')
interface MovimientoBobinasDataGridDto extends MovimientoBobinasDto {
  id: string;
}

const ReporteMovimientoBobinasPage: React.FC = () => {
  const [reportData, setReportData] = useState<MovimientoBobinasDataGridDto[]>([]);
  const [loading, setLoading] = useState(false); // Loading para generar reporte
  const [loadingPdf, setLoadingPdf] = useState(false);
  const [error, setError] = useState<string | null>(null); // Error al generar reporte
  const [apiErrorParams, setApiErrorParams] = useState<string | null>(null); // Error específico del selector
  const [showParamSelector, setShowParamSelector] = useState(true);
  const [currentParams, setCurrentParams] = useState<{
    fechaDesde: string;
    fechaHasta: string;
    idPlanta: number;
    nombrePlanta?: string;
  } | null>(null);

  const { tienePermiso, isSuperAdmin } = usePermissions(); // << OBTENER PERMISOS
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR006"); // << PERMISO ESPECÍFICO

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

  const handleGenerarReporte = useCallback(async (params: {
    fechaDesde: string;
    fechaHasta: string;
    idPlanta: number;
  }) => {
    if (!puedeVerReporte) { // << CHEQUEO DE PERMISO
      setError("No tiene permiso para generar este reporte.");
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    setApiErrorParams(null);

    let plantaNombre = `Planta ${params.idPlanta}`; // Default
    try {
        const plantaService = (await import('../../services/Impresion/plantaService')).default;
        const plantaData = await plantaService.getPlantaById(params.idPlanta);
        if (plantaData) plantaNombre = plantaData.nombre;
    } catch (e) { console.warn("No se pudo obtener nombre de planta para el reporte", e)}
    
    setCurrentParams({...params, nombrePlanta: plantaNombre});

    try {
      const data = await reportesService.getMovimientoBobinas(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); // Error para el selector
      setReportData([]);
    } finally {
      setLoading(false);
    }
  }, [puedeVerReporte]); // << AÑADIR puedeVerReporte

  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(item => ({
      "Tipo Bobina": item.tipoBobina,
      "Cant. Inicial": item.bobinasIniciales,
      "Kg Iniciales": item.kilosIniciales,
      "Compradas": item.bobinasCompradas,
      "Kg Comprados": item.kilosComprados,
      "Consumidas": item.bobinasConsumidas,
      "Kg Consumidos": item.kilosConsumidos,
      "Dañadas": item.bobinasDaniadas,
      "Kg Dañados": item.kilosDaniados,
      "Cant. Final": item.bobinasFinales,
      "Kg Finales": item.kilosFinales,
    }));

    // Añadir fila de totales
    const totalesRow = {
      "Tipo Bobina": "Totales",
      "Cant. Inicial": reportData.reduce((sum, item) => sum + item.bobinasIniciales, 0),
      "Kg Iniciales": reportData.reduce((sum, item) => sum + item.kilosIniciales, 0),
      "Compradas": reportData.reduce((sum, item) => sum + item.bobinasCompradas, 0),
      "Kg Comprados": reportData.reduce((sum, item) => sum + item.kilosComprados, 0),
      "Consumidas": reportData.reduce((sum, item) => sum + item.bobinasConsumidas, 0),
      "Kg Consumidos": reportData.reduce((sum, item) => sum + item.kilosConsumidos, 0),
      "Dañadas": reportData.reduce((sum, item) => sum + item.bobinasDaniadas, 0),
      "Kg Dañados": reportData.reduce((sum, item) => sum + item.kilosDaniados, 0),
      "Cant. Final": reportData.reduce((sum, item) => sum + item.bobinasFinales, 0),
      "Kg Finales": reportData.reduce((sum, item) => sum + item.kilosFinales, 0),
    };
    dataToExport.push(totalesRow);


    const ws = XLSX.utils.json_to_sheet(dataToExport);
    const headers = Object.keys(dataToExport[0]);
    ws['!cols'] = headers.map(h => {
      const maxLen = dataToExport.reduce((prev, row) => {
        const cell = (row as any)[h]?.toString() ?? '';
        return Math.max(prev, cell.length);
      }, 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, "MovimientoBobinas");
    let fileName = "ReporteMovimientoBobinas";
    if (currentParams) {
      // Asumiendo que currentParams.nombrePlanta está disponible o se usa idPlanta
      fileName += `_${currentParams.nombrePlanta || `Planta${currentParams.idPlanta}`}`;
      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.getMovimientoBobinasPdf(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]);

  // Definiciones de Columnas para DataGrid
  const columns: GridColDef[] = [
    { field: 'tipoBobina', headerName: 'Tipo Bobina', width: 200, flex: 1.5 },
    { field: 'bobinasIniciales', headerName: 'Cant. Ini.', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'kilosIniciales', headerName: 'Kg Ini.', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'bobinasCompradas', headerName: 'Compradas', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'kilosComprados', headerName: 'Kg Compr.', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'bobinasConsumidas', headerName: 'Consum.', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'kilosConsumidos', headerName: 'Kg Consum.', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'bobinasDaniadas', headerName: 'Dañadas', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'kilosDaniados', headerName: 'Kg Dañ.', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'bobinasFinales', headerName: 'Cant. Fin.', type: 'number', width: 100, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'kilosFinales', headerName: 'Kg Finales', type: 'number', width: 110, align: 'right', headerAlign: 'right', valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
  ];

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

  // Calcular totales para el footer
  const totales = useMemo(() => {
    if (reportData.length === 0) return null;
    return {
      bobinasIniciales: reportData.reduce((sum, item) => sum + item.bobinasIniciales, 0),
      kilosIniciales: reportData.reduce((sum, item) => sum + item.kilosIniciales, 0),
      bobinasCompradas: reportData.reduce((sum, item) => sum + item.bobinasCompradas, 0),
      kilosComprados: reportData.reduce((sum, item) => sum + item.kilosComprados, 0),
      bobinasConsumidas: reportData.reduce((sum, item) => sum + item.bobinasConsumidas, 0),
      kilosConsumidos: reportData.reduce((sum, item) => sum + item.kilosConsumidos, 0),
      bobinasDaniadas: reportData.reduce((sum, item) => sum + item.bobinasDaniadas, 0),
      kilosDaniados: reportData.reduce((sum, item) => sum + item.kilosDaniados, 0),
      bobinasFinales: reportData.reduce((sum, item) => sum + item.bobinasFinales, 0),
      kilosFinales: reportData.reduce((sum, item) => sum + item.kilosFinales, 0),
    };
  }, [reportData]);

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

    const getCellStyle = (field: (typeof columns)[number]['field'] | 'label', isLabel: boolean = false) => {
        const colConfig = columns.find(c => c.field === field);
        let targetWidth: number | string = 'auto'; // Por defecto, dejar que el contenido decida
        let targetMinWidth: number | string = 'auto';

        if (isLabel) {
            // Para la etiqueta "TOTALES:", un ancho más ajustado.
            // Podrías basarlo en el ancho de la primera columna si es consistentemente la de "Tipo Bobina"
            // o un valor fijo que sepas que funciona.
            targetWidth = colConfig?.width ? Math.max(80, colConfig.width * 0.6) : 120; // Ej: 60% del ancho de la columna o 120px
            targetMinWidth = 80; // Un mínimo razonable para "TOTALES:"
        } else if (colConfig) {
            // Para los valores numéricos, podemos ser un poco más conservadores que el ancho de la columna.
            // O usar el ancho de la columna si es pequeño.
            targetWidth = colConfig.width ? Math.max(70, colConfig.width * 0.85) : 90; // Ej: 85% del ancho de la columna o 90px
            targetMinWidth = 70; // Un mínimo para números
        }
        
        return {
            minWidth: targetMinWidth,
            width: targetWidth,
            textAlign: isLabel ? 'left' : (colConfig?.align || 'right') as 'right' | 'left' | 'center',
            pr: isLabel ? 1 : (field === 'kilosFinales' ? 0 : 1), // padding-right
            fontWeight: 'bold',
            // Añadimos overflow y textOverflow para manejar texto largo en la etiqueta si fuera necesario
            overflow: isLabel ? 'hidden' : undefined,
            textOverflow: isLabel ? 'ellipsis' : undefined,
            whiteSpace: 'nowrap', // Asegurar que no haya saltos de línea en los totales
        };
    };

    return (
        <GridFooterContainer sx={{
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center',
            width: '100%',
            borderTop: (theme) => `1px solid ${theme.palette.divider}`,
            minHeight: '52px',
        }}>
            {/* Box para la paginación estándar */}
            <Box sx={{ 
                display: 'flex', 
                alignItems: 'center',
                flexShrink: 0, 
                overflow: 'hidden', 
                px:1,
                // Para asegurar que la paginación no se coma todo el espacio si es muy ancha:
                // Podríamos darle un flex-basis o un maxWidth si los totales necesitan más espacio garantizado.
                // Por ejemplo:
                // flexBasis: '50%', // Ocupa el 50% del espacio disponible si no hay otros factores
                // maxWidth: '600px', // Un máximo absoluto
            }}>
                <GridFooter 
                    sx={{ 
                        borderTop: 'none',
                        width: '100%',
                        '& .MuiToolbar-root': { 
                            paddingLeft: 0,
                            paddingRight: 0,
                        },
                         '& .MuiDataGrid-selectedRowCount': { display: 'none' }, 
                    }} 
                />
            </Box>

            {/* Box para los totales personalizados */}
            <Box sx={{
                display: 'flex',
                alignItems: 'center',
                fontWeight: 'bold',
                whiteSpace: 'nowrap', // Ya estaba, es importante
                overflowX: 'auto', 
                px:1, 
                flexShrink: 1, // Permitir que este contenedor se encoja si es necesario
                // maxWidth: 'calc(100% - ANCHO_PAGINACION_ESTIMADO)' // Si quieres ser muy preciso
            }}>
                <Typography variant="subtitle2" sx={getCellStyle('label', true)}>TOTALES:</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('bobinasIniciales')}>{numberLocaleFormatter(totales.bobinasIniciales)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('kilosIniciales')}>{numberLocaleFormatter(totales.kilosIniciales)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('bobinasCompradas')}>{numberLocaleFormatter(totales.bobinasCompradas)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('kilosComprados')}>{numberLocaleFormatter(totales.kilosComprados)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('bobinasConsumidas')}>{numberLocaleFormatter(totales.bobinasConsumidas)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('kilosConsumidos')}>{numberLocaleFormatter(totales.kilosConsumidos)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('bobinasDaniadas')}>{numberLocaleFormatter(totales.bobinasDaniadas)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('kilosDaniados')}>{numberLocaleFormatter(totales.kilosDaniados)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('bobinasFinales')}>{numberLocaleFormatter(totales.bobinasFinales)}</Typography>
                <Typography variant="subtitle2" sx={getCellStyle('kilosFinales')}>{numberLocaleFormatter(totales.kilosFinales)}</Typography>
            </Box>
        </GridFooterContainer>
    );
  };

  // --- Lógica de Renderizado Principal ---
  // Primero, el chequeo de permiso para el selector
  if (showParamSelector) {
    if (!loading && !puedeVerReporte) { // Si está cargando, no mostrar nada aún
        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}>
          <SeleccionaReporteMovimientoBobinas
            onGenerarReporte={handleGenerarReporte}
            onCancel={handleVolverAParametros}
            isLoading={loading}
            apiErrorMessage={apiErrorParams} // Pasar el error del selector
          />
        </Paper>
      </Box>
    );
  }

  // Si ya pasó el selector y no tiene permiso (ej. cambio de roles mientras ve la pantalla)
  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>
      );
  }

  return (
    <Box sx={{ p: 2 }}>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2, flexWrap: 'wrap', gap: 1 }}>
        <Typography variant="h5">Reporte: Movimiento de Bobinas {currentParams?.nombrePlanta ? `(${currentParams.nombrePlanta})` : ''}</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 }}>
          <DataGrid
            rows={rows}
            columns={columns}
            localeText={esES.components.MuiDataGrid.defaultProps.localeText}
            slots={{ footer: CustomFooter }}
            density="compact"
            autoHeight // Para que se ajuste al contenido y al footer
            hideFooterSelectedRowCount
            disableRowSelectionOnClick
          />
        </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 ReporteMovimientoBobinasPage;