import React, { useState, useCallback, useMemo } from 'react';
import { Box, Typography, Paper, CircularProgress, Alert, Button, Divider, type SxProps, type Theme } from '@mui/material';
// No necesitaremos DataGrid para la estructura principal, solo para el detalle si se decide mostrar.
import reportesService from '../../services/Reportes/reportesService';
import type { ControlDevolucionesDataResponseDto } from '../../models/dtos/Reportes/ControlDevolucionesDataResponseDto';
import SeleccionaReporteControlDevoluciones from './SeleccionaReporteControlDevoluciones';
import { usePermissions } from '../../hooks/usePermissions';
import * as XLSX from 'xlsx';
import axios from 'axios';


const ReporteControlDevolucionesPage: React.FC = () => {
  const [reportData, setReportData] = useState<ControlDevolucionesDataResponseDto | 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<{ fecha: string; idEmpresa: number; nombreEmpresa?: string } | null>(null);
  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerReporte = isSuperAdmin || tienePermiso("RR003");

  const numberLocaleFormatter = (value: number | null | undefined, showSign = false): string => {
    if (value == null) return '';
    const formatted = Number(value).toLocaleString('es-AR');
    if (showSign && value > 0 && value !== 0) return `+${formatted}`;
    return formatted;
  };

  const handleGenerarReporte = useCallback(async (params: { fecha: string; idEmpresa: number }) => {
    if (!puedeVerReporte) {
      setError("No tiene permiso para generar este reporte.");
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    setApiErrorParams(null);
    setReportData(null);

    const empresaService = (await import('../../services/Distribucion/empresaService')).default;
    const empData = await empresaService.getEmpresaById(params.idEmpresa);
    setCurrentParams({ ...params, nombreEmpresa: empData?.nombre });

    try {
      const data = await reportesService.getControlDevolucionesData(params);
      setReportData(data);

      if (data.detallesCtrlDevoluciones.length === 0 &&
        data.devolucionesOtrosDias.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(null);
    setError(null);
    setApiErrorParams(null);
    setCurrentParams(null);
  }, []);

  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.getControlDevolucionesPdf(currentParams);
      if (blob.type === "application/json") { // Error devuelto como 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("Permita popups para ver el PDF.")
      }
    } catch (err) {
      setError('Ocurrió un error al generar el PDF.');
    } finally {
      setLoadingPdf(false);
    }
  }, [currentParams]);

  // Cálculos para la visualización estilo PDF
  const calculatedValues = useMemo(() => {
    // Comprobación más robusta al inicio
    if (!reportData || !reportData.detallesCtrlDevoluciones || reportData.detallesCtrlDevoluciones.length === 0) {
      // Si no hay detalles, pero sí hay devoluciones de otros días
      if (reportData?.devolucionesOtrosDias && reportData.devolucionesOtrosDias.length > 0) {
        const totalDevolucionOtrosDias = reportData.devolucionesOtrosDias.reduce((sum, item) => sum + item.devueltos, 0);
        return {
          ingresadosPorRemito: 0,
          cantidadCanillas: 0,
          llevadosAcc: 0, devueltosAcc: 0, totalAcc: 0,
          llevadosCan: 0, devueltosCan: 0, totalCan: 0,
          // sumLlevadosTotal: 0, // No es necesario devolverlos si no se usan directamente en UI
          // sumDevueltosTotal: 0,
          totalDevolucionFecha: 0,
          totalDevolucionOtrosDias,
          totalDevolucion: totalDevolucionOtrosDias,
          sinCargo: 0,
          sobrantes: 0,
          diferencia: totalDevolucionOtrosDias, // O 0 si se prefiere una diferencia nula
        };
      }
      return null; // Si no hay ningún dato relevante
    }

    const detalles = reportData.detallesCtrlDevoluciones;
    const primerDetalle = detalles[0];

    const ingresadosPorRemitoRDLC = primerDetalle.ingresados;
    const sobrantesRDLC = primerDetalle.sobrantes;
    const sinCargoRDLC = primerDetalle.sinCargo;
    const cantidadCanillas = primerDetalle.totalNoAccionistas;

    const sumLlevadosTotalRDLC = detalles.reduce((sum, item) => sum + item.llevados, 0);
    const sumDevueltosTotalRDLC = detalles.reduce((sum, item) => sum + item.devueltos, 0);

    const accionistasDetalle = detalles.find(d => d.tipo?.toLowerCase() === 'accionistas');
    const llevadosAcc = accionistasDetalle?.llevados || 0;
    const devueltosAcc = accionistasDetalle?.devueltos || 0;
    const totalAcc = llevadosAcc - devueltosAcc;

    const canillitasDetalle = detalles.find(d => d.tipo?.toLowerCase() === 'canillitas');
    const llevadosCan = canillitasDetalle?.llevados || 0;
    const devueltosCan = canillitasDetalle?.devueltos || 0;
    const totalCan = llevadosCan - devueltosCan;

    const totalDevolucionFechaRDLC = ingresadosPorRemitoRDLC - sumLlevadosTotalRDLC + sumDevueltosTotalRDLC;

    // Usar encadenamiento opcional y valor por defecto para devolucionesOtrosDias
    const totalDevolucionOtrosDiasRDLC = reportData.devolucionesOtrosDias?.reduce((sum, item) => sum + item.devueltos, 0) || 0;

    const totalDevolucionRDLC = totalDevolucionFechaRDLC + totalDevolucionOtrosDiasRDLC;

    // Fórmula de diferencia del RDLC
    const diferencia = ingresadosPorRemitoRDLC - sumLlevadosTotalRDLC + sumDevueltosTotalRDLC - sobrantesRDLC - sinCargoRDLC;

    return {
      ingresadosPorRemito: ingresadosPorRemitoRDLC,
      cantidadCanillas,
      llevadosAcc, devueltosAcc, totalAcc,
      llevadosCan, devueltosCan, totalCan,
      totalDevolucionFecha: totalDevolucionFechaRDLC,
      totalDevolucionOtrosDias: totalDevolucionOtrosDiasRDLC,
      totalDevolucion: totalDevolucionRDLC,
      sinCargo: sinCargoRDLC,
      sobrantes: sobrantesRDLC,
      diferencia, // Usar la variable 'diferencia' que contiene el cálculo correcto
    };
  }, [reportData]);

  const handleExportToExcel = useCallback(() => {
    if (!reportData || !calculatedValues || !currentParams) {
      alert("No hay datos para exportar.");
      return;
    }

    const dataForExcel: any[][] = [];

    // --- Títulos y Cabecera ---
    dataForExcel.push(["Control de Devoluciones"]); // Título Principal
    dataForExcel.push(["Canillas / Accionistas"]);   // Subtítulo
    dataForExcel.push([]); // Fila vacía para espaciado

    dataForExcel.push([
      `Fecha Consultada: ${currentParams.fecha ? new Date(currentParams.fecha + 'T00:00:00').toLocaleDateString('es-AR', { timeZone: 'UTC' }) : ''}`,
      "", // Celda vacía para espaciado o para alinear con la segunda columna si fuera necesario
      `Cantidad Canillas: ${calculatedValues.cantidadCanillas}`
    ]);
    dataForExcel.push([]);

    dataForExcel.push([currentParams.nombreEmpresa || 'EL DIA']); // Nombre de la Empresa/Publicación
    dataForExcel.push([]);

    // --- Cuerpo del Reporte ---
    dataForExcel.push(["Ingresados por Remito:", calculatedValues.ingresadosPorRemito]);
    dataForExcel.push(["----------------------------------", "-------------------"]); // Línea divisoria (estilo simple)

    dataForExcel.push(["Accionistas"]);
    dataForExcel.push(["Llevados", -calculatedValues.llevadosAcc]);
    dataForExcel.push(["Devueltos", calculatedValues.devueltosAcc]);
    dataForExcel.push(["Total", -calculatedValues.totalAcc]); // Fila de Total con estilo
    dataForExcel.push([]);

    dataForExcel.push(["Canillitas"]);
    dataForExcel.push(["Llevados", -calculatedValues.llevadosCan]);
    dataForExcel.push(["Devueltos", calculatedValues.devueltosCan]);
    dataForExcel.push(["Total", -calculatedValues.totalCan]); // Fila de Total con estilo
    dataForExcel.push(["==================================", "==================="]); // Línea divisoria sólida

    dataForExcel.push(["Total Devolución a la Fecha", calculatedValues.totalDevolucionFecha]);
    dataForExcel.push(["Total Devolución Días Anteriores", calculatedValues.totalDevolucionOtrosDias]);
    dataForExcel.push(["Total Devolución", calculatedValues.totalDevolucion]); // Fila de Total con estilo
    dataForExcel.push(["----------------------------------", "-------------------"]);

    dataForExcel.push(["Sin Cargo", calculatedValues.sinCargo]);
    dataForExcel.push(["Sobrantes", -calculatedValues.sobrantes]);
    dataForExcel.push(["Diferencia", calculatedValues.diferencia]); // Fila de Total con estilo

    // --- Crear Hoja y Libro ---
    const ws = XLSX.utils.aoa_to_sheet(dataForExcel);

    // Ajustar anchos de columna (opcional, pero recomendado)
    // Esto es un cálculo aproximado, puedes ajustarlo
    const colWidths = [
      { wch: 40 }, // Columna A (Etiquetas)
      { wch: 15 }, // Columna B (Valores)
      { wch: 25 }  // Columna C (para Cantidad Canillas)
    ];
    ws['!cols'] = colWidths;

    // Fusionar celdas para títulos (opcional, requiere más trabajo con la estructura de 'ws')
    // Ejemplo para el título principal (ocuparía A1:C1)
    if (!ws['!merges']) ws['!merges'] = [];
    ws['!merges'].push({ s: { r: 0, c: 0 }, e: { r: 0, c: 2 } }); // Fusionar A1 a C1
    ws['!merges'].push({ s: { r: 1, c: 0 }, e: { r: 1, c: 2 } }); // Fusionar A2 a C2
    ws['!merges'].push({ s: { r: 5, c: 0 }, e: { r: 5, c: 2 } }); // Fusionar celda de Nombre Empresa


    // Aplicar formato numérico (esto es más avanzado y depende de cómo quieras los números en Excel)
    // Por ahora, los números se exportarán como números si son de tipo number en dataForExcel.
    // Para formato de moneda o miles, tendrías que modificar las celdas en el objeto 'ws'
    // o asegurarte de que los valores en 'dataForExcel' ya estén como strings formateados si Excel no los interpreta bien.
    // Por simplicidad, los dejamos como números y Excel usará su formato por defecto.

    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "ControlDevoluciones");

    let fileName = "ReporteControlDevoluciones";
    fileName += `_${currentParams.nombreEmpresa?.replace(/\s+/g, '') ?? `Emp${currentParams.idEmpresa}`}`;
    fileName += `_${currentParams.fecha}`;
    fileName += ".xlsx";
    XLSX.writeFile(wb, fileName);

  }, [reportData, calculatedValues, currentParams]);




  // Componente para una fila del reporte usando Box con Flexbox
  interface ReportRowProps {
    label: string;
    value: string | number;
    boldValue?: boolean;
    valueAlign?: 'flex-start' | 'flex-end' | 'center'; // Para justifyContent del valor
    sx?: SxProps<Theme>;
    isTotalLine?: boolean; // Para la línea superior de los totales de Accionistas/Canillitas
  }

  const ReportRow: React.FC<ReportRowProps> =
    ({ label, value, boldValue = false, valueAlign = 'flex-end', sx, isTotalLine = false }) => (
      <Box
        sx={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          py: 0.3, // Padding vertical más ajustado
          ...(isTotalLine && { borderTop: '2px solid black', pt: 0.8, mt: 0.2 }),
          ...sx,
        }}
      >
        <Typography variant="body2" sx={{ flexGrow: 1, pr: 1 /* Espacio antes del valor */ }}>{label}</Typography>
        <Typography
          variant="body2"
          sx={{
            fontWeight: boldValue ? 'bold' : 'normal',
            textAlign: valueAlign === 'flex-start' ? 'left' : valueAlign === 'flex-end' ? 'right' : 'center',
            minWidth: '80px', // Para asegurar algo de espacio para el valor
          }}
        >
          {typeof value === 'number' ? numberLocaleFormatter(value) : value}
        </Typography>
      </Box>
    );

  // Componente para subcabeceras (como "Ingresados por Remito:")
  interface ReportSubHeaderProps {
    label: string;
    value: string | number;
    sx?: SxProps<Theme>;
  }
  const ReportSubHeader: React.FC<ReportSubHeaderProps> = ({ label, value, sx }) => (
    <Box
      sx={{
        display: 'flex',
        justifyContent: 'space-between',
        alignItems: 'center',
        py: 0.5,
        ...sx,
      }}
    >
      <Typography variant="body2" sx={{ fontWeight: 'bold', flexGrow: 1, pr: 1 }}>{label}</Typography>
      <Typography variant="body2" sx={{ fontWeight: 'bold', textAlign: 'right', minWidth: '80px' }}>
        {numberLocaleFormatter(Number(value))}
      </Typography>
    </Box>
  );

  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}>
          <SeleccionaReporteControlDevoluciones
            onGenerarReporte={handleGenerarReporte}
            isLoading={loading}
            apiErrorMessage={apiErrorParams}
          />
        </Paper>
      </Box>
    );
  }

  if (loading) return <Box sx={{ display: 'flex', justifyContent: 'center', my: 5 }}><CircularProgress /></Box>;
  if (error && !reportData) return <Alert severity="info" sx={{ m: 2 }}>{error}</Alert>;
  if (!reportData || !calculatedValues || !currentParams) return <Typography sx={{ m: 2, fontStyle: 'italic' }}>Seleccione parámetros para generar el reporte.</Typography>;


  return (
    <Box sx={{ p: 2 }}>
      <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2, flexWrap: 'wrap', gap: 1 }}>
        <Typography variant="h5">Control de Devoluciones</Typography>
        <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
          <Button onClick={handleGenerarYAbrirPdf} variant="contained" disabled={loadingPdf || !reportData || !!error} size="small">
            {loadingPdf ? <CircularProgress size={20} color="inherit" /> : "Abrir PDF"}
          </Button>
          <Button onClick={handleExportToExcel} variant="outlined" disabled={!reportData || !!error} size="small">
            Exportar a Excel
          </Button>
          <Button onClick={handleVolverAParametros} variant="outlined" color="secondary" size="small">
            Nuevos Parámetros
          </Button>
        </Box>
      </Box>
      <Typography variant="subtitle1" gutterBottom sx={{ textAlign: 'center', fontWeight: 'bold' }}>
        Canillas / Accionistas
      </Typography>

      <Paper sx={{ p: 2, maxWidth: 450, mx: 'auto' }}> {/* Ancho ligeramente reducido */}
        {/* Cabecera con Fecha y Cantidad Canillas */}
        <Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 1 }}>
          <Typography variant="body2">Fecha Consultada: <strong>{currentParams.fecha ? new Date(currentParams.fecha + 'T00:00:00').toLocaleDateString('es-AR', { timeZone: 'UTC' }) : ''}</strong></Typography>
          <Typography variant="body2">Cantidad Canillas: <strong>{calculatedValues.cantidadCanillas}</strong></Typography>
        </Box>

        <Typography variant="subtitle1" align="center" sx={{ my: 1, fontWeight: 'bold' }}>
          {currentParams.nombreEmpresa || 'EL DIA'}
        </Typography>

        <ReportSubHeader label="Ingresados por Remito:" value={calculatedValues.ingresadosPorRemito} />
        <Divider sx={{ my: 1, borderStyle: 'dashed', borderColor: 'grey.500' }} />

        <Typography variant="body2" sx={{ fontWeight: 'bold', mt: 1 }}>Accionistas</Typography>
        <ReportRow label="Llevados" value={-calculatedValues.llevadosAcc} />
        <ReportRow label="Devueltos" value={calculatedValues.devueltosAcc} />
        <ReportRow label="Total" value={-calculatedValues.totalAcc} boldValue isTotalLine />

        <Typography variant="body2" sx={{ fontWeight: 'bold', mt: 1.5 }}>Canillitas</Typography>
        <ReportRow label="Llevados" value={-calculatedValues.llevadosCan} />
        <ReportRow label="Devueltos" value={calculatedValues.devueltosCan} />
        <ReportRow label="Total" value={-calculatedValues.totalCan} boldValue isTotalLine />
        <Divider sx={{ my: 1, borderColor: 'grey.500' }} />

        <ReportRow label="Total Devolución a la Fecha" value={calculatedValues.totalDevolucionFecha} boldValue />
        <ReportRow label="Total Devolución Días Anteriores" value={calculatedValues.totalDevolucionOtrosDias} boldValue />
        <Box sx={{ borderTop: '1px solid black', pt: 0.5, mt: 0.5 }}> {/* Línea sólida para Total Devolución */}
          <ReportRow label="Total Devolución" value={calculatedValues.totalDevolucion} boldValue />
        </Box>
        <Divider sx={{ my: 1, borderStyle: 'dashed', borderColor: 'grey.500' }} />
        <ReportRow label="Sin Cargo" value={calculatedValues.sinCargo} boldValue />
        <ReportRow label="Sobrantes" value={-calculatedValues.sobrantes} boldValue />
        <Box sx={{ borderTop: '1px solid black', pt: 0.5, mt: 0.5 }}> {/* Línea sólida para Diferencia */}
          <ReportRow label="Diferencia" value={calculatedValues.diferencia} boldValue />
        </Box>
      </Paper>
    </Box>
  );
};

export default ReporteControlDevolucionesPage;