import { useState, useEffect, useCallback } from "react";
import type { Servicio, GastoEntry, PagoServicio, PagoServicioRow } from "../types";
import { normalizePagoServicio } from "../helpers";
import { PAGOS_TAB_ID } from "../types";

export function useServiciosData(
  initialServicios: Servicio[],
  userName: string,
) {
  const [activeTab, setActiveTab] = useState(initialServicios[0]?.id.toString() || "");
  const [entries, setEntries] = useState<Record<string, GastoEntry[]>>({});
  const [dirtyEntries, setDirtyEntries] = useState<Record<string, Partial<GastoEntry>>>({});
  const [servicios, setServicios] = useState(initialServicios);
  const [dirtyServicios, setDirtyServicios] = useState<Record<number, Partial<Servicio>>>({});

  // Pagos de servicios (pagos globales del inquilino)
  const [pagosServicios, setPagosServicios] = useState<PagoServicio[]>([]);
  const [addingPago, setAddingPago] = useState(false);
  const [pagoFecha, setPagoFecha] = useState("");
  const [pagoMonto, setPagoMonto] = useState("");
  const [pagoNotas, setPagoNotas] = useState("");
  const [pagoFechaFilter, setPagoFechaFilter] = useState("");
  const [pagoRegistradoPorFilter, setPagoRegistradoPorFilter] = useState("");
  const [pagoNotasFilter, setPagoNotasFilter] = useState("");
  const [pagoMontoMinFilter, setPagoMontoMinFilter] = useState("");
  const [pagoMontoMaxFilter, setPagoMontoMaxFilter] = useState("");
  const [pagoSortField, setPagoSortField] = useState<"fecha" | "monto" | "notas" | "creadoPor">("fecha");
  const [pagoSortDirection, setPagoSortDirection] = useState<"asc" | "desc">("desc");

  // Distribución
  const [distribucionSearch, setDistribucionSearch] = useState("");
  const [distribucionSortField, setDistribucionSortField] = useState<"servicio" | "corresponde" | "pagado" | "deuda">("servicio");
  const [distribucionSortDirection, setDistribucionSortDirection] = useState<"asc" | "desc">("asc");

  // Entries (gastos)
  const [entriesSearch, setEntriesSearch] = useState("");
  const [entriesSortField, setEntriesSortField, setEntriesSortDir, entriesSortDirection] = useSortState<"periodo" | "facturado" | "corresponde" | "pagado" | "diasMora" | "penalidad" | "porcentajeCubierto" | "completado" | "fechaPago" | "notas">("periodo", "desc");

  // Proof modal
  const [proofModal, setProofModal] = useState<{ title: string; urls: string[] } | null>(null);

  // Agregar servicio
  const [adding, setAdding] = useState(false);
  const [newNombre, setNewNombre] = useState("");
  const [newPorcentaje, setNewPorcentaje] = useState("45");
  const [newColor, setNewColor] = useState("#64748b");

  // Agregar gasto
  const [addingEntry, setAddingEntry] = useState(false);
  const [entryPeriodo, setEntryPeriodo] = useState("");
  const [entryFacturado, setEntryFacturado] = useState("");
  const [entryPagado, setEntryPagado] = useState("");
  const [entryFecha, setEntryFecha] = useState("");
  const [entryNotas, setEntryNotas] = useState("");

  // ---- Loadings ----

  const loadPagosServicios = useCallback(async function loadPagosServicios() {
    const res = await fetch("/api/admin/pagos-servicios");
    if (res.ok) {
      const data: PagoServicio[] = await res.json();
      setPagosServicios(data);
    }
  }, []);

  useEffect(() => {
    const timer = window.setTimeout(() => void loadPagosServicios(), 0);
    return () => window.clearTimeout(timer);
  }, [loadPagosServicios]);

  const loadEntries = useCallback(async (servicioId: string) => {
    if (servicioId === PAGOS_TAB_ID) return;
    const res = await fetch(`/api/admin/servicios/${servicioId}/entries`);
    const data: GastoEntry[] = await res.json();
    setEntries(prev => ({ ...prev, [servicioId]: data }));
    setDirtyEntries({});
  }, []);

  useEffect(() => {
    if (activeTab && activeTab !== PAGOS_TAB_ID) {
      const timer = window.setTimeout(() => void loadEntries(activeTab), 0);
      return () => window.clearTimeout(timer);
    }
  }, [activeTab, loadEntries]);

  // Cargar entries de todos los servicios para las summary cards
  useEffect(() => {
    const timer = window.setTimeout(() => {
      servicios.forEach((svc) => void loadEntries(svc.id.toString()));
    }, 0);
    return () => window.clearTimeout(timer);
  }, [servicios, loadEntries]);

  // ---- Sort toggles ----

  function togglePagoSort(field: typeof pagoSortField) {
    if (pagoSortField === field) {
      setPagoSortDirection(current => current === "asc" ? "desc" : "asc");
    } else {
      setPagoSortField(field);
      setPagoSortDirection(field === "monto" ? "desc" : "asc");
    }
  }

  function toggleDistribucionSort(field: typeof distribucionSortField) {
    if (distribucionSortField === field) {
      setDistribucionSortDirection(current => current === "asc" ? "desc" : "asc");
    } else {
      setDistribucionSortField(field);
      setDistribucionSortDirection(field === "servicio" ? "asc" : "desc");
    }
  }

  function toggleEntriesSort(field: Parameters<typeof setEntriesSortField>[0]) {
    if (entriesSortField === field) {
      setEntriesSortDir(current => current === "asc" ? "desc" : "asc");
    } else {
      setEntriesSortField(field);
      setEntriesSortDir(field === "periodo" || field === "fechaPago" || field === "completado" ? "desc" : "asc");
    }
  }

  // ---- Mutations ----

  async function addPagoServicio() {
    if (!pagoFecha || !pagoMonto) return;
    const res = await fetch("/api/admin/pagos-servicios", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ fecha: pagoFecha, monto: Number(pagoMonto), notas: pagoNotas || null, creadoPor: userName }),
    });
    if (res.ok) {
      setAddingPago(false);
      setPagoFecha(""); setPagoMonto(""); setPagoNotas("");
      loadPagosServicios();
    }
  }

  async function deletePagoServicio(id: number, fecha: string) {
    if (!confirm(`Eliminar pago del ${fecha}?`)) return;
    const res = await fetch(`/api/admin/pagos-servicios/${id}`, { method: "DELETE" });
    if (res.ok) loadPagosServicios();
  }

  async function addServicio() {
    if (!newNombre.trim()) return;
    const res = await fetch("/api/admin/servicios", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ nombre: newNombre.trim(), porcentaje: Number(newPorcentaje) || 45, color: newColor }),
    });
    if (res.ok) {
      const svc: Servicio = await res.json();
      setServicios(prev => [...prev, svc]);
      setNewNombre("");
      setNewPorcentaje("45");
      setNewColor("#64748b");
      setAdding(false);
      setActiveTab(svc.id.toString());
    }
  }

  async function deleteServicio(id: number, nombre: string) {
    if (!confirm(`Eliminar servicio "${nombre}"? Se ocultará pero no se borrarán sus registros.`)) return;
    const res = await fetch(`/api/admin/servicios/${id}`, { method: "DELETE" });
    if (res.ok) {
      setServicios(prev => prev.filter(s => s.id !== id));
      if (activeTab === id.toString()) {
        const remaining = servicios.filter(s => s.id !== id);
        setActiveTab(remaining[0]?.id.toString() || "");
      }
    }
  }

  function updateServicioPorcentaje(servicioId: number, value: number) {
    setDirtyServicios(prev => ({
      ...prev,
      [servicioId]: { ...prev[servicioId], id: servicioId, porcentaje: value }
    }));
  }

  async function saveServicioPorcentaje(servicioId: number) {
    const changes = dirtyServicios[servicioId];
    if (!changes) return;
    await fetch(`/api/admin/servicios/${servicioId}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(changes),
    });
    setDirtyServicios(prev => {
      const next = { ...prev };
      delete next[servicioId];
      return next;
    });
    setServicios(prev => prev.map(s => s.id === servicioId ? { ...s, porcentaje: changes.porcentaje ?? s.porcentaje } : s));
  }

  function updateEntryField(entryId: number, field: keyof GastoEntry, value: string | number) {
    const key = `${activeTab}-${entryId}`;
    setDirtyEntries(prev => ({
      ...prev,
      [key]: { ...prev[key], id: entryId, [field]: value }
    }));
  }

  async function saveEntry(entryId: number) {
    const key = `${activeTab}-${entryId}`;
    const changes = dirtyEntries[key];
    if (!changes) return;
    await fetch(`/api/admin/entries/${entryId}`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ ...changes, usuario: userName }),
    });
    setDirtyEntries(prev => {
      const next = { ...prev };
      delete next[key];
      return next;
    });
    loadEntries(activeTab);
  }

  async function addEntry() {
    if (!entryPeriodo || !entryFacturado) return;
    const res = await fetch(`/api/admin/servicios/${activeTab}/entries`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        periodo: entryPeriodo,
        montoFacturado: Number(entryFacturado),
        montoPagado: Number(entryPagado) || 0,
        fechaPago: entryFecha || null,
        notas: entryNotas || null,
      }),
    });
    if (res.ok) {
      setAddingEntry(false);
      setEntryPeriodo(""); setEntryFacturado(""); setEntryPagado(""); setEntryFecha(""); setEntryNotas("");
      loadEntries(activeTab);
    }
  }

  async function deleteEntry(entryId: number, periodo: string) {
    if (!confirm(`Eliminar gasto de ${periodo}?`)) return;
    const res = await fetch(`/api/admin/entries/${entryId}`, { method: "DELETE" });
    if (res.ok) loadEntries(activeTab);
  }

  return {
    activeTab, setActiveTab,
    entries, setEntries,
    dirtyEntries,
    servicios,
    dirtyServicios,
    pagosServicios,
    addingPago, setAddingPago,
    pagoFecha, setPagoFecha,
    pagoMonto, setPagoMonto,
    pagoNotas, setPagoNotas,
    pagoFechaFilter, setPagoFechaFilter,
    pagoRegistradoPorFilter, setPagoRegistradoPorFilter,
    pagoNotasFilter, setPagoNotasFilter,
    pagoMontoMinFilter, setPagoMontoMinFilter,
    pagoMontoMaxFilter, setPagoMontoMaxFilter,
    pagoSortField, pagoSortDirection, togglePagoSort,
    distribucionSearch, setDistribucionSearch,
    distribucionSortField, distribucionSortDirection, toggleDistribucionSort,
    entriesSearch, setEntriesSearch,
    entriesSortField, entriesSortDirection, toggleEntriesSort,
    proofModal, setProofModal,
    adding, setAdding,
    newNombre, setNewNombre,
    newPorcentaje, setNewPorcentaje,
    newColor, setNewColor,
    addingEntry, setAddingEntry,
    entryPeriodo, setEntryPeriodo,
    entryFacturado, setEntryFacturado,
    entryPagado, setEntryPagado,
    entryFecha, setEntryFecha,
    entryNotas, setEntryNotas,
    addPagoServicio,
    deletePagoServicio,
    addServicio,
    deleteServicio,
    updateServicioPorcentaje,
    saveServicioPorcentaje,
    updateEntryField,
    saveEntry,
    addEntry,
    deleteEntry,
  };
}

// Shared sort state hook to allow separate field/direction setters
function useSortState<T extends string>(initialField: T, initialDir: "asc" | "desc") {
  const [field, setField] = useState<T>(initialField);
  const [dir, setDir] = useState<"asc" | "desc">(initialDir);
  // Combine into a single value for compatibility with components that expect entriesSortDirection
  const direction = dir;
  return [field, setField, setDir, direction] as const;
}
