import { useState, useEffect, useMemo, useRef } from 'react';

import { sheetsApi } from '../api/client';

import { useAuth } from '../context/AuthContext';

import { useSheetAutoSave } from '../hooks/useSheetAutoSave';

import { useGestionView } from '../hooks/useGestionView';

import SaveStatus from './SaveStatus';

import GestionBanner from './GestionBanner';

import GestionesSidebar from './GestionesSidebar';

import { emptyGastoRow, formatMoney } from '../utils/calc';

import { isRowEditable } from '../utils/gestion';



export default function GastoSheet({ sheetType, title, defaultClasificacion }) {

  const { canEdit, user } = useAuth();

  const editable = canEdit(sheetType);

  const isAdmin = !!user?.isAdmin;

  const { selectedGestionId, selectGestion, sidebarGestiones } = useGestionView();

  const [rows, setRows] = useState([emptyGastoRow()]);

  const [gestion, setGestion] = useState(null);

  const [gestionVista, setGestionVista] = useState(null);

  const [esHistorial, setEsHistorial] = useState(false);

  const [loading, setLoading] = useState(true);

  const [loadError, setLoadError] = useState(null);

  const skipNotifyRef = useRef(false);



  const emptyRow = () => ({ ...emptyGastoRow(), clasificacion: defaultClasificacion });

  const canEditSheet = editable && !esHistorial;



  const { status, error: saveError, setReady, notifyChange, saveNow } = useSheetAutoSave({

    enabled: canEditSheet,

    sheetType,

  });



  useEffect(() => {

    let active = true;

    setLoading(true);

    setLoadError(null);

    setReady(false);



    (async () => {

      try {

        const data = await sheetsApi.get(sheetType, { gestionId: selectedGestionId });

        if (!active) return;

        const loaded = data.rows || [];

        skipNotifyRef.current = true;

        if (loaded.length) {

          setRows(loaded.map((r) => ({ ...r, clasificacion: r.clasificacion || defaultClasificacion })));

        } else if (!data.esHistorial && canEditSheet) {

          setRows([emptyRow()]);

        } else {

          setRows([]);

        }

        setGestion(data.gestion || null);

        setGestionVista(data.gestionVista || null);

        setEsHistorial(!!data.esHistorial);

        setReady(!data.esHistorial);

      } catch (e) {

        if (active) setLoadError(e.message);

      } finally {

        if (active) setLoading(false);

      }

    })();



    return () => {

      active = false;

    };

  }, [sheetType, defaultClasificacion, selectedGestionId, setReady, canEditSheet]);



  useEffect(() => {

    if (loading || !canEditSheet) return;

    if (skipNotifyRef.current) {

      skipNotifyRef.current = false;

      return;

    }

    notifyChange({ rows });

  }, [rows, loading, canEditSheet, notifyChange]);



  const total = useMemo(

    () => rows.reduce((acc, r) => acc + (Number(r.monto) || 0), 0),

    [rows]

  );



  const updateRow = (index, field, value) => {

    if (!isRowEditable(rows[index], canEditSheet, isAdmin)) return;

    setRows((prev) => prev.map((r, i) => (i === index ? { ...r, [field]: value } : r)));

  };



  const addRow = () => setRows((prev) => [...prev, emptyRow()]);



  const removeRow = (index) => {

    if (!isRowEditable(rows[index], canEditSheet, isAdmin)) return;

    skipNotifyRef.current = true;

    const next = rows.filter((_, i) => i !== index);

    const result = next.length > 0 ? next : [emptyRow()];

    setRows(result);

    saveNow({ rows: result });

  };



  const clearSheet = () => {

    const msg = gestion?.fechaCierreGestion && !isAdmin

      ? '¿Eliminar solo las filas editables? Las del período cerrado se conservarán.'

      : '¿Vaciar toda la planilla? Se eliminarán todas las filas de la gestión actual.';

    if (!window.confirm(msg)) return;

    skipNotifyRef.current = true;

    if (isAdmin || !gestion?.fechaCierreGestion) {

      const blank = [emptyRow()];

      setRows(blank);

      saveNow({ rows: blank });

      return;

    }

    const kept = rows.filter((r) => r.bloqueada);

    const result = kept.length ? kept : [emptyRow()];

    setRows(result);

    saveNow({ rows: result });

  };



  if (loading) return <p className="loading">Cargando planilla…</p>;



  return (

    <div className="sheet-layout">

      <GestionesSidebar

        gestiones={sidebarGestiones}

        selectedId={selectedGestionId}

        onSelect={selectGestion}

      />



      <div className="sheet-layout__main">

        <h1 className="page-title">{title}</h1>

        {loadError && <div className="alert alert-error">{loadError}</div>}



        {esHistorial && gestionVista && (

          <div className="historial-badge">

            Historial: <strong>{gestionVista.etiqueta}</strong> ({gestionVista.fechaInicio} →{' '}

            {gestionVista.fechaFin}) — solo lectura

          </div>

        )}



        {!esHistorial && <GestionBanner gestion={gestion} isAdmin={isAdmin} />}

        {canEditSheet && <SaveStatus status={status} error={saveError} />}

        {esHistorial && <div className="alert alert-info">Gestión cerrada — solo consulta</div>}

        {!editable && !esHistorial && <div className="alert alert-info">Solo lectura</div>}



        <div className="toolbar">

          {canEditSheet && (

            <>

              <button type="button" className="btn btn-primary btn-icon" onClick={addRow}>

                +

              </button>

              <button type="button" className="btn btn-secondary" onClick={() => saveNow({ rows })} disabled={status === 'saving'}>

                Guardar ahora

              </button>

              <button type="button" className="btn btn-danger" onClick={clearSheet}>

                Vaciar planilla

              </button>

            </>

          )}

        </div>



        {rows.length === 0 ? (

          <p className="loading">Sin registros en esta gestión.</p>

        ) : (

          <div className="card sheet-table-wrap">

            <table className="sheet-table">

              <thead>

                <tr>

                  <th>Fecha</th>

                  <th>Detalle</th>

                  <th>Impuestos</th>

                  <th>Nº Factura</th>

                  <th>Monto</th>

                  <th>Clasificación</th>

                  {canEditSheet && <th></th>}

                </tr>

              </thead>

              <tbody>

                {rows.map((row, i) => {

                  const rowEditable = isRowEditable(row, canEditSheet, isAdmin);

                  return (

                    <tr key={i} className={row.bloqueada ? 'row-locked' : ''}>

                      <td>

                        <input type="date" value={row.fecha || ''} disabled={!rowEditable} onChange={(e) => updateRow(i, 'fecha', e.target.value)} />

                      </td>

                      <td>

                        <input value={row.detalle || ''} disabled={!rowEditable} onChange={(e) => updateRow(i, 'detalle', e.target.value)} />

                      </td>

                      <td>

                        <input type="number" min="0" step="any" value={row.impuestos ?? ''} disabled={!rowEditable} onChange={(e) => updateRow(i, 'impuestos', e.target.value)} />

                      </td>

                      <td>

                        <input value={row.numeroFactura || ''} disabled={!rowEditable} onChange={(e) => updateRow(i, 'numeroFactura', e.target.value)} />

                      </td>

                      <td>

                        <input type="number" min="0" step="any" value={row.monto ?? ''} disabled={!rowEditable} onChange={(e) => updateRow(i, 'monto', e.target.value)} />

                      </td>

                      <td>

                        <select value={row.clasificacion || 'diario'} disabled={!rowEditable} onChange={(e) => updateRow(i, 'clasificacion', e.target.value)}>

                          <option value="diario">Gasto Diario</option>

                          <option value="fijo">Gasto Fijo</option>

                          <option value="variable">Gasto Variable</option>

                        </select>

                      </td>

                      {canEditSheet && (

                        <td>

                          <button

                            type="button"

                            className="btn btn-danger btn-icon"

                            onClick={(e) => {

                              e.preventDefault();

                              e.stopPropagation();

                              removeRow(i);

                            }}

                            disabled={!rowEditable}

                            title={row.bloqueada ? 'Bloqueado — período cerrado' : 'Eliminar fila'}

                          >

                            ×

                          </button>

                        </td>

                      )}

                    </tr>

                  );

                })}

              </tbody>

            </table>

          </div>

        )}



        <div className="totals-bar">

          <span>

            Total gastos: <strong>{formatMoney(total)}</strong>

          </span>

        </div>

      </div>

    </div>

  );

}

