"use client";

/*
 * A empresa está no estoque novo? As telas com duas caras perguntam aqui e,
 * enquanto a resposta não chega, não mostram nenhuma das duas (`carregando`)
 * — assim quem está fora do v2 nunca vê um pedaço da tela nova piscar.
 */

import { useEffect, useState } from "react";

export type SituacaoDoEstoque = {
  v2: boolean;
  dono: string | null;
  podeLer: boolean;
  podeEscrever: boolean;
  podeCadastrar: boolean;
  podeMexerNoProduto: boolean;
};

let lembrada: { valor: SituacaoDoEstoque; em: number } | null = null;
let pedido: Promise<SituacaoDoEstoque> | null = null;

const FORA: SituacaoDoEstoque = { v2: false, dono: null, podeLer: false, podeEscrever: false, podeCadastrar: false, podeMexerNoProduto: false };

export function perguntarSituacao(): Promise<SituacaoDoEstoque> {
  if (lembrada && Date.now() - lembrada.em < 60_000) return Promise.resolve(lembrada.valor);
  if (!pedido) {
    pedido = fetch("/api/estoque/situacao", { cache: "no-store" })
      .then(async (r) => (r.ok ? ((await r.json()) as SituacaoDoEstoque) : FORA))
      .catch(() => FORA)
      .then((valor) => {
        lembrada = { valor, em: Date.now() };
        pedido = null;
        return valor;
      });
  }
  return pedido;
}

export function useEstoqueV2(): SituacaoDoEstoque & { carregando: boolean } {
  const [situacao, setSituacao] = useState<SituacaoDoEstoque | null>(() =>
    lembrada && Date.now() - lembrada.em < 60_000 ? lembrada.valor : null
  );
  useEffect(() => {
    let vivo = true;
    void perguntarSituacao().then((s) => vivo && setSituacao(s));
    return () => {
      vivo = false;
    };
  }, []);
  return { ...(situacao ?? FORA), carregando: situacao === null };
}

/** fetch + JSON com a mensagem de erro do servidor (já em português). */
export async function pedirJson<T>(url: string, init?: RequestInit & { corpo?: unknown }): Promise<T> {
  const { corpo, ...resto } = init ?? {};
  const r = await fetch(url, {
    cache: "no-store",
    ...resto,
    ...(corpo !== undefined ? { body: JSON.stringify(corpo), headers: { "content-type": "application/json", ...(resto.headers ?? {}) } } : {}),
  });
  const json = (await r.json().catch(() => null)) as (T & { error?: string }) | null;
  if (!r.ok || !json) {
    const erro = new Error(json?.error || "Não deu certo. Confira a internet e tente de novo.") as Error & { status?: number; dados?: unknown };
    erro.status = r.status;
    erro.dados = json;
    throw erro;
  }
  return json;
}
