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 { MovimientoBobinasPorEstadoResponseDto } from '../../models/dtos/Reportes/MovimientoBobinasPorEstadoResponseDto';
import type { MovimientoBobinaEstadoDetalleDto } from '../../models/dtos/Reportes/MovimientoBobinaEstadoDetalleDto';
import type { MovimientoBobinaEstadoTotalDto } from '../../models/dtos/Reportes/MovimientoBobinaEstadoTotalDto';
import { usePermissions } from '../../hooks/usePermissions';
import SeleccionaReporteMovimientoBobinasEstado from './SeleccionaReporteMovimientoBobinasEstado';
import * as XLSX from 'xlsx';
import axios from 'axios';

// Interfaces extendidas para DataGrid con 'id'
interface DetalleMovimientoDataGrid extends MovimientoBobinaEstadoDetalleDto {
  id: string;
}
interface TotalPorEstadoDataGrid extends MovimientoBobinaEstadoTotalDto {
  id: string;
}

const ReporteMovimientoBobinasEstadoPage: React.FC = () => {
  const [reportData, setReportData] = useState<MovimientoBobinasPorEstadoResponseDto | 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;
    idPlanta: number;
    nombrePlanta?: string;
  } | null>(null);
  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR006");

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

  const dateLocaleFormatter = (value: string | null | undefined) =>
    value ? new Date(value).toLocaleDateString('es-AR', { timeZone: 'UTC' }) : '-';


  const handleGenerarReporte = useCallback(async (params: {
    fechaDesde: string;
    fechaHasta: string;
    idPlanta: number;
  }) => {
    if (!puedeVerReporte) {
      setError("No tiene permiso para generar este reporte.");
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    setApiErrorParams(null);
    setCurrentParams(params);
    try {
      const data = await reportesService.getMovimientoBobinasEstado(params);

      const processedData: MovimientoBobinasPorEstadoResponseDto = {
        detalle: data.detalle?.map((item, index) => ({ ...item, id: `detalle-${index}-${item.numeroRemito}-${item.tipoBobina}` })) || [],
        totales: data.totales?.map((item, index) => ({ ...item, id: `total-${index}-${item.tipoMovimiento}` })) || []
      };
      setReportData(processedData);

      if ((!processedData.detalle || processedData.detalle.length === 0) && (!processedData.totales || processedData.totales.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);
      setReportData(null);
    } finally {
      setLoading(false);
    }
  }, []);

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

  const handleExportToExcel = useCallback(() => {
    if (!reportData || (!reportData.detalle?.length && !reportData.totales?.length)) {
      alert("No hay datos para exportar.");
      return;
    }

    const wb = XLSX.utils.book_new();

    if (reportData.detalle?.length) {
      const detalleToExport = reportData.detalle.map(item => ({
        "Tipo Bobina": item.tipoBobina,
        "Nro Remito": item.numeroRemito,
        "Fecha Movimiento": item.fechaMovimiento ? new Date(item.fechaMovimiento).toLocaleDateString('es-AR', { timeZone: 'UTC' }) : '-',
        "Cantidad": item.cantidad,
        "Tipo Movimiento": item.tipoMovimiento,
      }));
      const wsDetalle = XLSX.utils.json_to_sheet(detalleToExport);
      const headersDetalle = Object.keys(detalleToExport[0] || {});
      wsDetalle['!cols'] = headersDetalle.map(h => ({ wch: Math.max(...detalleToExport.map(row => (row as any)[h]?.toString().length ?? 0), h.length) + 2 }));
      wsDetalle['!freeze'] = { xSplit: 0, ySplit: 1 };
      XLSX.utils.book_append_sheet(wb, wsDetalle, "DetalleMovimientos");
    }

    if (reportData.totales?.length) {
      const totalesToExport = reportData.totales.map(item => ({
        "Tipo Movimiento": item.tipoMovimiento,
        "Total Bobinas": item.totalBobinas,
        "Total Kilos": item.totalKilos,
      }));
      const wsTotales = XLSX.utils.json_to_sheet(totalesToExport);
      const headersTotales = Object.keys(totalesToExport[0] || {});
      wsTotales['!cols'] = headersTotales.map(h => ({ wch: Math.max(...totalesToExport.map(row => (row as any)[h]?.toString().length ?? 0), h.length) + 2 }));
      wsTotales['!freeze'] = { xSplit: 0, ySplit: 1 };
      XLSX.utils.book_append_sheet(wb, wsTotales, "TotalesPorEstado");
    }

    let fileName = "ReporteMovimientoBobinasEstado";
    if (currentParams) {
      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.getMovimientoBobinasEstadoPdf(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]);

  // Columnas para DataGrid de Detalle de Movimientos
  const columnsDetalle: GridColDef<DetalleMovimientoDataGrid>[] = [ // Tipar con la interfaz correcta
    { field: 'tipoBobina', headerName: 'Tipo Bobina', width: 220, flex: 1.5 },
    { field: 'numeroRemito', headerName: 'Nro Remito', width: 130, flex: 0.8 },
    { field: 'fechaMovimiento', headerName: 'Fecha Movimiento', width: 150, flex: 1, valueFormatter: (value) => dateLocaleFormatter(value as string) },
    { field: 'cantidad', headerName: 'Cantidad', type: 'number', width: 120, align: 'right', headerAlign: 'right', flex: 0.7, valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'tipoMovimiento', headerName: 'Tipo Movimiento', width: 150, flex: 1 },
  ];

  // Columnas para DataGrid de Totales por Estado
  const columnsTotales: GridColDef<TotalPorEstadoDataGrid>[] = [ // Tipar con la interfaz correcta
    { field: 'tipoMovimiento', headerName: 'Tipo Movimiento', width: 200, flex: 1 },
    { field: 'totalBobinas', headerName: 'Total Bobinas', type: 'number', width: 150, align: 'right', headerAlign: 'right', flex: 0.8, valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
    { field: 'totalKilos', headerName: 'Total Kilos', type: 'number', width: 150, align: 'right', headerAlign: 'right', flex: 0.8, valueFormatter: (value) => numberLocaleFormatter(Number(value)) },
  ];

  const rowsDetalle = useMemo(() => (reportData?.detalle as DetalleMovimientoDataGrid[]) || [], [reportData]);
  const rowsTotales = useMemo(() => (reportData?.totales as TotalPorEstadoDataGrid[]) || [], [reportData]);

  // eslint-disable-next-line react/display-name
  const CustomFooterDetalle = () => (
    <GridFooterContainer sx={{
      display: 'flex',
      justifyContent: 'space-between',
      alignItems: 'center',
      width: '100%',
      borderTop: (theme) => `1px solid ${theme.palette.divider}`,
      minHeight: '52px',
    }}>
      <Box sx={{
        flexGrow: 1,
        display: 'flex',
        justifyContent: 'flex-start',
      }}>
        <GridFooter
          sx={{
            borderTop: 'none',
            width: 'auto',
            '& .MuiToolbar-root': {
              paddingLeft: (theme) => theme.spacing(1),
              paddingRight: (theme) => theme.spacing(1),
            },
            '& .MuiDataGrid-selectedRowCount': { display: 'none' },
          }}
        />
      </Box>
    </GridFooterContainer>
  );


  if (showParamSelector) {
    if (!loading && !puedeVerReporte) { // Si no tiene permiso Y no está cargando, muestra error
      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}>
          <SeleccionaReporteMovimientoBobinasEstado
            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: Movimiento de Bobinas por Estado {currentParams?.nombrePlanta ? `(${currentParams.nombrePlanta})` : ''}</Typography>
        <Box sx={{ display: 'flex', gap: 1 }}>
          <Button
            onClick={handleGenerarYAbrirPdf}
            variant="contained"
            disabled={loadingPdf || !reportData || (!reportData.detalle?.length && !reportData.totales?.length) || !!error}
            size="small"
          >
            {loadingPdf ? <CircularProgress size={20} color="inherit" /> : "Abrir PDF"}
          </Button>
          <Button
            onClick={handleExportToExcel}
            variant="outlined"
            disabled={!reportData || (!reportData.detalle?.length && !reportData.totales?.length) || !!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 && (
        <>
          <Typography variant="h6" gutterBottom sx={{ mt: 3 }}>
            Detalle de Movimientos
          </Typography>
          {rowsDetalle.length > 0 ? (
            <Paper sx={{ width: '100%', mb: 3 }}>
              <DataGrid
                rows={rowsDetalle}
                columns={columnsDetalle}
                localeText={esES.components.MuiDataGrid.defaultProps.localeText}
                density="compact"
                sx={{ height: 'calc(100vh - 350px)' }}
                slots={{ footer: CustomFooterDetalle }}

              />
            </Paper>
          ) : (
            <Typography sx={{ mb: 3, fontStyle: 'italic' }}>No hay detalles de movimientos para mostrar.</Typography>
          )}

          <Typography variant="h6" gutterBottom sx={{ mt: 3 }}>
            Totales por Estado
          </Typography>
          {rowsTotales.length > 0 ? (
            <Paper sx={{ width: '100%', maxWidth: '700px' }}>
              <DataGrid
                rows={rowsTotales}
                columns={columnsTotales}
                localeText={esES.components.MuiDataGrid.defaultProps.localeText}
                density="compact"
                autoHeight
                hideFooter
                disableRowSelectionOnClick
              />
            </Paper>
          ) : (
            <Typography sx={{ fontStyle: 'italic' }}>No hay totales por estado para mostrar.</Typography>
          )}
        </>
      )}
      {!loading && !error && !reportData && currentParams && (<Typography sx={{ mt: 2, fontStyle: 'italic' }}>No se encontraron datos para los criterios seleccionados.</Typography>)}
    </Box>
  );
};

export default ReporteMovimientoBobinasEstadoPage;