import React, { useState, useEffect, useCallback } from 'react';
import {
    Box, Typography, TextField, Button, Paper, IconButton, Menu, MenuItem, Chip,
    Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination,
    CircularProgress, Alert, FormControl, InputLabel, Select, Tooltip
} from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import FilterListIcon from '@mui/icons-material/FilterList';

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

import type { NotaCreditoDebitoDto } from '../../models/dtos/Contables/NotaCreditoDebitoDto';
import type { CreateNotaDto } from '../../models/dtos/Contables/CreateNotaDto';
import type { UpdateNotaDto } from '../../models/dtos/Contables/UpdateNotaDto';
import type { DistribuidorDto } from '../../models/dtos/Distribucion/DistribuidorDto';
import type { CanillaDto } from '../../models/dtos/Distribucion/CanillaDto';
import type { EmpresaDto } from '../../models/dtos/Distribucion/EmpresaDto';

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

type DestinoFiltroType = 'Distribuidores' | 'Canillas' | '';
type TipoNotaFiltroType = 'Credito' | 'Debito' | '';

const GestionarNotasCDPage: React.FC = () => {
  const [notas, setNotas] = useState<NotaCreditoDebitoDto[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [apiErrorMessage, setApiErrorMessage] = useState<string | null>(null);

  // Filtros
  const [filtroFechaDesde, setFiltroFechaDesde] = useState<string>(new Date().toISOString().split('T')[0]); //useState('');
  const [filtroFechaHasta, setFiltroFechaHasta] = useState<string>(new Date().toISOString().split('T')[0]); //useState('');
  const [filtroDestino, setFiltroDestino] = useState<DestinoFiltroType>('');
  const [filtroIdDestinatario, setFiltroIdDestinatario] = useState<number | string>('');
  const [filtroIdEmpresa, setFiltroIdEmpresa] = useState<number | string>('');
  const [filtroTipoNota, setFiltroTipoNota] = useState<TipoNotaFiltroType>('');

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

  const [modalOpen, setModalOpen] = useState(false);
  const [editingNota, setEditingNota] = useState<NotaCreditoDebitoDto | null>(null);

  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(25);
  const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
  const [selectedRow, setSelectedRow] = useState<NotaCreditoDebitoDto | null>(null);

  const { tienePermiso, isSuperAdmin } = usePermissions();
  const puedeVer = isSuperAdmin || tienePermiso("CN001");
  const puedeCrear = isSuperAdmin || tienePermiso("CN002");
  const puedeModificar = isSuperAdmin || tienePermiso("CN003");
  const puedeEliminar = isSuperAdmin || tienePermiso("CN004");

  const fetchEmpresasParaFiltro = useCallback(async () => {
    setLoadingFiltersDropdown(true);
    try {
        const empData = await empresaService.getAllEmpresas();
        setEmpresas(empData);
    } catch (err) { console.error(err); setError("Error al cargar empresas.");
    } finally { setLoadingFiltersDropdown(false); }
  }, []);

  const fetchDestinatariosParaFiltro = useCallback(async (tipoDestino: DestinoFiltroType) => {
    if (!tipoDestino) { setDestinatariosFiltro([]); return; }
    setLoadingFiltersDropdown(true);
    setFiltroIdDestinatario(''); // Resetear selección de destinatario
    try {
        if (tipoDestino === 'Distribuidores') {
            const data = await distribuidorService.getAllDistribuidores();
            setDestinatariosFiltro(data);
        } else if (tipoDestino === 'Canillas') {
            const data = await canillaService.getAllCanillas(undefined, undefined, true);
            setDestinatariosFiltro(data);
        }
    } catch (err) { console.error(err); setError(`Error al cargar ${tipoDestino}.`);
    } finally { setLoadingFiltersDropdown(false); }
  }, []);

  useEffect(() => { fetchEmpresasParaFiltro(); }, [fetchEmpresasParaFiltro]);
  useEffect(() => { fetchDestinatariosParaFiltro(filtroDestino); }, [filtroDestino, fetchDestinatariosParaFiltro]);


  const cargarNotas = useCallback(async () => {
    if (!puedeVer) { setError("No tiene permiso."); setLoading(false); return; }
    setLoading(true); setError(null); setApiErrorMessage(null);
    try {
      const params = {
        fechaDesde: filtroFechaDesde || null, fechaHasta: filtroFechaHasta || null,
        destino: filtroDestino || null,
        idDestino: filtroIdDestinatario ? Number(filtroIdDestinatario) : null,
        idEmpresa: filtroIdEmpresa ? Number(filtroIdEmpresa) : null,
        tipoNota: filtroTipoNota || null,
      };
      const data = await notaCreditoDebitoService.getAllNotas(params);
      setNotas(data);
    } catch (err) { console.error(err); setError('Error al cargar las notas.');
    } finally { setLoading(false); }
  }, [puedeVer, filtroFechaDesde, filtroFechaHasta, filtroDestino, filtroIdDestinatario, filtroIdEmpresa, filtroTipoNota]);

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

  const handleOpenModal = (item?: NotaCreditoDebitoDto) => {
    setEditingNota(item || null); setApiErrorMessage(null); setModalOpen(true);
  };
  const handleCloseModal = () => { setModalOpen(false); setEditingNota(null); };

  const handleSubmitModal = async (data: CreateNotaDto | UpdateNotaDto, idNota?: number) => {
    setApiErrorMessage(null);
    try {
      if (idNota && editingNota) {
        await notaCreditoDebitoService.updateNota(idNota, data as UpdateNotaDto);
      } else {
        await notaCreditoDebitoService.createNota(data as CreateNotaDto);
      }
      cargarNotas();
    } catch (err: any) {
      const { message } = parseApiError(err, 'Error al guardar la nota.');
      setApiErrorMessage(message); throw err;
    }
  };

  const handleDelete = async (idNota: number) => {
    if (window.confirm(`¿Seguro de eliminar esta nota (ID: ${idNota})? Esta acción revertirá el impacto en el saldo.`)) {
       setApiErrorMessage(null);
       try { await notaCreditoDebitoService.deleteNota(idNota); cargarNotas(); }
       catch (err: any) { const { message } = parseApiError(err, 'Error al eliminar.'); setApiErrorMessage(message); }
    }
    handleMenuClose();
  };

  const handleMenuOpen = (event: React.MouseEvent<HTMLElement>, item: NotaCreditoDebitoDto) => {
    setAnchorEl(event.currentTarget); setSelectedRow(item);
  };
  const handleMenuClose = () => { setAnchorEl(null); setSelectedRow(null); };

  const handleChangePage = (_event: unknown, newPage: number) => setPage(newPage);
  const handleChangeRowsPerPage = (event: React.ChangeEvent<HTMLInputElement>) => {
    setRowsPerPage(parseInt(event.target.value, 10)); setPage(0);
  };
  const displayData = notas.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage);
  const formatDate = (dateString?: string | null) => dateString ? new Date(dateString + 'T00:00:00Z').toLocaleDateString('es-AR') : '-';

  if (!loading && !puedeVer && !loadingFiltersDropdown) return <Box sx={{ p: 2 }}><Alert severity="error">{error || "Acceso denegado."}</Alert></Box>;

  return (
    <Box sx={{ p: 1 }}>
      <Typography variant="h5" gutterBottom>Notas de Crédito/Débito</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}}>
            <TextField label="Fecha Desde" type="date" size="small" value={filtroFechaDesde} onChange={(e) => setFiltroFechaDesde(e.target.value)} InputLabelProps={{ shrink: true }} sx={{minWidth: 170}}/>
            <TextField label="Fecha Hasta" type="date" size="small" value={filtroFechaHasta} onChange={(e) => setFiltroFechaHasta(e.target.value)} InputLabelProps={{ shrink: true }} sx={{minWidth: 170}}/>
            <FormControl size="small" sx={{minWidth: 180, flexGrow: 1}}>
                <InputLabel>Empresa</InputLabel>
                <Select value={filtroIdEmpresa} label="Empresa" onChange={(e) => setFiltroIdEmpresa(e.target.value as number | string)} disabled={loadingFiltersDropdown}>
                    <MenuItem value=""><em>Todas</em></MenuItem>
                    {empresas.map(e => <MenuItem key={e.idEmpresa} value={e.idEmpresa}>{e.nombre}</MenuItem>)}
                </Select>
            </FormControl>
            <FormControl size="small" sx={{minWidth: 180, flexGrow: 1}}>
                <InputLabel>Tipo Destino</InputLabel>
                <Select value={filtroDestino} label="Tipo Destino" onChange={(e) => setFiltroDestino(e.target.value as DestinoFiltroType)}>
                    <MenuItem value=""><em>Todos</em></MenuItem>
                    <MenuItem value="Distribuidores">Distribuidores</MenuItem>
                    <MenuItem value="Canillas">Canillas</MenuItem>
                </Select>
            </FormControl>
            <FormControl size="small" sx={{minWidth: 200, flexGrow: 1}} disabled={loadingFiltersDropdown || !filtroDestino}>
                <InputLabel>Destinatario</InputLabel>
                <Select value={filtroIdDestinatario} label="Destinatario" onChange={(e) => setFiltroIdDestinatario(e.target.value as number | string)}>
                    <MenuItem value=""><em>Todos</em></MenuItem>
                    {destinatariosFiltro.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: 150, flexGrow: 1}}>
                <InputLabel>Tipo Nota</InputLabel>
                <Select value={filtroTipoNota} label="Tipo Nota" onChange={(e) => setFiltroTipoNota(e.target.value as TipoNotaFiltroType)}>
                    <MenuItem value=""><em>Ambas</em></MenuItem>
                    <MenuItem value="Credito">Crédito</MenuItem>
                    <MenuItem value="Debito">Débito</MenuItem>
                </Select>
            </FormControl>
         </Box>
         {puedeCrear && (<Button variant="contained" startIcon={<AddIcon />} onClick={() => handleOpenModal()}>Registrar Nota</Button>)}
      </Paper>

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

      {!loading && !error && puedeVer && (
         <TableContainer component={Paper}>
           <Table size="small">
             <TableHead><TableRow>
                 <TableCell>Fecha</TableCell><TableCell>Empresa</TableCell><TableCell>Destino</TableCell>
                 <TableCell>Destinatario</TableCell><TableCell>Tipo</TableCell>
                 <TableCell align="right">Monto</TableCell><TableCell>Referencia Interna</TableCell><TableCell>Referencia</TableCell>
                 {(puedeModificar || puedeEliminar) && <TableCell align="right">Acciones</TableCell>}
             </TableRow></TableHead>
             <TableBody>
               {displayData.length === 0 ? (
                  <TableRow><TableCell colSpan={puedeModificar || puedeEliminar ? 9 : 8} align="center">No se encontraron notas.</TableCell></TableRow>
               ) : (
                 displayData.map((n) => (
                     <TableRow key={n.idNota} hover>
                     <TableCell>{formatDate(n.fecha)}</TableCell><TableCell>{n.nombreEmpresa}</TableCell>
                     <TableCell>{n.destino}</TableCell><TableCell>{n.nombreDestinatario}</TableCell>
                     <TableCell>
                        <Chip label={n.tipo} color={n.tipo === 'Credito' ? 'success' : 'error'} size="small"/>
                     </TableCell>
                     <TableCell align="right" sx={{color: n.tipo === 'Credito' ? 'green' : 'red'}}>${n.monto.toFixed(2)}</TableCell>
                     <TableCell>{n.referencia || '-'}</TableCell>
                     <TableCell><Tooltip title={n.observaciones || ''}><Box sx={{maxWidth: 150, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap'}}>{n.observaciones || '-'}</Box></Tooltip></TableCell>
                     {(puedeModificar || puedeEliminar) && (
                        <TableCell align="right">
                            <IconButton onClick={(e) => handleMenuOpen(e, n)} disabled={!puedeModificar && !puedeEliminar}><MoreVertIcon /></IconButton>
                        </TableCell>
                     )}
                     </TableRow>
                 )))}
             </TableBody>
           </Table>
           <TablePagination
             rowsPerPageOptions={[25, 50, 100]} component="div" count={notas.length}
             rowsPerPage={rowsPerPage} page={page} onPageChange={handleChangePage}
             onRowsPerPageChange={handleChangeRowsPerPage} labelRowsPerPage="Filas por página:"
           />
         </TableContainer>
       )}

      <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleMenuClose}>
        {puedeModificar && selectedRow && (
            <MenuItem onClick={() => { handleOpenModal(selectedRow); handleMenuClose(); }}><EditIcon fontSize="small" sx={{mr:1}}/> Modificar</MenuItem>)}
        {puedeEliminar && selectedRow && (
            <MenuItem onClick={() => handleDelete(selectedRow.idNota)}><DeleteIcon fontSize="small" sx={{mr:1}}/> Eliminar</MenuItem>)}
      </Menu>

      <NotaCreditoDebitoFormModal
        open={modalOpen} onClose={handleCloseModal} onSubmit={handleSubmitModal}
        initialData={editingNota} errorMessage={apiErrorMessage}
        clearErrorMessage={() => setApiErrorMessage(null)}
      />
    </Box>
  );
};

export default GestionarNotasCDPage;