import type { Metadata } from "next";

import { FORMATO_DO_CODIGO } from "@/lib/assistentes/codigo-de-envio";
import { ehEnvioDigital, lerEnvioDigital, limitesDoEnvio, TIPO_DO_ENVIO_DE_VIDEO } from "@/lib/assistentes/envio-digital";
import { ErroDigital } from "@/lib/digitais/servidor/contexto";
import { createAdminClient } from "@/lib/supabase-server";

import { EnvioDeImagem } from "./envio-de-imagem";
import { EnvioDigital } from "./envio-digital";
import { ESTILO_DO_ENVIO } from "./estilo";

/*
 * A página onde a pessoa solta a imagem que quer mandar ao assistente
 * (pedir_imagem, migration 192). Sem login e sem o painel em volta: abre no
 * celular de quem conversa com o Claude ou o ChatGPT. Mostra o nome da loja
 * para a pessoa saber para onde a imagem vai, e nada além disso.
 */

export const dynamic = "force-dynamic";
export const revalidate = 0;

export const metadata: Metadata = {
  title: "Enviar arquivo - Ktalogu",
  robots: { index: false, follow: false },
  referrer: "no-referrer",
};

type Situacao =
  | { tipo: "nao-existe" }
  | { tipo: "indisponivel" }
  | { tipo: "vencido" }
  | { tipo: "aberto"; loja: string | null; paraQue: string | null; recebido: { nome: string | null; largura: number | null; altura: number | null } | null }
  /* Vídeo ou arquivo dos produtos digitais (pedir_video): vai direto ao depósito, em partes. */
  | { tipo: "digital"; loja: string | null; paraQue: string | null; soVideo: boolean; limite: string; recebido: string | null }
  | { tipo: "recusado"; mensagem: string };

async function lerSituacao(codigo: string): Promise<Situacao> {
  if (!FORMATO_DO_CODIGO.test(codigo || "")) return { tipo: "nao-existe" };
  const admin = createAdminClient();
  const { data, error } = await admin
    .from("assistentes_envios")
    .select("company_id,para_que,nome,largura,altura,vence_em,recebido_em,caminho,tipo")
    .eq("codigo", codigo)
    .maybeSingle();
  if (error) {
    console.error("[enviar] abrir página", error.message);
    return { tipo: "indisponivel" };
  }
  const envio = data as {
    company_id: string;
    para_que: string | null;
    nome: string | null;
    largura: number | null;
    altura: number | null;
    vence_em: string;
    recebido_em: string | null;
    caminho: string | null;
    tipo: string | null;
  } | null;
  if (!envio) return { tipo: "nao-existe" };
  if (new Date(envio.vence_em).getTime() <= Date.now()) return { tipo: "vencido" };

  /* O nome da loja vem do perfil do dono da empresa (o nome da empresa
     costuma ser o começo do e-mail, então não serve). Sem ele, a página segue
     sem nome. */
  let loja: string | null = null;
  const { data: empresa } = await admin.from("companies").select("owner_id").eq("id", envio.company_id).maybeSingle();
  const dono = (empresa as { owner_id?: string | null } | null)?.owner_id;
  if (dono) {
    const { data: perfil } = await admin.from("profiles").select("catalog_name").eq("id", dono).maybeSingle();
    const nome = (perfil as { catalog_name?: string | null } | null)?.catalog_name?.trim();
    loja = nome || null;
  }
  if (ehEnvioDigital(envio.tipo)) {
    try {
      const digital = await lerEnvioDigital(admin, codigo);
      const limites = await limitesDoEnvio(admin, digital);
      return {
        tipo: "digital",
        loja: loja ? loja.slice(0, 80) : null,
        paraQue: digital.paraQue,
        soVideo: digital.tipo === TIPO_DO_ENVIO_DE_VIDEO,
        limite: limites.porArquivoLegivel,
        recebido: digital.recebidoEm ? digital.nome : null,
      };
    } catch (erro) {
      if (erro instanceof ErroDigital) return { tipo: "recusado", mensagem: erro.message };
      throw erro;
    }
  }
  return {
    tipo: "aberto",
    loja: loja ? loja.slice(0, 80) : null,
    paraQue: envio.para_que,
    recebido: envio.recebido_em && envio.caminho ? { nome: envio.nome, largura: envio.largura, altura: envio.altura } : null,
  };
}

function Aviso({ titulo, texto }: { titulo: string; texto: string }) {
  return (
    <section className="envio-aviso">
      <h1>{titulo}</h1>
      <p>{texto}</p>
    </section>
  );
}

export default async function PaginaDeEnvio({ params }: { params: Promise<{ codigo: string }> }) {
  const { codigo } = await params;
  const situacao = await lerSituacao(codigo);

  return (
    <main className="envio">
      <style>{ESTILO_DO_ENVIO}</style>
      <div className="envio-faixa">
        <span className="envio-marca">Ktalogu</span>
        <span className="envio-faixa-texto">{situacao.tipo === "digital" ? (situacao.soVideo ? "Envio de vídeo" : "Envio de arquivo") : "Envio de imagem"}</span>
      </div>
      <div className="envio-corpo">
        {situacao.tipo === "nao-existe" && (
          <Aviso
            titulo="Este link de envio não existe"
            texto="Confira se o link foi copiado inteiro. Se não der certo, peça um link novo ao assistente na conversa."
          />
        )}
        {situacao.tipo === "vencido" && (
          <Aviso titulo="Este link venceu" texto="Os links de envio valem 24 horas. Peça um link novo ao assistente na conversa." />
        )}
        {situacao.tipo === "indisponivel" && <Aviso titulo="Não deu para abrir agora" texto="Tente de novo em instantes." />}
        {situacao.tipo === "recusado" && <Aviso titulo="Não dá para enviar por este link" texto={situacao.mensagem} />}
        {situacao.tipo === "digital" && (
          <EnvioDigital
            codigo={codigo}
            loja={situacao.loja}
            paraQue={situacao.paraQue}
            soVideo={situacao.soVideo}
            limite={situacao.limite}
            recebido={situacao.recebido}
          />
        )}
        {situacao.tipo === "aberto" && (
          <EnvioDeImagem codigo={codigo} loja={situacao.loja} paraQue={situacao.paraQue} recebido={situacao.recebido} />
        )}
      </div>
    </main>
  );
}
