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

const ReporteExistenciaPapelPage: React.FC = () => {
  const [reportData, setReportData] = useState<ExistenciaPapelDto[]>([]);
  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 { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR005");
  const [currentParams, setCurrentParams] = useState<{
    fechaDesde: string;
    fechaHasta: string;
    idPlanta?: number | null;
    consolidado: boolean;
  } | null>(null);

  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); // Asegurarse que loading no quede en true
      return;
    }
    setLoading(true);
    setError(null);
    setApiErrorParams(null);
    setCurrentParams(params);
    try {
      const data = await reportesService.getExistenciaPapel(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);
      setReportData([]);
    } 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;
    }

    // 1) Data inicial formateada
    const dataToExport: Record<string, any>[] = reportData.map(item => {
      let fechaString = '-';
      if (item.fechaEstimacionFinStock) {
        const d = new Date(item.fechaEstimacionFinStock);
        if (!isNaN(d.getTime())) {
          fechaString = d.toLocaleDateString('es-AR', { timeZone: 'UTC' });
        }
      }
      return {
        "Tipo Bobina": item.tipoBobina,
        "Bobinas Stock": item.bobinasEnStock ?? 0,
        "Kg Stock": item.totalKilosEnStock ?? 0,
        "Consumo Acum. (Kg)": item.consumoAcumulado ?? 0,
        "Días Disp. (Prom.)": item.promedioDiasDisponibles != null
          ? Math.round(item.promedioDiasDisponibles)
          : '-',
        "Fecha Est. Fin Stock": fechaString,
      };
    });

    // 2) Cálculo de totales
    const totales = dataToExport.reduce(
      (acc, row) => {
        acc.bobinas += Number(row["Bobinas Stock"]);
        acc.kilos += Number(row["Kg Stock"]);
        acc.consumo += Number(row["Consumo Acum. (Kg)"]);
        return acc;
      },
      { bobinas: 0, kilos: 0, consumo: 0 }
    );

    // 3) Insertamos la fila de totales
    dataToExport.push({
      "Tipo Bobina": "Totales",
      "Bobinas Stock": totales.bobinas,
      "Kg Stock": totales.kilos,
      "Consumo Acum. (Kg)": totales.consumo,
      "Días Disp. (Prom.)": '-',            // o lo que prefieras
      "Fecha Est. Fin Stock": '-'           // vacío o guión
    });

    // 4) Creamos la hoja
    const ws = XLSX.utils.json_to_sheet(dataToExport);

    // 5) Auto‐anchos
    const headers = Object.keys(dataToExport[0]);
    ws['!cols'] = headers.map(h => {
      const maxLen = dataToExport.reduce((prev, row) => {
        const cell = row[h]?.toString() ?? '';
        return Math.max(prev, cell.length);
      }, h.length);
      return { wch: maxLen + 2 };
    });

    // 6) Congelamos la primera fila
    ws['!freeze'] = { xSplit: 0, ySplit: 1 };

    // 7) Libro y guardado
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "ExistenciaPapel");

    let fileName = "ReporteExistenciaPapel";
    if (currentParams) {
      fileName += `_${currentParams.fechaDesde}_a_${currentParams.fechaHasta}`;
      if (currentParams.consolidado) fileName += "_Consolidado";
      else if (currentParams.idPlanta) fileName += `_Planta${currentParams.idPlanta}`;
    }
    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.getExistenciaPapelPdf(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]);

  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}>
          <SeleccionaReporteExistenciaPapel
            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: Existencia de Papel</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 && (
        <TableContainer component={Paper} sx={{ maxHeight: 'calc(100vh - 240px)' }}>
          <Table stickyHeader size="small">
            <TableHead>
              <TableRow>
                <TableCell>Tipo Bobina</TableCell>
                <TableCell align="right">Cant. Stock</TableCell>
                <TableCell align="right">Kg. Stock</TableCell>
                <TableCell align="right">Consumo Acum. (Kg)</TableCell>
                <TableCell align="right">Días Disp. (Prom.)</TableCell>
                <TableCell>Fecha Est. Fin Stock</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {reportData.map((row, idx) => {
                const d = row.fechaEstimacionFinStock ? new Date(row.fechaEstimacionFinStock) : null;
                const fechaFmt = d && !isNaN(d.getTime())
                  ? d.toLocaleDateString('es-AR', { timeZone: 'UTC' })
                  : '-';
                return (
                  <TableRow key={row.tipoBobina + idx}>
                    <TableCell>{row.tipoBobina}</TableCell>
                    <TableCell align="right">{row.bobinasEnStock?.toLocaleString('es-AR') ?? '-'}</TableCell>
                    <TableCell align="right">{row.totalKilosEnStock?.toLocaleString('es-AR') ?? '-'}</TableCell>
                    <TableCell align="right">{row.consumoAcumulado?.toLocaleString('es-AR') ?? '-'}</TableCell>
                    <TableCell align="right">{row.promedioDiasDisponibles != null ? Math.round(row.promedioDiasDisponibles).toLocaleString('es-AR') : '-'}</TableCell>
                    <TableCell>{fechaFmt}</TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </TableContainer>
      )}
    </Box>
  );
};

export default ReporteExistenciaPapelPage;