import { NextResponse } from "next/server";
import { acessoDoChat } from "@/lib/chats/acesso";
import { avisarConversa } from "@/lib/chats/aviso";
import { createAdminClient } from "@/lib/supabase-server";

/*
  As configurações do atendimento, num lugar só.

  Antes elas estavam espalhadas: o chat da loja ligava na personalização do
  catálogo, o online/offline vivia no cabeçalho da lista e as respostas prontas
  em outro canto. Quem senta para atender precisa de uma engrenagem, e não de
  um mapa do tesouro.

  O expediente é o que tira o peso da memória: em vez de lembrar de ficar
  offline às 18h, a loja diz o horário uma vez e o sistema respeita.
*/

const DIAS = ["dom", "seg", "ter", "qua", "qui", "sex", "sab"] as const;

const HORARIO_PADRAO = DIAS.map((dia) => ({
  dia,
  aberto: dia !== "dom" && dia !== "sab",
  de: "08:00",
  ate: "18:00",
}));

const AUSENCIA_PADRAO =
  "Estamos fora do horário de atendimento agora. Pode deixar sua mensagem que respondemos assim que abrirmos.";

function texto(valor: unknown) {
  return String(valor ?? "").trim();
}

function horaValida(valor: string) {
  return /^([01]\d|2[0-3]):[0-5]\d$/.test(valor);
}

/* O expediente vem da tela como quiser; daqui para dentro ele tem forma. */
function limparHorario(bruto: unknown) {
  const lista = Array.isArray(bruto) ? bruto : [];
  return DIAS.map((dia, indice) => {
    const achado = (lista as { dia?: string; aberto?: boolean; de?: string; ate?: string }[]).find(
      (item) => item?.dia === dia
    );
    const de = texto(achado?.de);
    const ate = texto(achado?.ate);
    return {
      dia,
      aberto: Boolean(achado?.aberto),
      de: horaValida(de) ? de : HORARIO_PADRAO[indice].de,
      ate: horaValida(ate) ? ate : HORARIO_PADRAO[indice].ate,
    };
  });
}

export async function GET() {
  const acesso = await acessoDoChat();
  if ("erro" in acesso) return acesso.erro;

  const admin = createAdminClient();
  const { data } = await admin
    .from("profiles")
    .select(
      "slug,store_chat_enabled,store_chat_online,store_chat_welcome,store_chat_welcome_enabled,chat_welcome_delay,chat_welcome_trigger,chat_business_hours,chat_away_message,chat_auto_offline,chat_nudge_minutes"
    )
    .eq("id", acesso.tenantIds[0])
    .maybeSingle();

  const perfil = data as Record<string, unknown> | null;

  return NextResponse.json({
    ok: true,
    podeConfigurar: acesso.podeConfigurar,
    configuracoes: {
      slug: texto(perfil?.slug) || null,
      chatLigado: perfil?.store_chat_enabled === true,
      online: perfil?.store_chat_online === true,
      saudacaoLigada: perfil?.store_chat_welcome_enabled === true,
      saudacao: texto(perfil?.store_chat_welcome),
      /* Quando a loja fala primeiro: por tempo ou quando a pessoa faz algo. */
      saudacaoEspera: Math.max(5, Number(perfil?.chat_welcome_delay ?? 25)),
      saudacaoQuando: texto(perfil?.chat_welcome_trigger) === "acao" ? "acao" : "tempo",
      horario: Array.isArray(perfil?.chat_business_hours)
        ? limparHorario(perfil?.chat_business_hours)
        : HORARIO_PADRAO,
      horarioConfigurado: Array.isArray(perfil?.chat_business_hours),
      ausencia: texto(perfil?.chat_away_message) || AUSENCIA_PADRAO,
      offlineAutomatico: perfil?.chat_auto_offline === true,
      /* De quantos em quantos minutos sem resposta a loja quer ser cutucada. */
      cutucaoEmMinutos: Math.max(0, Number(perfil?.chat_nudge_minutes ?? 15)),
    },
  });
}

export async function PUT(request: Request) {
  const acesso = await acessoDoChat();
  if ("erro" in acesso) return acesso.erro;
  if (!acesso.podeConfigurar) {
    return NextResponse.json({ error: "Você não tem permissão para configurar o atendimento." }, { status: 403 });
  }

  const corpo = (await request.json().catch(() => null)) as Record<string, unknown> | null;
  if (!corpo) return NextResponse.json({ error: "Envio inválido." }, { status: 400 });

  const mudancas: Record<string, unknown> = {};

  if ("chatLigado" in corpo) mudancas.store_chat_enabled = corpo.chatLigado === true;
  if ("saudacaoLigada" in corpo) mudancas.store_chat_welcome_enabled = corpo.saudacaoLigada === true;
  if ("saudacao" in corpo) mudancas.store_chat_welcome = texto(corpo.saudacao).slice(0, 400) || null;
  if ("saudacaoEspera" in corpo) {
    /* Menos de cinco segundos é abordagem de porta de loja: espanta. Mais de
       cinco minutos e a pessoa já foi embora. */
    const segundos = Math.round(Number(corpo.saudacaoEspera));
    mudancas.chat_welcome_delay = Number.isFinite(segundos) ? Math.min(300, Math.max(5, segundos)) : 25;
  }
  if ("saudacaoQuando" in corpo) {
    mudancas.chat_welcome_trigger = texto(corpo.saudacaoQuando) === "acao" ? "acao" : "tempo";
  }
  if ("ausencia" in corpo) mudancas.chat_away_message = texto(corpo.ausencia).slice(0, 400) || null;
  if ("offlineAutomatico" in corpo) mudancas.chat_auto_offline = corpo.offlineAutomatico === true;
  if ("cutucaoEmMinutos" in corpo) {
    /* Zero desliga. Menos de cinco minutos vira alarme de incendio. */
    const minutos = Math.round(Number(corpo.cutucaoEmMinutos));
    mudancas.chat_nudge_minutes = Number.isFinite(minutos) ? Math.min(240, Math.max(0, minutos)) : 15;
  }
  if ("horario" in corpo) mudancas.chat_business_hours = limparHorario(corpo.horario);

  if (!Object.keys(mudancas).length) return NextResponse.json({ ok: true });

  const admin = createAdminClient();
  const { data, error } = await admin
    .from("profiles")
    .update(mudancas)
    .eq("id", acesso.tenantIds[0])
    .select("slug,store_chat_enabled")
    .maybeSingle();

  if (error) return NextResponse.json({ error: error.message }, { status: 400 });

  /* Ligar ou desligar o chat muda a vitrine na hora: quem está com a loja
     aberta não pode ficar olhando um balão que não existe mais. */
  const slug = texto((data as { slug?: string } | null)?.slug);
  if (slug && "chatLigado" in corpo) {
    await avisarConversa([`loja-${slug}`], {
      threadId: "loja",
      autor: "system",
      resumo: corpo.chatLigado === true ? "ligado" : "desligado",
    });
  }

  return NextResponse.json({ ok: true });
}
