"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { supabase } from "../../lib/supabase";

type Cliente = {
  id: number;
  nombre: string;
};

type Pago = {
  id: number;
  cliente_id: number | null;
  cliente: string;
  monto: number;
  moneda: string;
  metodo_pago: string;
  referencia: string | null;
  fecha: string;
  notas: string | null;
};

type CuentaCliente = {
  clienteId: number;
  cliente: string;
  totalDebe: number;
  totalPagado: number;
  pendiente: number;
};

export default function PagosPage() {
  const [pagos, setPagos] = useState<Pago[]>([]);
  const [clientes, setClientes] = useState<Cliente[]>([]);
  const [loading, setLoading] = useState(true);

  const [clienteId, setClienteId] = useState("");
  const [monto, setMonto] = useState("");
  const [totalDebe, setTotalDebe] = useState("");

  const [metodoPago, setMetodoPago] =
    useState("Efectivo");

  const [referencia, setReferencia] =
    useState("");

  const [fecha, setFecha] = useState(
    new Date().toISOString().split("T")[0]
  );

  const [notas, setNotas] = useState("");

  useEffect(() => {
    cargarDatos();
  }, []);

  async function cargarDatos() {
    setLoading(true);

    const [
      pagosResult,
      clientesResult,
    ] = await Promise.all([
      supabase
        .from("pagos")
        .select("*")
        .order("fecha", {
          ascending: false,
        }),

      supabase
        .from("clientes")
        .select("id, nombre")
        .order("nombre", {
          ascending: true,
        }),
    ]);

    if (pagosResult.error) {
      console.error(
        "Error cargando pagos:",
        pagosResult.error
      );

      alert(
        "Error cargando pagos: " +
          pagosResult.error.message
      );
    }

    if (clientesResult.error) {
      console.error(
        "Error cargando clientes:",
        clientesResult.error
      );
    }

    setPagos(pagosResult.data || []);
    setClientes(clientesResult.data || []);

    setLoading(false);
  }

  const cuentasClientes = useMemo(() => {
    const cuentas: Record<
      string,
      CuentaCliente
    > = {};

    clientes.forEach((cliente) => {
      cuentas[cliente.id] = {
        clienteId: cliente.id,
        cliente: cliente.nombre,
        totalDebe: 0,
        totalPagado: 0,
        pendiente: 0,
      };
    });

    pagos.forEach((pago) => {
      if (!pago.cliente_id) {
        return;
      }

      const id = String(pago.cliente_id);

      if (!cuentas[id]) {
        cuentas[id] = {
          clienteId: pago.cliente_id,
          cliente: pago.cliente || "Cliente",
          totalDebe: 0,
          totalPagado: 0,
          pendiente: 0,
        };
      }

      const montoPago = Number(
        pago.monto || 0
      );

      const deudaOriginal =
        Number(
          pago.notas
            ?.match(
              /\[DEUDA_TOTAL:([0-9.]+)\]/
            )
            ?.[1] || 0
        );

      if (deudaOriginal > 0) {
        cuentas[id].totalDebe =
          Math.max(
            cuentas[id].totalDebe,
            deudaOriginal
          );
      }

      cuentas[id].totalPagado +=
        montoPago;
    });

    Object.values(cuentas).forEach(
      (cuenta) => {
        cuenta.pendiente =
          Math.max(
            0,
            cuenta.totalDebe -
              cuenta.totalPagado
          );
      }
    );

    return Object.values(cuentas);
  }, [clientes, pagos]);

  const cuentaSeleccionada = useMemo(() => {
    if (!clienteId) {
      return null;
    }

    return (
      cuentasClientes.find(
        (cuenta) =>
          cuenta.clienteId.toString() ===
          clienteId
      ) || null
    );
  }, [
    clienteId,
    cuentasClientes,
  ]);

  async function registrarPago(
    event: React.FormEvent
  ) {
    event.preventDefault();

    if (!clienteId) {
      alert("Selecciona un cliente.");
      return;
    }

    if (
      !monto ||
      Number(monto) <= 0
    ) {
      alert(
        "Ingresa un monto válido mayor que $0."
      );

      return;
    }

    const clienteSeleccionado =
      clientes.find(
        (cliente) =>
          cliente.id.toString() ===
          clienteId
      );

    if (!clienteSeleccionado) {
      alert(
        "No se encontró el cliente."
      );

      return;
    }

    const pagoActual =
      Number(monto);

    const cuentaActual =
      cuentasClientes.find(
        (cuenta) =>
          cuenta.clienteId ===
          clienteSeleccionado.id
      );

    let deudaCliente =
      cuentaActual?.totalDebe || 0;

    if (
      deudaCliente <= 0 &&
      totalDebe
    ) {
      deudaCliente =
        Number(totalDebe);
    }

    if (deudaCliente <= 0) {
      alert(
        "Debes indicar cuánto debe en total este cliente."
      );

      return;
    }

    const yaPagado =
      cuentaActual?.totalPagado || 0;

    const nuevoTotalPagado =
      yaPagado +
      pagoActual;

    if (
      nuevoTotalPagado >
      deudaCliente
    ) {
      alert(
        `El pago supera el saldo pendiente de ${formatoDolar(
          Math.max(
            0,
            deudaCliente - yaPagado
          )
        )}.`
      );

      return;
    }

    let notasFinales =
      notas.trim();

    /*
    Guardamos la deuda total dentro
    de la primera referencia de pago.

    Si el cliente ya tenía una deuda,
    conservamos su deuda original.
    */

    if (
      !cuentaActual ||
      cuentaActual.totalDebe <= 0
    ) {
      notasFinales =
        `${notasFinales} [DEUDA_TOTAL:${deudaCliente}]`
          .trim();
    }

    const { error } = await supabase
      .from("pagos")
      .insert({
        cliente_id:
          clienteSeleccionado.id,

        cliente:
          clienteSeleccionado.nombre,

        monto:
          pagoActual,

        moneda:
          "USD",

        metodo_pago:
          metodoPago,

        referencia:
          referencia.trim() || null,

        fecha,

        notas:
          notasFinales || null,
      });

    if (error) {
      console.error(
        "Error registrando pago:",
        error
      );

      alert(
        "No se pudo registrar el pago: " +
          error.message
      );

      return;
    }

    const pendiente =
      Math.max(
        0,
        deudaCliente -
          nuevoTotalPagado
      );

    if (pendiente === 0) {
      alert(
        `Pago registrado correctamente.\n\n${clienteSeleccionado.nombre} ya pagó completamente ${formatoDolar(
          deudaCliente
        )}.`
      );
    } else {
      alert(
        `Pago registrado correctamente.\n\nTotal pagado: ${formatoDolar(
          nuevoTotalPagado
        )}\nSaldo pendiente: ${formatoDolar(
          pendiente
        )}`
      );
    }

    setClienteId("");
    setMonto("");
    setTotalDebe("");
    setMetodoPago("Efectivo");
    setReferencia("");

    setFecha(
      new Date()
        .toISOString()
        .split("T")[0]
    );

    setNotas("");

    await cargarDatos();
  }

  async function eliminarPago(
    id: number
  ) {
    const confirmar =
      window.confirm(
        "¿Seguro que deseas eliminar este pago?"
      );

    if (!confirmar) {
      return;
    }

    const { error } =
      await supabase
        .from("pagos")
        .delete()
        .eq(
          "id",
          id
        );

    if (error) {
      alert(
        "No se pudo eliminar el pago: " +
          error.message
      );

      return;
    }

    setPagos(
      (pagosActuales) =>
        pagosActuales.filter(
          (pago) =>
            pago.id !== id
        )
    );

    alert(
      "Pago eliminado correctamente."
    );
  }

  const totalCobrado =
    pagos.reduce(
      (total, pago) =>
        total +
        Number(
          pago.monto || 0
        ),
      0
    );

  const totalPendiente =
    cuentasClientes.reduce(
      (total, cuenta) =>
        total +
        cuenta.pendiente,
      0
    );

  const pagosHoy =
    pagos.filter(
      (pago) => {
        const hoy =
          new Date()
            .toISOString()
            .split("T")[0];

        return pago.fecha === hoy;
      }
    );

  const totalHoy =
    pagosHoy.reduce(
      (total, pago) =>
        total +
        Number(
          pago.monto || 0
        ),
      0
    );

  function formatoDolar(
    cantidad: number
  ) {
    return new Intl.NumberFormat(
      "en-US",
      {
        style: "currency",
        currency: "USD",
      }
    ).format(cantidad);
  }

  if (loading) {
    return (
      <main className="min-h-screen bg-[#020817] p-10 text-white">
        Cargando pagos...
      </main>
    );
  }

  return (
    <main className="min-h-screen bg-[#020817] p-10 text-white">

      <div className="mb-8">
        <Link
          href="/dashboard"
          className="inline-flex items-center gap-2 rounded-xl border border-slate-700 bg-slate-800 px-6 py-3 text-lg font-semibold text-white transition hover:bg-slate-700"
        >
          🏠 Inicio
        </Link>
      </div>

      <div className="mb-10">
        <h1 className="text-5xl font-bold">
          💰 Pagos
        </h1>

        <p className="mt-2 text-xl text-slate-400">
          Control individual de pagos y saldos pendientes por cliente
        </p>
      </div>

      {/* RESUMEN */}

      <div className="mb-10 grid grid-cols-1 gap-6 md:grid-cols-4">

        <div className="rounded-3xl border border-green-700 bg-slate-900 p-6">
          <p className="text-lg text-slate-400">
            💵 Total cobrado
          </p>

          <h2 className="mt-3 text-3xl font-bold text-green-400">
            {formatoDolar(
              totalCobrado
            )}
          </h2>
        </div>

        <div className="rounded-3xl border border-blue-700 bg-slate-900 p-6">
          <p className="text-lg text-slate-400">
            📅 Cobrado hoy
          </p>

          <h2 className="mt-3 text-3xl font-bold text-blue-400">
            {formatoDolar(
              totalHoy
            )}
          </h2>
        </div>

        <div className="rounded-3xl border border-red-700 bg-slate-900 p-6">
          <p className="text-lg text-slate-400">
            ⏳ Total pendiente
          </p>

          <h2 className="mt-3 text-3xl font-bold text-red-400">
            {formatoDolar(
              totalPendiente
            )}
          </h2>
        </div>

        <div className="rounded-3xl border border-orange-700 bg-slate-900 p-6">
          <p className="text-lg text-slate-400">
            🧾 Total de pagos
          </p>

          <h2 className="mt-3 text-3xl font-bold text-orange-400">
            {pagos.length}
          </h2>
        </div>

      </div>

      {/* CUENTAS POR CLIENTE */}

      <div className="mb-10 overflow-hidden rounded-3xl border border-slate-700 bg-slate-900">

        <div className="border-b border-slate-700 p-6">

          <h2 className="text-3xl font-bold">
            👥 Estado de cuenta por cliente
          </h2>

          <p className="mt-2 text-slate-400">
            Cada cliente tiene su propio saldo independiente.
          </p>

        </div>

        <div className="overflow-x-auto">

          <table className="w-full">

            <thead className="bg-slate-800">

              <tr>

                <th className="px-5 py-5 text-left">
                  Cliente
                </th>

                <th className="px-5 py-5 text-right">
                  Total debe
                </th>

                <th className="px-5 py-5 text-right">
                  Total pagado
                </th>

                <th className="px-5 py-5 text-right">
                  Pendiente
                </th>

                <th className="px-5 py-5 text-center">
                  Estado
                </th>

              </tr>

            </thead>

            <tbody>

              {cuentasClientes
                .filter(
                  (cuenta) =>
                    cuenta.totalDebe > 0 ||
                    cuenta.totalPagado > 0
                )
                .map(
                  (cuenta) => {

                    const pagadoCompleto =
                      cuenta.pendiente <= 0 &&
                      cuenta.totalDebe > 0;

                    return (

                      <tr
                        key={
                          cuenta.clienteId
                        }
                        className="border-t border-slate-700 hover:bg-slate-800/70"
                      >

                        <td className="px-5 py-5 text-lg font-bold">
                          👤 {cuenta.cliente}
                        </td>

                        <td className="px-5 py-5 text-right">
                          {formatoDolar(
                            cuenta.totalDebe
                          )}
                        </td>

                        <td className="px-5 py-5 text-right font-bold text-green-400">
                          {formatoDolar(
                            cuenta.totalPagado
                          )}
                        </td>

                        <td className="px-5 py-5 text-right text-lg font-bold text-red-400">
                          {formatoDolar(
                            cuenta.pendiente
                          )}
                        </td>

                        <td className="px-5 py-5 text-center">

                          {pagadoCompleto ? (

                            <span className="rounded-full bg-green-500/20 px-4 py-2 font-bold text-green-400">
                              ✅ PAGADO
                            </span>

                          ) : (

                            <span className="rounded-full bg-red-500/20 px-4 py-2 font-bold text-red-400">
                              ⏳ PENDIENTE
                            </span>

                          )}

                        </td>

                      </tr>

                    );

                  }
                )}

              {cuentasClientes.filter(
                (cuenta) =>
                  cuenta.totalDebe > 0 ||
                  cuenta.totalPagado > 0
              ).length === 0 && (

                <tr>

                  <td
                    colSpan={5}
                    className="px-5 py-10 text-center text-slate-400"
                  >
                    Aún no hay cuentas registradas.
                  </td>

                </tr>

              )}

            </tbody>

          </table>

        </div>

      </div>

      {/* FORMULARIO */}

      <div className="mb-10 rounded-3xl border border-slate-700 bg-slate-900 p-8">

        <h2 className="mb-6 text-3xl font-bold">
          ➕ Registrar pago
        </h2>

        <form
          onSubmit={registrarPago}
          className="grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3"
        >

          <div>

            <label className="mb-2 block text-lg font-medium">
              Cliente
            </label>

            <select
              value={clienteId}
              onChange={(event) => {

                const nuevoClienteId =
                  event.target.value;

                setClienteId(
                  nuevoClienteId
                );

                const cuenta =
                  cuentasClientes.find(
                    (item) =>
                      item.clienteId.toString() ===
                      nuevoClienteId
                  );

                if (
                  cuenta &&
                  cuenta.totalDebe > 0
                ) {
                  setTotalDebe(
                    cuenta.totalDebe.toString()
                  );
                } else {
                  setTotalDebe("");
                }

              }}
              className="w-full rounded-xl border border-slate-600 bg-slate-800 px-4 py-3 text-white outline-none focus:border-orange-500"
            >

              <option value="">
                Seleccionar cliente
              </option>

              {clientes.map(
                (cliente) => (

                  <option
                    key={cliente.id}
                    value={cliente.id}
                  >
                    {cliente.nombre}
                  </option>

                )
              )}

            </select>

          </div>

          <div>

            <label className="mb-2 block text-lg font-medium">
              Total que debe el cliente (USD)
            </label>

            <input
              type="number"
              min="0"
              step="0.01"
              value={totalDebe}
              onChange={(event) =>
                setTotalDebe(
                  event.target.value
                )
              }
              placeholder="$ 780.00"
              className="w-full rounded-xl border border-slate-600 bg-slate-800 px-4 py-3 text-white outline-none focus:border-orange-500"
            />

          </div>

          <div>

            <label className="mb-2 block text-lg font-medium">
              Pago recibido (USD)
            </label>

            <input
              type="number"
              min="0"
              step="0.01"
              value={monto}
              onChange={(event) =>
                setMonto(
                  event.target.value
                )
              }
              placeholder="$ 500.00"
              className="w-full rounded-xl border border-slate-600 bg-slate-800 px-4 py-3 text-white outline-none focus:border-orange-500"
            />

          </div>

          {cuentaSeleccionada &&
            cuentaSeleccionada.totalDebe > 0 && (

              <div className="rounded-xl border border-orange-500/40 bg-orange-500/10 p-4">

                <p className="text-sm text-slate-400">
                  Saldo pendiente actual
                </p>

                <p className="mt-1 text-2xl font-bold text-orange-400">
                  {formatoDolar(
                    cuentaSeleccionada.pendiente
                  )}
                </p>

              </div>

            )}

          <div>

            <label className="mb-2 block text-lg font-medium">
              Método de pago
            </label>

            <select
              value={metodoPago}
              onChange={(event) =>
                setMetodoPago(
                  event.target.value
                )
              }
              className="w-full rounded-xl border border-slate-600 bg-slate-800 px-4 py-3 text-white outline-none focus:border-orange-500"
            >

              <option>Efectivo</option>
              <option>Zelle</option>
              <option>Transferencia bancaria</option>
              <option>Tarjeta</option>
              <option>PayPal</option>
              <option>Otro</option>

            </select>

          </div>

          <div>

            <label className="mb-2 block text-lg font-medium">
              Referencia
            </label>

            <input
              type="text"
              value={referencia}
              onChange={(event) =>
                setReferencia(
                  event.target.value
                )
              }
              placeholder="Número de transacción"
              className="w-full rounded-xl border border-slate-600 bg-slate-800 px-4 py-3 text-white outline-none focus:border-orange-500"
            />

          </div>

          <div>

            <label className="mb-2 block text-lg font-medium">
              Fecha
            </label>

            <input
              type="date"
              value={fecha}
              onChange={(event) =>
                setFecha(
                  event.target.value
                )
              }
              className="w-full rounded-xl border border-slate-600 bg-slate-800 px-4 py-3 text-white outline-none focus:border-orange-500"
            />

          </div>

          <div>

            <label className="mb-2 block text-lg font-medium">
              Notas
            </label>

            <input
              type="text"
              value={notas}
              onChange={(event) =>
                setNotas(
                  event.target.value
                )
              }
              placeholder="Información adicional"
              className="w-full rounded-xl border border-slate-600 bg-slate-800 px-4 py-3 text-white outline-none focus:border-orange-500"
            />

          </div>

          <div className="flex items-end">

            <button
              type="submit"
              className="w-full rounded-xl bg-green-600 px-6 py-4 text-lg font-bold text-white transition hover:bg-green-700"
            >
              💵 Registrar pago
            </button>

          </div>

        </form>

      </div>

      {/* HISTORIAL */}

      <div className="overflow-hidden rounded-3xl border border-slate-700 bg-slate-900 shadow-2xl">

        <div className="border-b border-slate-700 p-6">

          <h2 className="text-3xl font-bold">
            📋 Historial de pagos
          </h2>

        </div>

        <div className="overflow-x-auto">

          <table className="w-full">

            <thead className="bg-slate-800">

              <tr>

                <th className="px-5 py-5 text-left">
                  Cliente
                </th>

                <th className="px-5 py-5 text-left">
                  Monto
                </th>

                <th className="px-5 py-5 text-left">
                  Método
                </th>

                <th className="px-5 py-5 text-left">
                  Referencia
                </th>

                <th className="px-5 py-5 text-left">
                  Fecha
                </th>

                <th className="px-5 py-5 text-center">
                  Acción
                </th>

              </tr>

            </thead>

            <tbody>

              {pagos.map(
                (pago) => (

                  <tr
                    key={pago.id}
                    className="border-t border-slate-700 transition hover:bg-slate-800/70"
                  >

                    <td className="px-5 py-5 text-lg font-semibold">
                      {pago.cliente}
                    </td>

                    <td className="px-5 py-5 text-lg font-bold text-green-400">
                      {formatoDolar(
                        Number(
                          pago.monto
                        )
                      )}
                    </td>

                    <td className="px-5 py-5">
                      {pago.metodo_pago}
                    </td>

                    <td className="px-5 py-5 text-slate-400">
                      {pago.referencia ||
                        "-"}
                    </td>

                    <td className="px-5 py-5">
                      {pago.fecha}
                    </td>

                    <td className="px-5 py-5 text-center">

                      <button
                        onClick={() =>
                          eliminarPago(
                            pago.id
                          )
                        }
                        className="rounded-xl bg-red-600 px-4 py-3 transition hover:bg-red-700"
                        title="Eliminar pago"
                      >
                        🗑
                      </button>

                    </td>

                  </tr>

                )
              )}

              {pagos.length === 0 && (

                <tr>

                  <td
                    colSpan={6}
                    className="px-5 py-10 text-center text-xl text-slate-400"
                  >
                    Aún no hay pagos registrados.
                  </td>

                </tr>

              )}

            </tbody>

          </table>

        </div>

      </div>

    </main>
  );
}