"use client";

import { useEffect, useState } from "react";
import type { EventoAgenda } from "./tipos";

/**
 * Agenda sem internet.
 *
 * O caso real: a van, o elevador do cliente, o galpao sem cobertura. Quem faz
 * visita precisa abrir a agenda justamente onde o sinal falta.
 *
 * Guarda a ultima janela consultada no proprio aparelho e a devolve quando a
 * rede cai — com a data de quando foi guardada, porque mostrar dado velho sem
 * dizer que e velho e pior do que nao mostrar nada.
 */

const CHAVE = "ktl_agenda_cache";

type Guardado = { chave: string; em: number; eventos: EventoAgenda[] };

export function guardar(chave: string, eventos: EventoAgenda[]) {
  try {
    const dados: Guardado = { chave, em: Date.now(), eventos };
    localStorage.setItem(CHAVE, JSON.stringify(dados));
  } catch {
    /* Aparelho com armazenamento cheio ou modo privado: seguir sem cache e
       melhor que quebrar a tela. */
  }
}

export function recuperar(chave: string): Guardado | null {
  try {
    const cru = localStorage.getItem(CHAVE);
    if (!cru) return null;
    const dados = JSON.parse(cru) as Guardado;
    /* So serve se for da mesma janela: devolver a semana passada como se
       fosse esta seria pior que a tela vazia. */
    return dados?.chave === chave ? dados : null;
  } catch {
    return null;
  }
}

export function useEstaOnline() {
  const [online, setOnline] = useState(true);

  useEffect(() => {
    setOnline(navigator.onLine);
    const subiu = () => setOnline(true);
    const caiu = () => setOnline(false);
    window.addEventListener("online", subiu);
    window.addEventListener("offline", caiu);
    return () => {
      window.removeEventListener("online", subiu);
      window.removeEventListener("offline", caiu);
    };
  }, []);

  return online;
}

/* ---------- fila de acoes ---------- */

const FILA = "ktl_agenda_fila";

export type AcaoPendente = {
  id: string;
  tipo: "concluir";
  eventoId: string;
  titulo: string;
  em: number;
};

export function lerFila(): AcaoPendente[] {
  try {
    return JSON.parse(localStorage.getItem(FILA) || "[]") as AcaoPendente[];
  } catch {
    return [];
  }
}

function gravarFila(fila: AcaoPendente[]) {
  try {
    localStorage.setItem(FILA, JSON.stringify(fila));
  } catch {
    /* sem espaco: a acao se perde, e melhor que travar o aplicativo */
  }
}

export function enfileirar(acao: Omit<AcaoPendente, "id" | "em">) {
  const fila = lerFila();
  /* Concluir duas vezes o mesmo compromisso e a mesma coisa que concluir uma:
     sem isso, tocar o botao sem sinal empilharia chamadas repetidas. */
  if (fila.some((a) => a.tipo === acao.tipo && a.eventoId === acao.eventoId)) return;
  fila.push({ ...acao, id: crypto.randomUUID(), em: Date.now() });
  gravarFila(fila);
}

/**
 * Sobe o que ficou pendente. Cada acao sai da fila so depois de o servidor
 * confirmar — falhou, fica para a proxima tentativa.
 */
export async function subirFila(): Promise<number> {
  const fila = lerFila();
  if (!fila.length) return 0;

  const restantes: AcaoPendente[] = [];
  let subiram = 0;

  for (const acao of fila) {
    try {
      const r = await fetch(`/api/agenda/events/${acao.eventoId}/concluir`, { method: "POST" });
      if (r.ok || r.status === 404) subiram += 1;
      else restantes.push(acao);
    } catch {
      restantes.push(acao);
    }
  }

  gravarFila(restantes);
  return subiram;
}
