/*
 * Regras puras das ferramentas de Produtos digitais do assistente: juntar o
 * que a pessoa pediu com o que já está gravado, as datas de Brasília, os
 * códigos de envio e as palavras da tela. Sem banco e sem "@/": o teste ao
 * lado roda direto no node.
 *
 * Vocabulário (regra da casa): é um ERP, não escola. Nada de aluno, aula ou
 * curso no que vai à pessoa: "conteúdo em vídeo", "módulo", "vídeo",
 * "cliente", "área de membros", como as telas do painel.
 */

/** "2026-10-20" + "19:30" → instante ISO (Brasília é sempre -03:00 desde 2019). */
export function instanteDeBrasilia(dia: string, hora = "00:00"): string | null {
  if (!/^\d{4}-\d{2}-\d{2}$/.test(dia) || !/^([01]\d|2[0-3]):[0-5]\d$/.test(hora)) return null;
  const t = new Date(`${dia}T${hora}:00-03:00`).getTime();
  return Number.isFinite(t) ? new Date(t).toISOString() : null;
}

/** Instante ISO → "20/10/2026 19:30" em Brasília (para a pessoa ler). */
export function dataEHoraBr(iso: string | null | undefined): string | null {
  if (!iso) return null;
  const t = new Date(iso).getTime();
  if (!Number.isFinite(t)) return null;
  const d = new Date(t - 3 * 3600 * 1000).toISOString();
  return `${d.slice(8, 10)}/${d.slice(5, 7)}/${d.slice(0, 4)} ${d.slice(11, 16)}`;
}

/** 1102 → "18 min"; 4380 → "1h 13min". */
export function duracaoBr(segundos: number | null | undefined): string | null {
  const s = Math.round(Number(segundos) || 0);
  if (s <= 0) return null;
  const minutos = Math.max(1, Math.round(s / 60));
  if (minutos < 60) return `${minutos} min`;
  const h = Math.floor(minutos / 60);
  const m = minutos % 60;
  return m ? `${h}h ${m}min` : `${h}h`;
}

/** 734003200 → "700 MB". */
export function tamanhoBr(bytes: number | null | undefined): string {
  const b = Math.max(0, Number(bytes) || 0);
  if (b >= 1024 ** 3) return `${(b / 1024 ** 3).toLocaleString("pt-BR", { maximumFractionDigits: 1 })} GB`;
  if (b >= 1024 ** 2) return `${(b / 1024 ** 2).toLocaleString("pt-BR", { maximumFractionDigits: 1 })} MB`;
  return `${Math.max(1, Math.round(b / 1024))} KB`;
}

const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

export type ReferenciaDeArquivo = { tipo: "id"; id: string } | { tipo: "envio"; codigo: string };

/**
 * O arquivo que a pessoa indicou: o id da biblioteca (listar_arquivos_digitais)
 * ou o código do envio ("envio:Ab3dE9xK2mQp", o código sozinho ou o link
 * /enviar/<código> inteiro). O resto é null.
 */
export function lerReferenciaDeArquivo(valor: unknown): ReferenciaDeArquivo | null {
  let texto = String(valor ?? "").trim();
  if (UUID.test(texto)) return { tipo: "id", id: texto.toLowerCase() };
  const doLink = /\/enviar\/([A-Za-z0-9]{12})\/?(?:[?#].*)?$/.exec(texto);
  if (doLink) texto = doLink[1];
  texto = texto.replace(/^envio:\s*/i, "");
  return /^[A-Za-z0-9]{12}$/.test(texto) ? { tipo: "envio", codigo: texto } : null;
}

/* ------------------------------------------------------------ produto */

export type MudancasNaConfig = {
  resumo?: string | null;
  perguntas?: Array<{ pergunta: string; resposta: string }>;
  funcionaCom?: string[];
  licenca?: { tipo: string; texto?: string | null } | null;
  /* null: segue as Configurações; 0: para sempre; n: n dias. */
  prazoDeAcessoDias?: number | null;
  amostras?: string[];
  entrega?: { modo?: string; prazoDias?: number };
  /* null: sem pré-venda. */
  preVendaEm?: string | null;
  limiteDeDownloads?: number | null;
  marcaNoPdf?: boolean | null;
  avisarCodigosCom?: number;
  curso?: {
    aprendizados?: string[];
    professor?: { nome: string; foto?: string | null; destaque?: string | null; bio?: string | null } | null;
    apresentacao?: { arquivoId: string } | { link: string } | null;
    garantiaDias?: number | null;
    certificado?: { emitir?: boolean; cargaHoras?: number | null };
  };
};

type Objeto = Record<string, unknown>;
const objeto = (valor: unknown): Objeto => (valor && typeof valor === "object" && !Array.isArray(valor) ? (valor as Objeto) : {});

/**
 * A config do produto com as mudanças por cima. A rota do painel troca a
 * config INTEIRA (a tela manda tudo); aqui o que não foi pedido continua como
 * estava. O tipo, o "o que você recebe" e o resumo do conteúdo são da rota.
 */
export function mesclarConfig(atual: unknown, mudancas: MudancasNaConfig): Objeto {
  const base = { ...objeto(atual) };
  if ("resumo" in mudancas) base.resumo = mudancas.resumo;
  if (mudancas.perguntas) base.perguntas = mudancas.perguntas;
  if (mudancas.funcionaCom) base.funcionaCom = mudancas.funcionaCom;
  if ("licenca" in mudancas) base.licenca = mudancas.licenca;
  if ("prazoDeAcessoDias" in mudancas) {
    /* A tela guarda `acesso: null` para "segue as Configurações" e prazoDias null para "para sempre". */
    const prazo = mudancas.prazoDeAcessoDias;
    base.acesso = prazo === null || prazo === undefined ? null : { prazoDias: prazo > 0 ? prazo : null };
  }
  if (mudancas.amostras) base.amostras = mudancas.amostras;
  if (mudancas.entrega) base.entrega = { ...objeto(base.entrega), ...mudancas.entrega };
  if ("preVendaEm" in mudancas) base.preVenda = mudancas.preVendaEm ? { em: mudancas.preVendaEm } : null;
  if ("limiteDeDownloads" in mudancas) base.limiteDeDownloads = mudancas.limiteDeDownloads;
  if ("marcaNoPdf" in mudancas) base.marcaNoPdf = mudancas.marcaNoPdf;
  if ("avisarCodigosCom" in mudancas) base.avisarCodigosCom = mudancas.avisarCodigosCom;
  if (mudancas.curso) {
    const curso = { ...objeto(base.curso) };
    const m = mudancas.curso;
    if (m.aprendizados) curso.aprendizados = m.aprendizados;
    if ("professor" in m) curso.professor = m.professor;
    if ("apresentacao" in m) {
      const a = m.apresentacao;
      curso.apresentacao = !a ? null : "arquivoId" in a ? { arquivoId: a.arquivoId } : { link: { url: a.link } };
    }
    if ("garantiaDias" in m) curso.garantiaDias = m.garantiaDias;
    if (m.certificado) curso.certificado = { ...objeto(curso.certificado), ...m.certificado };
    base.curso = curso;
  }
  return base;
}

/** Preço que muda num produto que está na loja: é dinheiro, passa pela prévia com código. */
export function mudaPrecoNaLoja(params: { naLoja: boolean; precoAtual: number; precoNovo: number | null | undefined }): boolean {
  if (params.precoNovo === null || params.precoNovo === undefined) return false;
  return params.naLoja && Math.round(params.precoAtual * 100) !== Math.round(params.precoNovo * 100);
}

/* ------------------------------------------------------------ lives */

/** A live como a tela mostra (liveParaATela) → os campos que a rota de salvar lê. */
export function dadosDaLiveParaSalvar(tela: Objeto): Objeto {
  return {
    categoria: tela.categoria,
    titulo: tela.titulo,
    comecaEm: tela.comecaEm,
    duracaoMin: tela.duracaoMin,
    esperaMin: tela.esperaMin,
    acesso: tela.acesso,
    preco: tela.preco,
    venderDurante: tela.venderDurante,
    limiteVagas: tela.limiteVagas,
    participacao: tela.participacao,
    camerasAlunos: tela.camerasAlunos,
    chat: tela.chat,
    gravar: tela.gravar,
    gravacaoPara: tela.gravacaoPara,
    gravacaoModo: tela.gravacaoModo,
    vaga: tela.vaga,
    vagaCompraId: tela.vagaCompraId,
    itens: tela.itens,
    vitrine: tela.vitrine,
    produtosVitrine: tela.produtosVitrine,
    apresentadorNome: tela.apresentadorNome,
    apresentadorBio: tela.apresentadorBio,
    apresentadorFoto: tela.apresentadorFoto,
    aprender: tela.aprender,
    capa: tela.capa,
    descricao: tela.descricao,
  };
}

/* O nome do campo da ferramenta → o nome que a rota lê. */
export const CAMPOS_DA_LIVE: Record<string, string> = {
  titulo: "titulo",
  duracao_min: "duracaoMin",
  espera_min: "esperaMin",
  acesso: "acesso",
  preco: "preco",
  vender_durante: "venderDurante",
  limite_de_vagas: "limiteVagas",
  participacao: "participacao",
  cameras_dos_participantes: "camerasAlunos",
  chat: "chat",
  gravar: "gravar",
  gravacao_para: "gravacaoPara",
  gravacao_modo: "gravacaoModo",
  vaga: "vaga",
  pacote_id: "vagaCompraId",
  vitrine: "vitrine",
  produtos_da_vitrine: "produtosVitrine",
  apresentador_nome: "apresentadorNome",
  apresentador_bio: "apresentadorBio",
  o_que_vai_ver: "aprender",
  descricao: "descricao",
};

export const SITUACAO_DA_LIVE: Record<string, string> = {
  agendada: "agendada",
  hoje: "hoje",
  ao_vivo: "no ar agora",
  encerrada: "encerrada",
  cancelada: "cancelada",
  passou: "o horário passou sem ir ao ar",
};

export const SITUACAO_DO_ARQUIVO: Record<string, string> = {
  enviando: "enviando",
  conferindo: "conferindo",
  pronto: "pronto",
  recusado: "recusado",
  apagado: "apagado",
};
