/*
  O aviso de que a conversa andou.

  Quem escreve pode fechar a aba no segundo seguinte, entao quem avisa e o
  servidor, e nao o navegador de quem mandou. Sao tres enderecos, cada um com
  uma pergunta diferente:

  - `chat-<conversa>`  quem esta com este fio aberto (as duas portas: a aba do
                       pedido e o modulo Chats)
  - `chat-loja-<loja>` a loja inteira, para o sininho tocar em qualquer tela
  - `chat-cliente-<cliente>` o portal do cliente, mesmo fora do pedido

  Falha aqui nunca derruba o envio: a mensagem ja esta salva, o aviso e so
  pressa.
*/

export type AvisoDaConversa = {
  threadId: string;
  autor: "store" | "client" | "team" | "system";
  autorNome?: string | null;
  resumo?: string | null;
  orderId?: string | null;
  clientId?: string | null;
  orderNumber?: number | null;
  em?: string;
};

export async function avisarConversa(canais: (string | null | undefined)[], aviso: AvisoDaConversa) {
  const url = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
  const chave = process.env.SUPABASE_SERVICE_ROLE_KEY;
  const topicos = canais.filter(Boolean) as string[];
  if (!url || !chave || !topicos.length) return;

  const corpo = {
    messages: topicos.map((topic) => ({
      topic,
      event: "novidade",
      payload: { ...aviso, em: aviso.em || new Date().toISOString() },
      private: false,
    })),
  };

  try {
    await fetch(`${url.replace(/\/$/, "")}/realtime/v1/api/broadcast`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        apikey: chave,
        Authorization: `Bearer ${chave}`,
      },
      body: JSON.stringify(corpo),
    });
  } catch {
    /* Sem aviso, a conversa ainda anda pela consulta de dez segundos. */
  }
}

export const canalDaConversa = (threadId: string) => `chat-${threadId}`;
export const canalDaLoja = (tenantId?: string | null) => (tenantId ? `chat-loja-${tenantId}` : null);
export const canalDoCliente = (clientId?: string | null) => (clientId ? `chat-cliente-${clientId}` : null);
/* Conversa da equipe nao tem loja nem cliente do outro lado: tem uma pessoa. */
export const canalDaPessoa = (userId?: string | null) => (userId ? `chat-pessoa-${userId}` : null);

/*
  Venda aprovada, para o sino tocar na hora.

  O push alcanca o celular; isto alcanca quem esta com o sistema aberto na
  tela. Sao os dois lados do mesmo aviso.
*/
export async function avisarVenda(
  tenantId: string | null | undefined,
  venda: {
    valor: number;
    metodo?: string | null;
    numero?: number | string | null;
    cliente?: string | null;
    orderId?: string | null;
    origem?: "sistema" | "loja";
  }
) {
  if (!tenantId) return;
  const url = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
  const chave = process.env.SUPABASE_SERVICE_ROLE_KEY;
  if (!url || !chave) return;

  try {
    await fetch(`${url.replace(/\/$/, "")}/realtime/v1/api/broadcast`, {
      method: "POST",
      headers: { "Content-Type": "application/json", apikey: chave, Authorization: `Bearer ${chave}` },
      body: JSON.stringify({
        messages: [
          {
            topic: `venda-${tenantId}`,
            event: "aprovada",
            payload: { ...venda, em: new Date().toISOString() },
            private: false,
          },
        ],
      }),
    });
  } catch {
    /* Sem aviso ao vivo, a venda ja esta registrada do mesmo jeito. */
  }
}

/*
  Movimento da vitrine.

  Mudou de pagina, colocou no carrinho, abriu o checkout: o Chats precisa saber
  no mesmo instante, senao a lista de quem esta na loja conta uma historia
  atrasada — e falar do produto errado e pior do que nao falar.
*/
export async function avisarMovimento(
  tenantId: string | null | undefined,
  movimento: { chave: string; tipo: string; produto?: string | null; pagina?: string | null }
) {
  if (!tenantId) return;
  const url = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
  const chave = process.env.SUPABASE_SERVICE_ROLE_KEY;
  if (!url || !chave) return;

  try {
    await fetch(`${url.replace(/\/$/, "")}/realtime/v1/api/broadcast`, {
      method: "POST",
      headers: { "Content-Type": "application/json", apikey: chave, Authorization: `Bearer ${chave}` },
      body: JSON.stringify({
        messages: [
          {
            topic: `loja-movimento-${tenantId}`,
            event: "movimento",
            payload: { ...movimento, em: new Date().toISOString() },
            private: false,
          },
        ],
      }),
    });
  } catch {
    /* Sem aviso, a lista se corrige sozinha na proxima volta do relogio. */
  }
}

/*
  Pedido que entrou pela loja (pelo WhatsApp, aguardando pagamento ou pedido
  de orcamento). Vai pelo mesmo canal da venda, com evento proprio: o sino
  toca sem o som de dinheiro, porque dinheiro ainda nao entrou.
*/
export async function avisarPedidoDaLoja(
  tenantId: string | null | undefined,
  pedido: {
    orderId: string;
    kind: "order" | "quote_request";
    numero?: number | null;
    cliente?: string | null;
    total?: number | null;
    itens?: number;
    aguardandoPagamento?: boolean;
  }
) {
  if (!tenantId) return;
  const url = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL;
  const chave = process.env.SUPABASE_SERVICE_ROLE_KEY;
  if (!url || !chave) return;

  try {
    await fetch(`${url.replace(/\/$/, "")}/realtime/v1/api/broadcast`, {
      method: "POST",
      headers: { "Content-Type": "application/json", apikey: chave, Authorization: `Bearer ${chave}` },
      body: JSON.stringify({
        messages: [
          {
            topic: `venda-${tenantId}`,
            event: "pedido-da-loja",
            payload: { ...pedido, em: new Date().toISOString() },
            private: false,
          },
        ],
      }),
    });
  } catch {
    /* Sem aviso ao vivo, o pedido ja esta gravado e aparece na proxima volta do relogio. */
  }
}
