"use client";

import Image from "next/image";
import { useCallback, useEffect, useRef, useState } from "react";
import { Check, CheckCheck, Clock3, FileText, Paperclip, Send, ThumbsDown, ThumbsUp, X } from "lucide-react";
import { getReadableTextColor } from "@/lib/color-contrast";
import { getSupabaseClient } from "@/lib/supabase";
import AtivarAvisosDoCliente from "@/components/client-portal/AtivarAvisosDoCliente";

/*
  Conversa do pedido — lado do cliente.

  Mesmo desenho da conversa que a loja ve no admin: mensagens seguidas do mesmo
  autor viram um bloco so, com hora e confirmacao apenas na ultima, avatar uma
  vez por bloco e a data separando os dias.

  A diferenca fica na arte: quando a loja marca uma imagem como arte, aqui
  aparecem os botoes de aprovar e pedir ajuste — no balao e tambem dentro da
  foto ampliada, que e onde a pessoa realmente confere o material.
*/

type Cartao = {
  tipo: "produto" | "cupom";
  titulo?: string | null;
  subtitulo?: string | null;
  imagem?: string | null;
  preco?: number | null;
  link?: string | null;
  codigo?: string | null;
};

type Mensagem = {
  id: string;
  sender: "store" | "client";
  sender_name?: string | null;
  body?: string | null;
  card?: Cartao | null;
  attachment_url?: string | null;
  attachment_name?: string | null;
  attachment_kind?: string | null;
  is_art?: boolean | null;
  art_status?: "pending" | "approved" | "rejected" | null;
  art_decided_at?: string | null;
  art_decision_note?: string | null;
  created_at: string;
  deleted_at?: string | null;
  read_by_store_at?: string | null;
  read_by_client_at?: string | null;
  /* So existe na tela: a mensagem que ainda esta indo para o servidor. */
  pendente?: boolean;
};

const DIA_EM_MS = 24 * 60 * 60 * 1000;
const INTERVALO_DE_AGRUPAMENTO_MS = 5 * 60 * 1000;

function rotuloDoDia(iso: string) {
  const data = new Date(iso);
  const hoje = new Date();
  const zerar = (valor: Date) => new Date(valor.getFullYear(), valor.getMonth(), valor.getDate()).getTime();
  const diferenca = Math.round((zerar(hoje) - zerar(data)) / DIA_EM_MS);
  if (diferenca === 0) return "Hoje";
  if (diferenca === 1) return "Ontem";
  return data.toLocaleDateString("pt-BR", { day: "2-digit", month: "long", year: "numeric" });
}

function hora(iso: string) {
  return new Date(iso).toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit" });
}

const emReais = (valor?: number | null) =>
  new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(Number(valor || 0));

/* O produto ou o cupom que a loja mandou pela conversa: com foto e preco, para
   decidir sem sair da tela. */
function CartaoDaMensagem({ cartao, doCliente }: { cartao: Cartao; doCliente: boolean }) {
  const fundo = doCliente ? "bg-white/15" : "bg-[#f2f1f5]";

  if (cartao.tipo === "cupom") {
    return (
      <div className={`mb-1.5 rounded-xl ${fundo} p-2.5`}>
        <div className="text-[10px] font-bold uppercase tracking-[0.12em] opacity-70">Cupom de desconto</div>
        <div className="mt-0.5 text-[17px] font-extrabold tracking-tight">{cartao.codigo || cartao.titulo}</div>
        {cartao.subtitulo ? <div className="text-[11.5px] opacity-80">{cartao.subtitulo}</div> : null}
      </div>
    );
  }

  return (
    <a
      href={cartao.link || "#"}
      className={`mb-1.5 flex items-center gap-2.5 rounded-xl ${fundo} p-2 no-underline`}
      style={{ color: "inherit" }}
    >
      {cartao.imagem ? (
        <Image
          src={cartao.imagem}
          alt={cartao.titulo || "Produto"}
          width={56}
          height={56}
          unoptimized
          className="h-14 w-14 shrink-0 rounded-lg object-cover"
        />
      ) : null}
      <span className="min-w-0">
        <span className="block truncate text-[12.5px] font-bold leading-tight">{cartao.titulo}</span>
        {cartao.preco ? (
          <span className="block text-[14px] font-extrabold tracking-tight">{emReais(cartao.preco)}</span>
        ) : (
          <span className="block text-[11.5px] opacity-80">Ver na loja</span>
        )}
        <span className="block text-[10.5px] underline opacity-80">abrir o produto</span>
      </span>
    </a>
  );
}

function iniciais(nome?: string | null) {
  const partes = String(nome || "").trim().split(/\s+/).filter(Boolean);
  if (!partes.length) return "?";
  if (partes.length === 1) return partes[0].slice(0, 2).toUpperCase();
  return (partes[0][0] + partes[partes.length - 1][0]).toUpperCase();
}

const TEXTO_DA_ARTE: Record<string, string> = {
  pending: "Aguardando sua resposta",
  approved: "Você aprovou",
  rejected: "Você pediu ajuste",
};

function BotoesDaArte({
  compacto,
  ocupado,
  aoAprovar,
  aoPedirAjuste,
}: {
  compacto?: boolean;
  ocupado: boolean;
  aoAprovar: () => void;
  aoPedirAjuste: () => void;
}) {
  return (
    <div className={`flex flex-wrap gap-2 ${compacto ? "" : "mt-2"}`}>
      <button
        type="button"
        onClick={aoAprovar}
        disabled={ocupado}
        className="inline-flex h-9 items-center gap-1.5 rounded-[10px] bg-emerald-600 px-3.5 text-[12px] font-semibold text-white transition hover:bg-emerald-700 disabled:opacity-60"
      >
        <ThumbsUp className="h-3.5 w-3.5" />
        Aprovar arte
      </button>
      <button
        type="button"
        onClick={aoPedirAjuste}
        disabled={ocupado}
        className="inline-flex h-9 items-center gap-1.5 rounded-[10px] border border-rose-200 bg-white px-3.5 text-[12px] font-semibold text-rose-600 transition hover:bg-rose-50 disabled:opacity-60"
      >
        <ThumbsDown className="h-3.5 w-3.5" />
        Pedir ajuste
      </button>
    </div>
  );
}

/* Visualizador da imagem: fundo escuro, a foto no centro, X no canto. Se a foto
   for a arte esperando resposta, os botoes de decisao vem junto — e olhando a
   imagem grande que a pessoa decide. */
function VisualizadorDeImagem({
  url,
  nome,
  arteEmAberto,
  ocupado,
  aoAprovar,
  aoPedirAjuste,
  aoFechar,
}: {
  url: string;
  nome?: string | null;
  arteEmAberto: boolean;
  ocupado: boolean;
  aoAprovar: () => void;
  aoPedirAjuste: () => void;
  aoFechar: () => void;
}) {
  useEffect(() => {
    const aoTeclar = (evento: KeyboardEvent) => {
      if (evento.key === "Escape") aoFechar();
    };
    window.addEventListener("keydown", aoTeclar);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", aoTeclar);
      document.body.style.overflow = "";
    };
  }, [aoFechar]);

  return (
    <div
      role="dialog"
      aria-modal="true"
      onClick={aoFechar}
      className="fixed inset-0 z-[100] flex flex-col items-center justify-center gap-4 bg-black/80 p-6 backdrop-blur-sm"
    >
      <button
        type="button"
        onClick={aoFechar}
        aria-label="Fechar imagem"
        className="absolute right-5 top-5 inline-flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white transition hover:bg-white/20"
      >
        <X className="h-5 w-5" />
      </button>

      <div onClick={(evento) => evento.stopPropagation()} className="max-h-full max-w-full">
        <Image
          src={url}
          alt={nome || "Imagem da conversa"}
          width={1400}
          height={1400}
          unoptimized
          className="max-h-[76vh] w-auto max-w-[92vw] rounded-lg object-contain"
        />
      </div>

      {arteEmAberto ? (
        <div
          onClick={(evento) => evento.stopPropagation()}
          className="rounded-2xl bg-white px-4 py-3 shadow-lg"
        >
          <div className="mb-2 text-center text-[12px] font-medium text-zinc-600">
            Confira a arte e responda para a loja seguir
          </div>
          <BotoesDaArte compacto ocupado={ocupado} aoAprovar={aoAprovar} aoPedirAjuste={aoPedirAjuste} />
        </div>
      ) : null}
    </div>
  );
}

export default function ConversaDoPedido({
  slug,
  orderId,
  primaryColor,
  nomeDaLoja,
}: {
  slug: string;
  orderId: string;
  primaryColor: string;
  /* Do lado do cliente, quem fala e a loja — nao o e-mail do atendente. */
  nomeDaLoja?: string | null;
}) {
  const [mensagens, setMensagens] = useState<Mensagem[]>([]);
  const [carregando, setCarregando] = useState(true);
  const [texto, setTexto] = useState("");
  const [arquivo, setArquivo] = useState<File | null>(null);
  const [enviando, setEnviando] = useState(false);
  const [decidindo, setDecidindo] = useState<string | null>(null);
  const [erro, setErro] = useState<string | null>(null);
  const [imagemAberta, setImagemAberta] = useState<{ url: string; nome?: string | null; arteId?: string | null } | null>(
    null
  );
  const [threadId, setThreadId] = useState<string | null>(null);
  /* Pedir ajuste abre uma caixa nossa, e nao a do navegador: ali cabe
     explicar o que a loja precisa saber, e o texto nao se perde se a pessoa
     clicar fora sem querer. */
  const [ajusteDaArte, setAjusteDaArte] = useState<string | null>(null);
  const [notaDoAjuste, setNotaDoAjuste] = useState("");
  const fimDaLista = useRef<HTMLDivElement | null>(null);
  const campoDeArquivo = useRef<HTMLInputElement | null>(null);

  const buscar = useCallback(
    async (rolar: boolean) => {
      try {
        const resposta = await fetch(
          `/api/client-portal/order-messages?slug=${encodeURIComponent(slug)}&orderId=${encodeURIComponent(orderId)}`,
          { cache: "no-store" }
        );
        const dados = (await resposta.json().catch(() => null)) as
          | { mensagens?: Mensagem[]; threadId?: string }
          | null;
        setMensagens(Array.isArray(dados?.mensagens) ? dados.mensagens : []);
        if (dados?.threadId) setThreadId(dados.threadId);
        if (rolar) window.setTimeout(() => fimDaLista.current?.scrollIntoView({ block: "end" }), 50);
      } finally {
        setCarregando(false);
      }
    },
    [orderId, slug]
  );

  useEffect(() => {
    void buscar(true);
    const relogio = window.setInterval(() => void buscar(false), 10000);
    return () => window.clearInterval(relogio);
  }, [buscar]);

  /* A loja pode estar com a mesma conversa aberta do outro lado. Um aviso no
     canal do fio evita esperar a proxima consulta para a resposta aparecer. */
  useEffect(() => {
    if (!threadId) return;
    const supabase = getSupabaseClient();
    const canal = supabase.channel(`chat-${threadId}`);
    canal.on("broadcast", { event: "novidade" }, () => void buscar(true));
    canal.subscribe();
    return () => {
      void supabase.removeChannel(canal);
    };
  }, [threadId, buscar]);

  /* Quem chegou pelo aviso do celular quer ver a mensagem, e nao o topo de uma
     pagina longa: o endereco traz a ancora e a tela desce sozinha. */
  useEffect(() => {
    if (window.location.hash !== "#conversa-do-pedido") return;
    const alvo = document.getElementById("conversa-do-pedido");
    if (!alvo) return;
    window.setTimeout(() => alvo.scrollIntoView({ behavior: "smooth", block: "start" }), 400);
  }, []);

  async function avisarCanal() {
    if (!threadId) return;
    try {
      const supabase = getSupabaseClient();
      const canal = supabase.channel(`chat-${threadId}`);
      await canal.subscribe();
      await canal.send({ type: "broadcast", event: "novidade", payload: { threadId } });
      window.setTimeout(() => void supabase.removeChannel(canal), 1200);
    } catch {
      /* Sem tempo real, a consulta de dez segundos ainda traz a novidade. */
    }
  }

  async function enviar() {
    if (enviando || (!texto.trim() && !arquivo)) return;

    const corpo = texto.trim();
    const anexo = arquivo;

    /*
      O balao aparece antes de a mensagem existir no banco.

      Quem escreveu ja sabe o que escreveu: esperar a viagem de ida e volta
      para ver o proprio texto e o que fazia a conversa parecer travada. Se o
      envio falhar, o balao some e o texto volta para o campo.
    */
    const provisoria: Mensagem = {
      id: `enviando-${Date.now()}`,
      sender: "client",
      sender_name: "Você",
      body: corpo || null,
      attachment_url: anexo && anexo.type.startsWith("image/") ? URL.createObjectURL(anexo) : null,
      attachment_name: anexo?.name || null,
      attachment_kind: anexo ? (anexo.type.startsWith("image/") ? "image" : "file") : null,
      created_at: new Date().toISOString(),
      pendente: true,
    };

    setMensagens((antes) => [...antes, provisoria]);
    setTexto("");
    setArquivo(null);
    if (campoDeArquivo.current) campoDeArquivo.current.value = "";
    window.setTimeout(() => fimDaLista.current?.scrollIntoView({ block: "end" }), 20);

    setEnviando(true);
    setErro(null);
    try {
      const dados = new FormData();
      dados.set("slug", slug);
      dados.set("orderId", orderId);
      dados.set("body", corpo);
      if (anexo) dados.set("file", anexo);

      const resposta = await fetch("/api/client-portal/order-messages", { method: "POST", body: dados });
      const retorno = (await resposta.json().catch(() => null)) as { error?: string } | null;
      if (!resposta.ok) throw new Error(retorno?.error || "Não foi possível enviar.");

      await buscar(true);
      void avisarCanal();
    } catch (falha) {
      setMensagens((antes) => antes.filter((mensagem) => mensagem.id !== provisoria.id));
      setTexto(corpo);
      setErro(falha instanceof Error ? falha.message : "Não foi possível enviar.");
    } finally {
      setEnviando(false);
    }
  }

  async function decidirArte(messageId: string, decision: "approved" | "rejected", observacao = "") {
    if (decidindo) return;

    /* Reprovar sem dizer o motivo faz a loja adivinhar: a caixa de ajuste vem
       antes do envio. */
    if (decision === "rejected" && !observacao) {
      setAjusteDaArte(messageId);
      setNotaDoAjuste("");
      return;
    }

    setDecidindo(messageId);
    setErro(null);
    try {
      const nota = observacao.slice(0, 500);
      const resposta = await fetch("/api/client-portal/order-messages", {
        method: "PATCH",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({ slug, orderId, messageId, decision, note: nota }),
      });
      const retorno = (await resposta.json().catch(() => null)) as { error?: string } | null;
      if (!resposta.ok) throw new Error(retorno?.error || "Não foi possível registrar sua resposta.");
      setImagemAberta(null);
      setAjusteDaArte(null);
      setNotaDoAjuste("");
      await buscar(true);
      void avisarCanal();
    } catch (falha) {
      setErro(falha instanceof Error ? falha.message : "Não foi possível registrar sua resposta.");
    } finally {
      setDecidindo(null);
    }
  }

  let ultimoDia = "";

  return (
    <section id="conversa-do-pedido" className="border border-[#efedf2] bg-white">
      <div className="flex items-center justify-between gap-3 border-b border-[#efedf2] px-4 py-3.5 sm:px-6">
        <div className="min-w-0">
          <div className="text-[15px] font-semibold text-zinc-900">Conversa com a loja</div>
          <div className="text-[12px] text-zinc-500">Combine detalhes, envie arquivos e aprove a arte por aqui.</div>
        </div>
        {/* Quem pergunta a noite nao deveria precisar voltar aqui de hora em
            hora para saber se ja responderam. */}
        <AtivarAvisosDoCliente slug={slug} primaryColor={primaryColor} />
      </div>

      <div className="max-h-[450px] min-h-[240px] overflow-y-auto bg-[#f6f5f8] px-4 py-4 sm:px-6">
        {carregando ? (
          <div className="py-12 text-center text-[13px] text-zinc-500">Carregando a conversa...</div>
        ) : mensagens.length === 0 ? (
          <div className="py-12 text-center text-[13px] text-zinc-500">
            Nenhuma mensagem ainda. Escreva abaixo para falar com a loja sobre este pedido.
          </div>
        ) : (
          mensagens.map((mensagem, indice) => {
            const doCliente = mensagem.sender === "client";
            const dia = rotuloDoDia(mensagem.created_at);
            const mostrarDia = dia !== ultimoDia;
            ultimoDia = dia;

            const anterior = indice > 0 ? mensagens[indice - 1] : null;
            const seguinte = indice < mensagens.length - 1 ? mensagens[indice + 1] : null;
            const perto = (a?: Mensagem | null, b?: Mensagem | null) =>
              Boolean(
                a &&
                  b &&
                  a.sender === b.sender &&
                  Math.abs(new Date(b.created_at).getTime() - new Date(a.created_at).getTime()) <
                    INTERVALO_DE_AGRUPAMENTO_MS
              );
            const continuaBloco = !mostrarDia && perto(anterior, mensagem);
            const fechaBloco = !perto(mensagem, seguinte);

            const apagada = Boolean(mensagem.deleted_at);
            const situacaoDaArte = String(mensagem.art_status || "pending");
            const arteEmAberto = Boolean(mensagem.is_art) && situacaoDaArte === "pending";
            const lida = doCliente ? Boolean(mensagem.read_by_store_at) : Boolean(mensagem.read_by_client_at);

            return (
              <div key={mensagem.id}>
                {mostrarDia ? (
                  <div className="my-4 flex justify-center">
                    <span className="rounded-md bg-white px-2.5 py-1 text-[11px] font-medium text-zinc-500 shadow-[0_1px_2px_rgba(16,24,40,0.06)]">
                      {dia}
                    </span>
                  </div>
                ) : null}

                <div
                  className={`flex items-end gap-2 ${doCliente ? "justify-end" : "justify-start"} ${
                    continuaBloco ? "mt-0.5" : "mt-3"
                  }`}
                >
                  {!doCliente ? (
                    <div className="w-7 shrink-0">
                      {fechaBloco ? (
                        <span className="flex h-7 w-7 items-center justify-center rounded-full bg-white text-[10px] font-bold text-zinc-500 shadow-[0_1px_2px_rgba(16,24,40,0.08)]">
                          {iniciais(nomeDaLoja || mensagem.sender_name)}
                        </span>
                      ) : null}
                    </div>
                  ) : null}

                  <div className="max-w-[78%]">
                    <div
                      className={`px-3 py-2 text-[13px] leading-6 shadow-[0_1px_2px_rgba(16,24,40,0.08)] ${
                        doCliente ? "" : "border border-[#efedf2] bg-white text-zinc-900"
                      } ${
                        doCliente
                          ? `rounded-2xl ${fechaBloco ? "rounded-br-md" : ""}`
                          : `rounded-2xl ${fechaBloco ? "rounded-bl-md" : ""}`
                      }`}
                      style={
                        doCliente
                          ? { backgroundColor: primaryColor, color: getReadableTextColor(primaryColor) }
                          : undefined
                      }
                    >
                      {apagada ? (
                        <span className={doCliente ? "italic opacity-70" : "italic text-zinc-400"}>
                          Esta mensagem foi apagada
                        </span>
                      ) : (
                        <>
                          {mensagem.attachment_url && mensagem.attachment_kind === "image" ? (
                            <button
                              type="button"
                              onClick={() =>
                                setImagemAberta({
                                  url: mensagem.attachment_url || "",
                                  nome: mensagem.attachment_name,
                                  arteId: arteEmAberto ? mensagem.id : null,
                                })
                              }
                              className="mb-1.5 block w-full"
                            >
                              <Image
                                src={mensagem.attachment_url}
                                alt={mensagem.attachment_name || "Anexo"}
                                width={360}
                                height={360}
                                unoptimized
                                className="max-h-[260px] w-full rounded-xl object-cover"
                              />
                            </button>
                          ) : null}

                          {mensagem.attachment_url && mensagem.attachment_kind !== "image" ? (
                            <a
                              href={mensagem.attachment_url}
                              target="_blank"
                              rel="noreferrer"
                              className={`mb-1.5 flex items-center gap-2 rounded-xl px-2.5 py-2 text-[12px] font-medium ${
                                doCliente ? "bg-white/15" : "bg-[#f2f1f5]"
                              }`}
                            >
                              <FileText className="h-4 w-4 shrink-0" />
                              <span className="truncate">{mensagem.attachment_name || "Arquivo"}</span>
                            </a>
                          ) : null}

                          {mensagem.card ? <CartaoDaMensagem cartao={mensagem.card} doCliente={doCliente} /> : null}

                          {mensagem.body ? <p className="whitespace-pre-wrap">{mensagem.body}</p> : null}

                          {mensagem.is_art ? (
                            <div className="mt-2 rounded-xl border border-[#efedf2] bg-white/95 p-2.5 text-zinc-900">
                              <div className="text-[11px] font-semibold uppercase tracking-[0.12em] text-zinc-400">
                                Arte para aprovação
                              </div>
                              <div className="mt-0.5 text-[12px] font-medium text-zinc-700">
                                {TEXTO_DA_ARTE[situacaoDaArte] || TEXTO_DA_ARTE.pending}
                              </div>

                              {arteEmAberto ? (
                                <BotoesDaArte
                                  ocupado={decidindo === mensagem.id}
                                  aoAprovar={() => void decidirArte(mensagem.id, "approved")}
                                  aoPedirAjuste={() => void decidirArte(mensagem.id, "rejected")}
                                />
                              ) : null}

                              {mensagem.art_decision_note ? (
                                <p className="mt-1.5 text-[12px] text-zinc-500">“{mensagem.art_decision_note}”</p>
                              ) : null}
                            </div>
                          ) : null}
                        </>
                      )}

                      {fechaBloco ? (
                        <div
                          className={`mt-1 flex items-center justify-end gap-1 text-[10px] ${
                            doCliente ? "opacity-70" : "text-zinc-400"
                          }`}
                        >
                          {hora(mensagem.created_at)}
                          {mensagem.pendente ? (
                            <Clock3 className="h-3 w-3" />
                          ) : doCliente ? (
                            lida ? (
                              <CheckCheck className="h-3.5 w-3.5 text-emerald-400" />
                            ) : (
                              <CheckCheck className="h-3.5 w-3.5" />
                            )
                          ) : (
                            <Check className="h-3.5 w-3.5" />
                          )}
                        </div>
                      ) : null}
                    </div>
                  </div>
                </div>
              </div>
            );
          })
        )}
        <div ref={fimDaLista} />
      </div>

      <div className="border-t border-[#efedf2] bg-white p-3 sm:px-6 sm:py-4">
        {arquivo ? (
          <div className="mb-2 flex items-center gap-2 rounded-xl bg-[#f6f5f8] px-3 py-2 text-[12px]">
            <Paperclip className="h-3.5 w-3.5 text-zinc-500" />
            <span className="max-w-[220px] truncate font-medium">{arquivo.name}</span>
            <button
              type="button"
              onClick={() => {
                setArquivo(null);
                if (campoDeArquivo.current) campoDeArquivo.current.value = "";
              }}
              className="ml-auto inline-flex h-6 w-6 items-center justify-center rounded-full text-zinc-400 hover:bg-white"
              aria-label="Remover anexo"
            >
              <X className="h-3.5 w-3.5" />
            </button>
          </div>
        ) : null}

        {erro ? <div className="mb-2 text-[12px] font-medium text-rose-600">{erro}</div> : null}

        <div className="flex items-end gap-2 rounded-2xl border border-[#efedf2] bg-white px-2 py-1.5">
          <input
            ref={campoDeArquivo}
            type="file"
            className="hidden"
            onChange={(evento) => setArquivo(evento.target.files?.[0] || null)}
          />
          <button
            type="button"
            onClick={() => campoDeArquivo.current?.click()}
            disabled={enviando}
            aria-label="Anexar arquivo"
            className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-zinc-400 transition hover:bg-[#f6f5f8] hover:text-zinc-700"
          >
            <Paperclip className="h-4 w-4" />
          </button>

          <textarea
            value={texto}
            onChange={(evento) => setTexto(evento.target.value)}
            onKeyDown={(evento) => {
              if (evento.key === "Enter" && !evento.shiftKey) {
                evento.preventDefault();
                void enviar();
              }
            }}
            rows={1}
            placeholder="Escreva uma mensagem"
            className="max-h-28 min-h-[36px] flex-1 resize-none border-0 bg-transparent px-1 py-2 text-[13px] outline-none"
          />

          <button
            type="button"
            onClick={() => void enviar()}
            disabled={enviando || (!texto.trim() && !arquivo)}
            aria-label="Enviar mensagem"
            className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full transition disabled:opacity-35"
            style={{ backgroundColor: primaryColor, color: getReadableTextColor(primaryColor) }}
          >
            <Send className="h-4 w-4" />
          </button>
        </div>
      </div>

      {imagemAberta ? (
        <VisualizadorDeImagem
          url={imagemAberta.url}
          nome={imagemAberta.nome}
          arteEmAberto={Boolean(imagemAberta.arteId)}
          ocupado={decidindo === imagemAberta.arteId}
          aoAprovar={() => imagemAberta.arteId && void decidirArte(imagemAberta.arteId, "approved")}
          aoPedirAjuste={() => imagemAberta.arteId && void decidirArte(imagemAberta.arteId, "rejected")}
          aoFechar={() => setImagemAberta(null)}
        />
      ) : null}

      {ajusteDaArte ? (
        <div
          role="dialog"
          aria-modal="true"
          onClick={() => setAjusteDaArte(null)}
          className="fixed inset-0 z-[120] flex items-center justify-center bg-[rgba(12,8,24,0.45)] p-5 backdrop-blur-[2px]"
        >
          <div
            onClick={(evento) => evento.stopPropagation()}
            className="w-[min(420px,100%)] rounded-2xl bg-white p-5 shadow-[0_24px_60px_rgba(15,23,42,0.3)]"
          >
            <div className="text-[16px] font-bold text-zinc-900">O que precisa mudar na arte?</div>
            <p className="mt-1 text-[12.5px] leading-5 text-zinc-500">
              Escreva com suas palavras — quanto mais claro, menos idas e vindas até ficar do seu jeito.
            </p>
            <textarea
              autoFocus
              value={notaDoAjuste}
              onChange={(evento) => setNotaDoAjuste(evento.target.value.slice(0, 500))}
              rows={4}
              placeholder="Ex: o logo está pequeno e o telefone saiu errado."
              className="mt-3 w-full resize-none rounded-xl border border-[#e6e6f2] px-3 py-2 text-[13px] outline-none focus:border-zinc-400"
            />
            <div className="mt-3 flex justify-end gap-2">
              <button
                type="button"
                onClick={() => setAjusteDaArte(null)}
                className="h-9 rounded-xl bg-[#f1f0f7] px-4 text-[13px] font-bold text-zinc-500 transition hover:bg-[#e6e6f2]"
              >
                Cancelar
              </button>
              <button
                type="button"
                disabled={!notaDoAjuste.trim() || Boolean(decidindo)}
                onClick={() => void decidirArte(ajusteDaArte, "rejected", notaDoAjuste.trim())}
                className="h-9 rounded-xl px-4 text-[13px] font-bold text-white transition disabled:opacity-40"
                style={{ backgroundColor: primaryColor, color: getReadableTextColor(primaryColor) }}
              >
                Enviar pedido de ajuste
              </button>
            </div>
          </div>
        </div>
      ) : null}
    </section>
  );
}
