import React, { useState, useEffect, useCallback } from 'react';
import {
  Box, Typography, Paper, IconButton, MenuItem,
  Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination,
  CircularProgress, Alert, FormControl, InputLabel, Select
} from '@mui/material';
import FilterListIcon from '@mui/icons-material/FilterList';
import EditNoteIcon from '@mui/icons-material/EditNote'; // Icono para ajustar saldo

import saldoService from '../../services/Contables/saldoService';
import empresaService from '../../services/Distribucion/empresaService';
import distribuidorService from '../../services/Distribucion/distribuidorService';
import canillaService from '../../services/Distribucion/canillaService';

import type { SaldoGestionDto } from '../../models/dtos/Contables/SaldoGestionDto';
import type { AjusteSaldoRequestDto } from '../../models/dtos/Contables/AjusteSaldoRequestDto';
import type { EmpresaDto } from '../../models/dtos/Distribucion/EmpresaDto';
import type { DistribuidorDto } from '../../models/dtos/Distribucion/DistribuidorDto';
import type { CanillaDto } from '../../models/dtos/Distribucion/CanillaDto';

import AjusteSaldoModal from '../../components/Modals/Contables/AjusteSaldoModal';
import { usePermissions } from '../../hooks/usePermissions';
import { parseApiError } from '../../utils/apiErrorParser';

type TipoDestinoFiltro = 'Distribuidores' | 'Canillas' | '';

const GestionarSaldosPage: React.FC = () => {
  const [saldos, setSaldos] = useState<SaldoGestionDto[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [apiErrorMessage, setApiErrorMessage] = useState<string | null>(null); // Para modal

  // Filtros
  const [filtroTipoDestino, setFiltroTipoDestino] = useState<TipoDestinoFiltro>('');
  const [filtroIdDestino, setFiltroIdDestino] = useState<number | string>('');
  const [filtroIdEmpresa, setFiltroIdEmpresa] = useState<number | string>('');

  const [destinatariosDropdown, setDestinatariosDropdown] = useState<(DistribuidorDto | CanillaDto)[]>([]);
  const [empresas, setEmpresas] = useState<EmpresaDto[]>([]);
  const [loadingFiltersDropdown, setLoadingFiltersDropdown] = useState(false);

  const [modalAjusteOpen, setModalAjusteOpen] = useState(false);
  const [saldoParaAjustar, setSaldoParaAjustar] = useState<SaldoGestionDto | null>(null);

  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(25);
  // No necesitamos menú de acciones por fila si el ajuste es la única acción

  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVerSaldos = isSuperAdmin || tienePermiso("CS001"); // Permiso para ver
  const puedeAjustarSaldos = isSuperAdmin; // Ajuste manual: exclusivo SuperAdmin (no se valida CS002)


  const fetchDropdownData = useCallback(async () => {
    setLoadingFiltersDropdown(true);
    setError(null);
    try {
        const empData = await empresaService.getAllEmpresas();
        setEmpresas(empData);

        if (filtroTipoDestino === 'Distribuidores') {
            const distData = await distribuidorService.getAllDistribuidores();
            setDestinatariosDropdown(distData);
        } else if (filtroTipoDestino === 'Canillas') {
            const canData = await canillaService.getAllCanillas(undefined, undefined, true); // Solo activos
            setDestinatariosDropdown(canData);
        } else {
            setDestinatariosDropdown([]);
        }
    } catch (err) {
      console.error("Error cargando datos para filtros:", err);
      setError("Error al cargar opciones de filtro.");
    } finally {
      setLoadingFiltersDropdown(false);
    }
  }, [filtroTipoDestino]);

  useEffect(() => {
    fetchDropdownData();
  }, [fetchDropdownData]);


  const cargarSaldos = useCallback(async () => {
    if (!puedeVerSaldos) {
      setError("No tiene permiso para ver saldos."); setLoading(false); return;
    }
    setLoading(true); setError(null); setApiErrorMessage(null);
    try {
      const params = {
        destino: filtroTipoDestino || undefined, // Enviar undefined si está vacío
        idDestino: filtroIdDestino ? Number(filtroIdDestino) : undefined,
        idEmpresa: filtroIdEmpresa ? Number(filtroIdEmpresa) : undefined,
      };
      const data = await saldoService.getAllSaldosGestion(params);
      setSaldos(data);
    } catch (err) {
      console.error("Error al cargar saldos:", err);
      setError('Error al cargar los saldos.');
      setSaldos([]);
    } finally {
      setLoading(false);
    }
  }, [puedeVerSaldos, filtroTipoDestino, filtroIdDestino, filtroIdEmpresa]);

  useEffect(() => {
    cargarSaldos();
  }, [cargarSaldos]);


  const handleOpenAjusteModal = (saldo: SaldoGestionDto) => {
    if (!puedeAjustarSaldos) {
        setApiErrorMessage("No tiene permiso para ajustar saldos.");
        return;
    }
    setSaldoParaAjustar(saldo);
    setApiErrorMessage(null);
    setModalAjusteOpen(true);
  };
  const handleCloseAjusteModal = () => {
    setModalAjusteOpen(false);
    setSaldoParaAjustar(null);
  };

  const handleSubmitAjusteModal = async (data: AjusteSaldoRequestDto) => {
    if (!puedeAjustarSaldos) return;
    setApiErrorMessage(null);
    try {
      await saldoService.ajustarSaldo(data);
      cargarSaldos(); // Recargar lista para ver el saldo actualizado
    } catch (err: any) {
      const { message } = parseApiError(err, 'Error al aplicar el ajuste de saldo.');
      setApiErrorMessage(message);
      throw err; // Para que el modal sepa que hubo error
    }
  };


  const handleChangePage = (_event: unknown, newPage: number) => setPage(newPage);
  const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
    setRowsPerPage(parseInt(event.target.value, 10)); setPage(0);
  };
  
  const displayData = saldos.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
  const formatDate = (dateString?: string | null) => dateString ? new Date(dateString).toLocaleString('es-AR', {timeZone:'UTC'}) : '-';
  const formatCurrency = (value: number) => value.toLocaleString('es-AR', { style: 'currency', currency: 'ARS' });


  if (!loading && !puedeVerSaldos) {
      return <Box sx={{ p: 2 }}><Alert severity="error">{error || "Acceso denegado a esta sección."}</Alert></Box>;
  }

  return (
    <Box sx={{ p: 1 }}>
      <Typography variant="h5" gutterBottom>Gestión de Saldos</Typography>
      <Paper sx={{ p: 2, mb: 2 }}>
        <Typography variant="h6" gutterBottom>Filtros <FilterListIcon fontSize="small" /></Typography>
        <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, alignItems: 'center', mb: 2 }}>
            <FormControl size="small" sx={{ minWidth: 180, flexGrow: 1 }}>
                <InputLabel>Tipo Destinatario</InputLabel>
                <Select value={filtroTipoDestino} label="Tipo Destinatario" 
                    onChange={(e) => {
                        setFiltroTipoDestino(e.target.value as TipoDestinoFiltro);
                        setFiltroIdDestino(''); // Resetear destinatario al cambiar tipo
                    }}>
                    <MenuItem value=""><em>Todos</em></MenuItem>
                    <MenuItem value="Distribuidores">Distribuidores</MenuItem>
                    <MenuItem value="Canillas">Canillitas</MenuItem>
                </Select>
            </FormControl>
            <FormControl size="small" sx={{ minWidth: 220, flexGrow: 1 }} disabled={loadingFiltersDropdown || !filtroTipoDestino}>
                <InputLabel>Destinatario Específico</InputLabel>
                <Select value={filtroIdDestino} label="Destinatario Específico" 
                    onChange={(e) => setFiltroIdDestino(e.target.value as number | string)}>
                    <MenuItem value=""><em>Todos</em></MenuItem>
                    {destinatariosDropdown.map(d => (
                        <MenuItem key={'idDistribuidor' in d ? d.idDistribuidor : d.idCanilla} value={'idDistribuidor' in d ? d.idDistribuidor : d.idCanilla}>
                            {'nomApe' in d ? d.nomApe : d.nombre}
                        </MenuItem>
                    ))}
                </Select>
            </FormControl>
            <FormControl size="small" sx={{ minWidth: 200, flexGrow: 1 }} disabled={loadingFiltersDropdown}>
                <InputLabel>Empresa</InputLabel>
                <Select value={filtroIdEmpresa} label="Empresa" 
                    onChange={(e) => setFiltroIdEmpresa(e.target.value as number | string)}>
                    <MenuItem value=""><em>Todas</em></MenuItem>
                    {empresas.map(e => <MenuItem key={e.idEmpresa} value={e.idEmpresa}>{e.nombre}</MenuItem>)}
                </Select>
            </FormControl>
        </Box>
        {/* No hay botón de "Agregar Saldo", se crean automáticamente */}
      </Paper>

      {loading && <Box sx={{ display: 'flex', justifyContent: 'center', my: 2 }}><CircularProgress /></Box>}
      {error && !loading && !apiErrorMessage && <Alert severity="error" sx={{ my: 2 }}>{error}</Alert>}
      {apiErrorMessage && <Alert severity="error" sx={{ my: 2 }}>{apiErrorMessage}</Alert>}

      {!loading && !error && puedeVerSaldos && (
         <TableContainer component={Paper}>
           <Table size="small">
             <TableHead><TableRow>
                 <TableCell sx={{fontWeight:'bold'}}>Destinatario</TableCell>
                 <TableCell sx={{fontWeight:'bold'}}>Tipo</TableCell>
                 <TableCell sx={{fontWeight:'bold'}}>Empresa</TableCell>
                 <TableCell align="right" sx={{fontWeight:'bold'}}>Monto Saldo</TableCell>
                 <TableCell sx={{fontWeight:'bold'}}>Últ. Modificación</TableCell>
                 {puedeAjustarSaldos && <TableCell align="right" sx={{fontWeight:'bold'}}>Acciones</TableCell>}
             </TableRow></TableHead>
             <TableBody>
               {displayData.length === 0 ? (
                  <TableRow><TableCell colSpan={puedeAjustarSaldos ? 6 : 5} align="center">No se encontraron saldos.</TableCell></TableRow>
               ) : (
                 displayData.map((s) => (
                     <TableRow key={s.idSaldo} hover
                        sx={{ backgroundColor: s.monto < 0 ? 'rgba(255, 0, 0, 0.05)' : (s.monto > 0 ? 'rgba(0, 255, 0, 0.05)' : 'inherit')}}
                     >
                        <TableCell>{s.nombreDestinatario}</TableCell>
                        <TableCell>{s.destino}</TableCell>
                        <TableCell>{s.nombreEmpresa}</TableCell>
                        <TableCell align="right" sx={{fontWeight:500}}>{formatCurrency(s.monto)}</TableCell>
                        <TableCell>{formatDate(s.fechaUltimaModificacion)}</TableCell>
                        {puedeAjustarSaldos && (
                            <TableCell align="right">
                                <IconButton size="small" onClick={() => handleOpenAjusteModal(s)} color="primary">
                                    <EditNoteIcon fontSize="small"/>
                                </IconButton>
                            </TableCell>
                        )}
                     </TableRow>
                 )))}
             </TableBody>
           </Table>
           <TablePagination
             rowsPerPageOptions={[25, 50, 100]} component="div" count={saldos.length}
             rowsPerPage={rowsPerPage} page={page} onPageChange={handleChangePage}
             onRowsPerPageChange={handleChangeRowsPerPage} labelRowsPerPage="Filas por página:"
           />
         </TableContainer>
       )}

      {saldoParaAjustar &&
        <AjusteSaldoModal
            open={modalAjusteOpen}
            onClose={handleCloseAjusteModal}
            onSubmit={handleSubmitAjusteModal}
            saldoParaAjustar={saldoParaAjustar}
            errorMessage={apiErrorMessage}
            clearErrorMessage={() => setApiErrorMessage(null)}
        />
      }
    </Box>
  );
};

export default GestionarSaldosPage;