import React, { useState, useCallback } from 'react';
import {
  Box, Typography, Paper, CircularProgress, Alert, Button,
  TableContainer, Table, TableHead, TableRow, TableCell, TableBody, TableFooter
} from '@mui/material';
import reportesService from '../../services/Reportes/reportesService';
import type { ConsumoBobinasSeccionDto } from '../../models/dtos/Reportes/ConsumoBobinasSeccionDto';
import SeleccionaReporteConsumoBobinasSeccion from './SeleccionaReporteConsumoBobinasSeccion';
import { usePermissions } from '../../hooks/usePermissions';
import * as XLSX from 'xlsx';
import axios from 'axios';

// Helper para agrupar los datos
const groupData = (data: ConsumoBobinasSeccionDto[]) => {
  return data.reduce((acc, current) => {
    const pubKey = current.nombrePublicacion;
    if (!acc[pubKey]) {
      acc[pubKey] = {};
    }
    const secKey = current.nombreSeccion;
    if (!acc[pubKey][secKey]) {
      acc[pubKey][secKey] = [];
    }
    acc[pubKey][secKey].push(current);
    return acc;
  }, {} as Record<string, Record<string, ConsumoBobinasSeccionDto[]>>);
};


const ReporteConsumoBobinasSeccionPage: React.FC = () => {
  const [reportData, setReportData] = useState<ConsumoBobinasSeccionDto[]>([]);
  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;
    idPlanta?: number | null;
    consolidado: boolean;
    nombrePlanta?: string; // Para el PDF
  } | null>(null);
  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR007");

  const handleGenerarReporte = useCallback(async (params: {
    fechaDesde: string;
    fechaHasta: 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";
    }
    setCurrentParams({ ...params, nombrePlanta: plantaNombre });

    try {
      const data = await reportesService.getConsumoBobinasSeccion(params);
      setReportData(data);
      if (data.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;
    }
    // Mapeo plano para Excel, ya que el agrupamiento es más para visualización.
    const dataToExport = reportData.map(item => ({
      "Publicación": item.nombrePublicacion,
      "Sección": item.nombreSeccion,
      "Tipo Bobina": item.nombreBobina,
      "Cantidad Bobinas": item.cantidadBobinas,
      "Total Kilos": item.totalKilos,
    }));

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

    dataToExport.push({ // Fila de totales
      "Publicación": "TOTAL GENERAL",
      "Sección": "",
      "Tipo Bobina": "",
      "Cantidad Bobinas": totalGeneralBobinas,
      "Total Kilos": totalGeneralKilos,
    });


    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, "ConsumoBobinasSeccion");
    let fileName = "ReporteConsumoBobinasSeccion";
    if (currentParams) {
      fileName += `_${currentParams.consolidado ? 'Consolidado' : `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.getConsumoBobinasSeccionPdf(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 groupedData = reportData.length > 0 ? groupData(reportData) : {};
  const totalGeneralBobinas = reportData.reduce((sum, item) => sum + item.cantidadBobinas, 0);
  const totalGeneralKilos = reportData.reduce((sum, item) => sum + item.totalKilos, 0);

  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}>
          <SeleccionaReporteConsumoBobinasSeccion
            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 Secció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' }}><CircularProgress /></Box>}
      {error && !loading && <Alert severity="error" sx={{ my: 2 }}>{error}</Alert>}

      {!loading && !error && reportData.length > 0 && (
        <TableContainer component={Paper} sx={{ maxHeight: 'calc(100vh - 240px)' }}>
          <Table stickyHeader size="small">
            <TableHead>
              <TableRow>
                <TableCell sx={{ fontWeight: 'bold' }}>Publicación</TableCell>
                <TableCell sx={{ fontWeight: 'bold' }}>Sección</TableCell>
                <TableCell sx={{ fontWeight: 'bold' }}>Tipo Bobina</TableCell>
                <TableCell align="right" sx={{ fontWeight: 'bold' }}>Cant. Bobinas</TableCell>
                <TableCell align="right" sx={{ fontWeight: 'bold' }}>Total Kilos</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {Object.entries(groupedData).map(([pubKey, secciones]) => (
                <React.Fragment key={pubKey}>
                  <TableRow sx={{ backgroundColor: 'rgba(0, 0, 0, 0.08)' }}>
                    <TableCell colSpan={5} sx={{ fontWeight: 'bold' }}>{pubKey}</TableCell>
                  </TableRow>
                  {Object.entries(secciones).map(([secKey, bobinas]) => {
                    const totalBobinasSeccion = bobinas.reduce((sum, item) => sum + item.cantidadBobinas, 0);
                    const totalKilosSeccion = bobinas.reduce((sum, item) => sum + item.totalKilos, 0);
                    return (
                      <React.Fragment key={`${pubKey}-${secKey}`}>
                        <TableRow sx={{ backgroundColor: 'rgba(0, 0, 0, 0.04)' }}>
                          <TableCell></TableCell> {/* Columna Publicación vacía para esta fila */}
                          <TableCell colSpan={4} sx={{ fontWeight: 'bold' }}>{secKey}</TableCell>
                        </TableRow>
                        {bobinas.map((bob, bobIdx) => (
                          <TableRow key={`${pubKey}-${secKey}-${bobIdx}`}>
                            <TableCell></TableCell>
                            <TableCell></TableCell>
                            <TableCell>{bob.nombreBobina}</TableCell>
                            <TableCell align="right">{bob.cantidadBobinas.toLocaleString('es-AR')}</TableCell>
                            <TableCell align="right">{bob.totalKilos.toLocaleString('es-AR')}</TableCell>
                          </TableRow>
                        ))}
                        {/* Fila de totales por sección */}
                        <TableRow sx={{ backgroundColor: 'rgba(0, 0, 0, 0.02)' }}>
                          <TableCell colSpan={3} align="right" sx={{ fontWeight: 'bold', fontStyle: 'italic' }}>Total Sección ({secKey}):</TableCell>
                          <TableCell align="right" sx={{ fontWeight: 'bold', fontStyle: 'italic' }}>{totalBobinasSeccion.toLocaleString('es-AR')}</TableCell>
                          <TableCell align="right" sx={{ fontWeight: 'bold', fontStyle: 'italic' }}>{totalKilosSeccion.toLocaleString('es-AR')}</TableCell>
                        </TableRow>
                      </React.Fragment>
                    );
                  })}
                </React.Fragment>
              ))}
            </TableBody>
            <TableFooter>
              <TableRow sx={{ backgroundColor: 'grey.300' }}>
                <TableCell colSpan={3} align="right" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>TOTAL GENERAL:</TableCell>
                <TableCell align="right" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>{totalGeneralBobinas.toLocaleString('es-AR')}</TableCell>
                <TableCell align="right" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>{totalGeneralKilos.toLocaleString('es-AR')}</TableCell>
              </TableRow>
            </TableFooter>
          </Table>
        </TableContainer>
      )}
      {!loading && !error && reportData.length === 0 && (<Typography>No se encontraron datos para los criterios seleccionados.</Typography>)}
    </Box>
  );
};

export default ReporteConsumoBobinasSeccionPage;