import { useState, useRef, useEffect, useCallback } from "react";
import { useParams, useLocation, useNavigate } from "react-router-dom";
import {
  AlignJustify,
  ArrowLeft,
  BookOpen,
  ChevronsLeft,
  ChevronsRight,
  Copy,
  Download,
  FileDown,
  GripHorizontal,
  History,
  Info,
  Loader2,
  Maximize2,
  MessageSquare,
  Minimize2,
  Minus,
  Pause,
  Pencil,
  Play,
  Plus,
  RotateCcw,
  Send,
  Trash2,
} from "lucide-react";
import ReactMarkdown from "react-markdown";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Textarea } from "@/components/ui/textarea";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import {
  AlertDialog,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { usePrompts } from "@/contexts/PromptsContext";
import { parecerService, type ParecerChatHistoricoItem, type ParecerDetalhe, type ParecerChatModo } from "@/services/parecerApi";
import { ParecerJuridicoGeneratingScreen } from "@/components/parecer-juridico/ParecerJuridicoGeneratingScreen";
import { playSuccessSound } from "@/utils/sound";
import { toast } from "sonner";
import { cn } from "@/lib/utils";

function formatarDataDetalhe(iso: string): string {
  if (!iso) return "—";
  try {
    return new Date(iso.replace(" ", "T")).toLocaleString("pt-BR");
  } catch {
    return iso;
  }
}

/** Evita exibir expressões n8n ($('...')) como nome de usuário. */
function textoAtualizadoPorValido(val: string | null | undefined): string | null {
  const v = val?.trim();
  if (!v) return null;
  if (v.includes("$(") || v.includes("{{") || v.startsWith("$")) return null;
  return v;
}

function textoUsuarioParecer(p: ParecerDetalhe): string {
  const email = p.user_email?.trim();
  const criado = p.criado_por?.trim();
  return email || criado || "—";
}

interface ParecerPreviewState {
  titulo?: string;
  conteudoMarkdown?: string;
}

interface ChatMessage {
  id: string;
  role: "user" | "assistant";
  content: string;
  created_at?: string;
  user_email?: string;
  tipo_resposta?: "chat" | "agente" | null;
}

const LS_READER_FONT = "codex-parecer-reader-font-step";
const LS_READER_WIDTH = "codex-parecer-reader-comfortable-width";
const LS_MAIN_COMFORTABLE = "codex-parecer-main-comfortable-width";

/** Velocidade do auto-scroll (px/s): nível 1 mais lento … 5 mais rápido (progressão mais perceptível). */
const READER_AUTO_SCROLL_SPEEDS = [42, 68, 98, 138, 195] as const;

const READER_AUTO_SCROLL_LEVEL_LABELS = ["Lento", "Médio-lento", "Médio", "Médio-rápido", "Rápido"] as const;

const READER_FONT_DEFAULT = 1;

function readStoredReaderFontStep(): number {
  if (typeof window === "undefined") return READER_FONT_DEFAULT;
  try {
    const raw = window.localStorage.getItem(LS_READER_FONT);
    if (raw == null) return READER_FONT_DEFAULT;
    const n = Number.parseInt(raw, 10);
    if (Number.isNaN(n)) return READER_FONT_DEFAULT;
    return Math.min(4, Math.max(0, n));
  } catch {
    return READER_FONT_DEFAULT;
  }
}

function readStoredReaderComfortableWidth(): boolean {
  if (typeof window === "undefined") return true;
  try {
    const raw = window.localStorage.getItem(LS_READER_WIDTH);
    if (raw == null) return true;
    return raw === "1" || raw === "true";
  } catch {
    return true;
  }
}

function readStoredMainComfortableWidth(): boolean {
  if (typeof window === "undefined") return false;
  try {
    const raw = window.localStorage.getItem(LS_MAIN_COMFORTABLE);
    if (raw == null) return false;
    return raw === "1" || raw === "true";
  } catch {
    return false;
  }
}

/** Índice 0–4 mapeado para classes `prose-*` do plugin Typography. */
const READER_PROSE_SCALE = ["prose-sm", "prose-base", "prose-lg", "prose-xl", "prose-2xl"] as const;

const READER_PROSE_COMMON =
  "prose-neutral dark:prose-invert w-full text-foreground prose-headings:font-semibold prose-p:leading-relaxed prose-ul:my-3 prose-ol:my-3 prose-li:my-0.5";

const READER_PANEL_FULLSCREEN_ID = "parecer-reader-panel";

export function ParecerJuridicoDetailView() {
  const { id } = useParams<{ id: string }>();
  const location = useLocation();
  const navigate = useNavigate();
  const preview = (location.state as ParecerPreviewState | undefined) ?? undefined;

  const [parecer, setParecer] = useState<ParecerDetalhe | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [exportingDocx, setExportingDocx] = useState(false);
  const [detailsOpen, setDetailsOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const { areaItems, refreshAreas } = usePrompts();

  const [editOpen, setEditOpen] = useState(false);
  const [editTitulo, setEditTitulo] = useState("");
  const [editAreaId, setEditAreaId] = useState("");
  const [editSaving, setEditSaving] = useState(false);

  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [chatLoading, setChatLoading] = useState(true);
  const [chatProcessing, setChatProcessing] = useState(false);
  const [chatInlineLoading, setChatInlineLoading] = useState(false);
  const [modo, setModo] = useState<ParecerChatModo>("agente");
  const [conteudoAtualizadoChat, setConteudoAtualizadoChat] = useState<string | null>(null);
  const [historicoOpen, setHistoricoOpen] = useState(false);
  const [historicoLoading, setHistoricoLoading] = useState(false);
  const [historicoItem, setHistoricoItem] = useState<ParecerChatHistoricoItem | null>(null);
  const [chatInput, setChatInput] = useState("");
  /** Painel lateral de chat: recolhido dá mais área à leitura do parecer. */
  const [chatPanelExpanded, setChatPanelExpanded] = useState(true);
  const [readerModeOpen, setReaderModeOpen] = useState(false);
  const [readerFontStep, setReaderFontStep] = useState(readStoredReaderFontStep);
  const [readerComfortableWidth, setReaderComfortableWidth] = useState(readStoredReaderComfortableWidth);
  const [mainComfortableWidth, setMainComfortableWidth] = useState(readStoredMainComfortableWidth);
  const [readerAutoScrollPlaying, setReaderAutoScrollPlaying] = useState(false);
  /** Nível 1–5 (x1…x5) para velocidade do auto-scroll. */
  const [readerAutoScrollSpeedLevel, setReaderAutoScrollSpeedLevel] = useState(3);
  const readerPanelRef = useRef<HTMLDivElement>(null);
  const [readerIsFullscreen, setReaderIsFullscreen] = useState(false);
  const readerScrollRef = useRef<HTMLDivElement>(null);
  const readerAutoScrollRafRef = useRef<number>(0);
  const readerAutoScrollLastTsRef = useRef(0);
  const readerAutoScrollProgrammaticRef = useRef(false);
  const readerAutoScrollPlayingRef = useRef(false);
  /** Acumula frações de px para velocidades baixas não ficarem presas em scrollTop inteiro. */
  const readerAutoScrollCarryRef = useRef(0);
  const chatInputRef = useRef<HTMLTextAreaElement>(null);
  const [textareaHeight, setTextareaHeight] = useState(60);
  const [isDragging, setIsDragging] = useState(false);
  const dragStartY = useRef(0);
  const dragStartHeight = useRef(0);
  const chatEndRef = useRef<HTMLDivElement>(null);

  /** Preenche título e área com os dados atuais do parecer (sempre que abrir o modal de edição). */
  const aplicarDadosAtuaisNoFormularioEdicao = useCallback(() => {
    if (!parecer) return;
    setEditTitulo(parecer.titulo?.trim() ?? "");
    setEditAreaId(parecer.area_id?.trim() ?? "");
  }, [parecer]);

  const openEditModal = useCallback(() => {
    aplicarDadosAtuaisNoFormularioEdicao();
    setEditOpen(true);
  }, [aplicarDadosAtuaisNoFormularioEdicao]);

  /** Fecha detalhes e abre edição já com título e área atuais. */
  const openEditFromDetailsModal = useCallback(() => {
    aplicarDadosAtuaisNoFormularioEdicao();
    setDetailsOpen(false);
    setEditOpen(true);
  }, [aplicarDadosAtuaisNoFormularioEdicao]);

  const syncReaderFullscreen = useCallback(() => {
    setReaderIsFullscreen(document.fullscreenElement?.id === READER_PANEL_FULLSCREEN_ID);
  }, []);

  const toggleReaderFullscreen = useCallback(async () => {
    const el = readerPanelRef.current;
    if (!el) return;
    try {
      if (document.fullscreenElement?.id === READER_PANEL_FULLSCREEN_ID) {
        await document.exitFullscreen();
      } else {
        await el.requestFullscreen();
      }
    } catch {
      toast.error("Tela cheia não disponível neste navegador ou foi bloqueada.");
    }
  }, []);

  const MIN_INPUT_HEIGHT = 60;
  const MAX_INPUT_HEIGHT = 400;

  const hasPreview = Boolean(preview?.conteudoMarkdown?.trim() || preview?.titulo);

  useEffect(() => {
    if (!id?.trim()) {
      setError("ID inválido");
      setLoading(false);
      return;
    }
    setLoading(true);
    setError(null);
    parecerService
      .buscarPorId(id)
      .then(setParecer)
      .catch((e) => {
        const msg = e?.message ?? "Erro ao carregar parecer";
        if (!hasPreview) {
          setError(msg);
          toast.error(msg);
        } else {
          toast.error(msg);
        }
      })
      .finally(() => setLoading(false));
  }, [id]);

  useEffect(() => {
    refreshAreas();
  }, [refreshAreas]);

  const carregarChat = useCallback(
    async (silent = false) => {
      if (!id?.trim()) return;
      if (!silent) setChatLoading(true);
      try {
        const rows = await parecerService.listarChat(id);
        const sorted = [...rows].sort(
          (a, b) =>
            new Date(a.created_at.replace(" ", "T")).getTime() -
            new Date(b.created_at.replace(" ", "T")).getTime()
        );
        const nonEmptyMessages = sorted.filter((m) => (m.content ?? "").trim().length > 0);
        setMessages(
          nonEmptyMessages.map((m) => ({
            id: m.id,
            role: m.role,
            content: m.content,
            created_at: m.created_at,
            user_email: m.user_email,
            tipo_resposta: m.tipo_resposta ?? null,
          }))
        );
      } catch {
        if (!silent) toast.error("Não foi possível carregar o histórico do chat.");
        if (!silent) setMessages([]);
      } finally {
        if (!silent) setChatLoading(false);
      }
    },
    [id]
  );

  useEffect(() => {
    carregarChat(false);
    // eslint-disable-next-line react-hooks/exhaustive-deps -- recarregar só ao mudar parecer
  }, [id]);

  useEffect(() => {
    setConteudoAtualizadoChat(null);
  }, [id]);

  const handleResizeMouseDown = (e: React.MouseEvent) => {
    setIsDragging(true);
    dragStartY.current = e.clientY;
    dragStartHeight.current = textareaHeight;
    e.preventDefault();
  };

  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      if (!isDragging) return;
      const deltaY = dragStartY.current - e.clientY;
      const newHeight = Math.min(MAX_INPUT_HEIGHT, Math.max(MIN_INPUT_HEIGHT, dragStartHeight.current + deltaY));
      setTextareaHeight(newHeight);
    };
    const handleMouseUp = () => setIsDragging(false);
    if (isDragging) {
      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
    }
    return () => {
      document.removeEventListener("mousemove", handleMouseMove);
      document.removeEventListener("mouseup", handleMouseUp);
    };
  }, [isDragging]);

  useEffect(() => {
    const el = chatInputRef.current;
    if (!el) return;
    const need = el.scrollHeight;
    if (need > textareaHeight) {
      setTextareaHeight((h) => Math.min(MAX_INPUT_HEIGHT, Math.max(h, need)));
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [chatInput]);

  useEffect(() => {
    if (messages.length === 0) return;
    const t = requestAnimationFrame(() => {
      chatEndRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
    });
    return () => cancelAnimationFrame(t);
  }, [messages]);

  useEffect(() => {
    try {
      window.localStorage.setItem(LS_READER_FONT, String(readerFontStep));
    } catch {
      /* ignore */
    }
  }, [readerFontStep]);

  useEffect(() => {
    try {
      window.localStorage.setItem(LS_READER_WIDTH, readerComfortableWidth ? "1" : "0");
    } catch {
      /* ignore */
    }
  }, [readerComfortableWidth]);

  useEffect(() => {
    try {
      window.localStorage.setItem(LS_MAIN_COMFORTABLE, mainComfortableWidth ? "1" : "0");
    } catch {
      /* ignore */
    }
  }, [mainComfortableWidth]);

  useEffect(() => {
    readerAutoScrollPlayingRef.current = readerAutoScrollPlaying;
  }, [readerAutoScrollPlaying]);

  useEffect(() => {
    document.addEventListener("fullscreenchange", syncReaderFullscreen);
    return () => document.removeEventListener("fullscreenchange", syncReaderFullscreen);
  }, [syncReaderFullscreen]);

  useEffect(() => {
    readerAutoScrollCarryRef.current = 0;
  }, [readerAutoScrollSpeedLevel]);

  useEffect(() => {
    if (!readerModeOpen) {
      if (document.fullscreenElement?.id === READER_PANEL_FULLSCREEN_ID) {
        void document.exitFullscreen().catch(() => {});
      }
      setReaderIsFullscreen(false);
      setReaderAutoScrollPlaying(false);
      readerAutoScrollPlayingRef.current = false;
      readerAutoScrollLastTsRef.current = 0;
      readerAutoScrollCarryRef.current = 0;
      if (readerAutoScrollRafRef.current) {
        cancelAnimationFrame(readerAutoScrollRafRef.current);
        readerAutoScrollRafRef.current = 0;
      }
    }
  }, [readerModeOpen]);

  useEffect(() => {
    if (!readerAutoScrollPlaying) readerAutoScrollCarryRef.current = 0;
  }, [readerAutoScrollPlaying]);

  useEffect(() => {
    const el = readerScrollRef.current;
    if (!el || !readerModeOpen) return;
    const pause = () => setReaderAutoScrollPlaying(false);
    const onScroll = () => {
      if (readerAutoScrollProgrammaticRef.current) return;
      pause();
    };
    const onWheel = () => pause();
    const onTouchMove = () => pause();
    el.addEventListener("scroll", onScroll, { passive: true });
    el.addEventListener("wheel", onWheel, { passive: true });
    el.addEventListener("touchmove", onTouchMove, { passive: true });
    return () => {
      el.removeEventListener("scroll", onScroll);
      el.removeEventListener("wheel", onWheel);
      el.removeEventListener("touchmove", onTouchMove);
    };
  }, [readerModeOpen]);

  useEffect(() => {
    if (!readerModeOpen || !readerAutoScrollPlaying) {
      if (readerAutoScrollRafRef.current) {
        cancelAnimationFrame(readerAutoScrollRafRef.current);
        readerAutoScrollRafRef.current = 0;
      }
      readerAutoScrollLastTsRef.current = 0;
      return;
    }
    const el = readerScrollRef.current;
    if (!el) return;

    const levelIdx = Math.min(4, Math.max(0, readerAutoScrollSpeedLevel - 1));
    const speedPxPerSec = READER_AUTO_SCROLL_SPEEDS[levelIdx] ?? READER_AUTO_SCROLL_SPEEDS[2];

    const tick = (ts: number) => {
      const scrollEl = readerScrollRef.current;
      if (!scrollEl || !readerAutoScrollPlayingRef.current) return;

      if (!readerAutoScrollLastTsRef.current) readerAutoScrollLastTsRef.current = ts;
      const dt = Math.min(80, ts - readerAutoScrollLastTsRef.current) / 1000;
      readerAutoScrollLastTsRef.current = ts;

      readerAutoScrollCarryRef.current += speedPxPerSec * dt;
      const pixels = Math.floor(readerAutoScrollCarryRef.current);
      readerAutoScrollCarryRef.current -= pixels;
      if (pixels > 0) {
        readerAutoScrollProgrammaticRef.current = true;
        scrollEl.scrollTop += pixels;
        requestAnimationFrame(() => {
          readerAutoScrollProgrammaticRef.current = false;
        });
      }

      const maxScroll = scrollEl.scrollHeight - scrollEl.clientHeight;
      if (maxScroll <= 0 || scrollEl.scrollTop >= maxScroll - 1) {
        setReaderAutoScrollPlaying(false);
        return;
      }

      readerAutoScrollRafRef.current = requestAnimationFrame(tick);
    };

    readerAutoScrollLastTsRef.current = 0;
    readerAutoScrollRafRef.current = requestAnimationFrame(tick);

    return () => {
      if (readerAutoScrollRafRef.current) {
        cancelAnimationFrame(readerAutoScrollRafRef.current);
        readerAutoScrollRafRef.current = 0;
      }
      readerAutoScrollLastTsRef.current = 0;
    };
  }, [readerModeOpen, readerAutoScrollPlaying, readerAutoScrollSpeedLevel]);

  const titulo = parecer?.titulo ?? preview?.titulo ?? "Parecer";
  const conteudoMarkdown =
    parecer?.conteudo_gerado ?? conteudoAtualizadoChat ?? preview?.conteudoMarkdown ?? "";

  const handleExport = async () => {
    const fileName = titulo.slice(0, 80).replace(/\s+/g, "-").replace(/[^\w-]/g, "") || "parecer";
    const text = conteudoMarkdown;
    setExportingDocx(true);
    try {
      const res = await fetch("https://codex-api.hgtx.com.br/api/Document/generate-docx", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ text, fileName }),
      });
      if (!res.ok) {
        const errText = await res.text();
        throw new Error(errText || `Erro ${res.status}`);
      }
      const blob = await res.blob();
      const disposition = res.headers.get("Content-Disposition");
      const match = disposition?.match(/filename\*?=(?:UTF-8'')?"?([^";\n]+)"?/i) || disposition?.match(/filename="?([^";\n]+)"?/i);
      const downloadName = match ? match[1].trim() : `${fileName}.docx`;
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = downloadName.endsWith(".docx") ? downloadName : `${downloadName}.docx`;
      a.click();
      URL.revokeObjectURL(url);
      toast.success("Documento DOCX gerado e baixado.");
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Erro ao gerar DOCX.");
    } finally {
      setExportingDocx(false);
    }
  };

  const handleDownloadAnexo = async () => {
    if (!parecer?.anexo_url) return;
    try {
      const response = await fetch(parecer.anexo_url);
      if (!response.ok) {
        throw new Error(`Erro ${response.status} ao baixar anexo.`);
      }

      const blob = await response.blob();
      const fallbackName = parecer.anexo_nome?.trim() || "anexo";
      const disposition = response.headers.get("Content-Disposition");
      const match = disposition?.match(/filename\*?=(?:UTF-8'')?"?([^";\n]+)"?/i) || disposition?.match(/filename="?([^";\n]+)"?/i);
      const fileName = match ? decodeURIComponent(match[1].trim()) : fallbackName;

      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = fileName;
      a.click();
      URL.revokeObjectURL(url);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Erro ao baixar anexo.");
    }
  };

  const handleSalvarEdicao = async () => {
    if (!id?.trim()) return;
    const tituloTrim = editTitulo.trim();
    const areaTrim = editAreaId.trim();

    if (!tituloTrim || !areaTrim) {
      toast.error("Título e área são obrigatórios.");
      return;
    }

    setEditSaving(true);
    try {
      await parecerService.editarTituloArea(id, { titulo: tituloTrim, area_id: areaTrim });
      const updated = await parecerService.buscarPorId(id);
      setParecer(updated);
      setConteudoAtualizadoChat(null);
      setEditOpen(false);
      playSuccessSound();
      toast.success("Parecer atualizado.");
    } catch (e: unknown) {
      const message =
        e && typeof e === "object" && "message" in e ? String((e as { message: string }).message) : "Erro ao atualizar parecer.";
      toast.error(message);
    } finally {
      setEditSaving(false);
    }
  };

  const handleExcluirParecer = () => {
    if (!id?.trim()) return;
    setDeleting(true);
    parecerService
      .excluir(id)
      .then((res) => {
        toast.success(res.message);
        setDeleteOpen(false);
        navigate("/codex/parecer-juridico");
      })
      .catch((e) => {
        toast.error(e?.message ?? "Erro ao excluir parecer.");
      })
      .finally(() => setDeleting(false));
  };

  const abrirHistoricoResposta = (messageId: string) => {
    setHistoricoOpen(true);
    setHistoricoLoading(true);
    setHistoricoItem(null);
    parecerService
      .buscarHistoricoChatMensagem(messageId)
      .then(setHistoricoItem)
      .catch((e) => {
        toast.error(e?.message ?? "Erro ao carregar histórico.");
        setHistoricoOpen(false);
      })
      .finally(() => setHistoricoLoading(false));
  };

  const copiarTexto = async (texto: string, label: string) => {
    try {
      await navigator.clipboard.writeText(texto);
      toast.success(`${label} copiado.`);
    } catch {
      toast.error("Não foi possível copiar.");
    }
  };

  const handleSendMessage = () => {
    const text = chatInput.trim();
    if (!text || !id?.trim() || chatProcessing) return;
    const isChatMode = modo === "chat";
    const tinhaParecer = parecer != null;
    setChatInput("");
    if (isChatMode) {
      setChatInlineLoading(true);
      // Garante que o usuário veja imediatamente o loading no final do chat.
      requestAnimationFrame(() => {
        chatEndRef.current?.scrollIntoView({ behavior: "smooth", block: "end" });
      });
    }
    setChatProcessing(true);
    parecerService
      .enviarMensagemChat(id, text, modo)
      .then(async (res) => {
        if (!isChatMode && "conteudo_gerado" in res) {
          if (tinhaParecer) {
            setParecer((p) => (p ? { ...p, conteudo_gerado: res.conteudo_gerado } : p));
          } else {
            setConteudoAtualizadoChat(res.conteudo_gerado);
          }
        }
        await carregarChat(true);

        if (!isChatMode) {
          // Garante que o modal de detalhes reflita também metadados atualizados
          // (ex.: "Atualizado em"), não só o conteúdo retornado no chat.
          try {
            const updatedParecer = await parecerService.buscarPorId(id);
            setParecer(updatedParecer);
            setConteudoAtualizadoChat(null);
          } catch {
            // Não bloqueia o fluxo do chat se a recarga falhar.
          }
        }

        playSuccessSound();
        toast.success(isChatMode ? "Resposta enviada ao chat." : "Parecer atualizado conforme sua solicitação.");
      })
      .catch((e) => {
        toast.error(e?.message ?? "Erro ao enviar mensagem.");
      })
      .finally(() => {
        setChatProcessing(false);
        setChatInlineLoading(false);
      });
  };

  if (!id?.trim()) {
    return (
      <div className="flex flex-col h-full bg-background p-6">
        <Button variant="ghost" onClick={() => navigate("/codex/parecer-juridico")} className="w-fit gap-2">
          <ArrowLeft className="w-4 h-4" />
          Voltar
        </Button>
        <Card className="max-w-md mt-8 mx-auto">
          <CardHeader>
            <CardTitle>ID inválido</CardTitle>
          </CardHeader>
        </Card>
      </div>
    );
  }

  if (loading && !hasPreview && !parecer) {
    return (
      <div className="flex flex-col h-full bg-background items-center justify-center gap-4 p-6">
        <Loader2 className="w-10 h-10 animate-spin text-muted-foreground" />
        <p className="text-sm text-muted-foreground">Carregando parecer...</p>
      </div>
    );
  }

  if (error && !parecer && !hasPreview) {
    return (
      <div className="flex flex-col h-full bg-background p-6">
        <Button variant="ghost" onClick={() => navigate("/codex/parecer-juridico")} className="w-fit gap-2">
          <ArrowLeft className="w-4 h-4" />
          Voltar
        </Button>
        <Card className="max-w-md mt-8 mx-auto">
          <CardHeader>
            <CardTitle>Não foi possível carregar o parecer</CardTitle>
          </CardHeader>
          <CardContent>
            <p className="text-muted-foreground text-sm">{error}</p>
          </CardContent>
        </Card>
      </div>
    );
  }

  return (
    <>
      {chatProcessing && modo === "agente" && (
        <ParecerJuridicoGeneratingScreen message="Processando sua solicitação no chat. Isso pode levar vários minutos. Mantenha esta tela aberta até finalizar." />
      )}
    <div className="flex flex-col h-full bg-background pb-16 md:pb-0">
      <header className="shrink-0 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between p-3 md:p-6 border-b border-border">
        <div className="flex items-center gap-2 min-w-0 flex-1">
          <Button variant="ghost" size="icon" onClick={() => navigate("/codex/parecer-juridico")} className="shrink-0">
            <ArrowLeft className="w-4 h-4" />
          </Button>
          <h1 className="text-lg md:text-xl font-bold truncate flex-1">{titulo}</h1>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="gap-2"
            disabled={!parecer || !id || editSaving}
            onClick={openEditModal}
          >
            <Pencil className="w-4 h-4" />
            Editar
          </Button>
          {loading && hasPreview && (
            <Loader2 className="w-4 h-4 shrink-0 animate-spin text-muted-foreground" aria-label="Sincronizando" />
          )}
        </div>
        <div className="flex flex-wrap items-center gap-2 justify-end">
          {!chatPanelExpanded && (
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="gap-2 shrink-0"
              onClick={() => setChatPanelExpanded(true)}
              aria-expanded={false}
              aria-controls="parecer-chat-panel"
            >
              <MessageSquare className="w-4 h-4" />
              <span className="hidden sm:inline">Mostrar chat</span>
              <span className="sm:hidden">Chat</span>
            </Button>
          )}
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="gap-2 shrink-0"
            disabled={!conteudoMarkdown.trim()}
            onClick={() => setReaderModeOpen(true)}
          >
            <BookOpen className="w-4 h-4" />
            <span className="hidden sm:inline">Modo leitura</span>
            <span className="sm:hidden">Ler</span>
          </Button>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="gap-2"
            disabled={!parecer}
            onClick={() => setDetailsOpen(true)}
          >
            <Info className="w-4 h-4" />
            Detalhes
          </Button>
          <Button
            type="button"
            variant="outline"
            size="sm"
            className="gap-2 text-destructive border-destructive/50 hover:bg-destructive/10 hover:text-destructive"
            disabled={!parecer || !id}
            onClick={() => setDeleteOpen(true)}
          >
            <Trash2 className="w-4 h-4" />
            Excluir parecer
          </Button>
          <Button
            onClick={handleExport}
            variant="outline"
            size="sm"
            className="shrink-0 gap-2"
            disabled={exportingDocx || !conteudoMarkdown.trim()}
          >
            {exportingDocx ? <Loader2 className="w-4 h-4 animate-spin" /> : <FileDown className="w-4 h-4" />}
            {exportingDocx ? "Exportando..." : "Exportar parecer"}
          </Button>
        </div>
      </header>

      <Dialog open={readerModeOpen} onOpenChange={setReaderModeOpen}>
        <DialogContent
          ref={readerPanelRef}
          id={READER_PANEL_FULLSCREEN_ID}
          className={cn(
            "max-w-[min(96vw,1200px)] w-[calc(100vw-1rem)] max-h-[92dvh] h-[min(90dvh,92vh)] flex flex-col gap-0 p-0 sm:rounded-lg overflow-x-hidden",
            "left-[50%] top-[4dvh] translate-x-[-50%] translate-y-0",
            "data-[state=closed]:slide-out-to-top-[4dvh] data-[state=open]:slide-in-from-top-[4dvh]",
            readerIsFullscreen &&
              "!inset-0 !left-0 !top-0 !translate-x-0 !translate-y-0 !w-screen !max-w-none !h-[100dvh] !max-h-[100dvh] rounded-none sm:!rounded-none z-[100]"
          )}
        >
          <DialogHeader className="shrink-0 border-b px-4 py-3 pr-12 space-y-3 sm:space-y-0 overflow-visible">
            <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between sm:gap-4 min-w-0">
              <div className="min-w-0 flex-1 space-y-1">
                <DialogTitle className="text-left text-lg sm:text-xl leading-tight line-clamp-3">{titulo}</DialogTitle>
                <DialogDescription className="text-left text-muted-foreground text-sm">
                  Ajuste o tamanho do texto e a largura da coluna. Use tela cheia para ocupar o monitor. Esc fecha este modo (em tela cheia, Esc pode sair do fullscreen primeiro).
                </DialogDescription>
              </div>
              <div className="flex flex-wrap items-center gap-2 shrink-0 sm:pt-0.5">
                <div className="flex items-center gap-1 rounded-md border border-border bg-muted/40 p-0.5">
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        disabled={readerFontStep <= 0}
                        onClick={() => setReaderFontStep((s) => Math.max(0, s - 1))}
                        aria-label="Diminuir tamanho da letra"
                      >
                        <Minus className="h-4 w-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent side="bottom" sideOffset={6} className="z-[100]">
                      Letra menor
                    </TooltipContent>
                  </Tooltip>
                  <span className="text-xs text-muted-foreground tabular-nums px-1 min-w-[2.5rem] text-center" aria-live="polite">
                    {readerFontStep + 1}/5
                  </span>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        disabled={readerFontStep >= 4}
                        onClick={() => setReaderFontStep((s) => Math.min(4, s + 1))}
                        aria-label="Aumentar tamanho da letra"
                      >
                        <Plus className="h-4 w-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent side="bottom" sideOffset={6} className="z-[100]">
                      Letra maior
                    </TooltipContent>
                  </Tooltip>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        onClick={() => setReaderFontStep(READER_FONT_DEFAULT)}
                        aria-label="Redefinir tamanho da letra ao padrão"
                      >
                        <RotateCcw className="h-4 w-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent side="bottom" sideOffset={6} className="z-[100]">
                      Tamanho padrão
                    </TooltipContent>
                  </Tooltip>
                </div>
                <div className="flex items-center gap-2 rounded-md border border-border bg-muted/40 px-2 py-1.5">
                  <Switch
                    id="reader-comfortable-width"
                    checked={readerComfortableWidth}
                    onCheckedChange={setReaderComfortableWidth}
                    aria-label="Largura confortável da coluna de texto"
                  />
                  <Label htmlFor="reader-comfortable-width" className="text-xs font-normal cursor-pointer whitespace-nowrap">
                    Largura confortável
                  </Label>
                </div>
                <Tooltip>
                  <TooltipTrigger asChild>
                    <Button
                      type="button"
                      variant="outline"
                      size="icon"
                      className="h-8 w-8 shrink-0"
                      onClick={() => void toggleReaderFullscreen()}
                      aria-label={readerIsFullscreen ? "Sair da tela cheia" : "Tela cheia"}
                    >
                      {readerIsFullscreen ? <Minimize2 className="h-4 w-4" /> : <Maximize2 className="h-4 w-4" />}
                    </Button>
                  </TooltipTrigger>
                  <TooltipContent side="bottom" sideOffset={6} className="z-[100]">
                    {readerIsFullscreen ? "Sair da tela cheia" : "Tela cheia"}
                  </TooltipContent>
                </Tooltip>
              </div>
            </div>
          </DialogHeader>
          <div
            ref={readerScrollRef}
            className="flex-1 min-h-0 overflow-y-auto overscroll-contain px-4 md:px-8 py-6"
          >
            {conteudoMarkdown.trim() ? (
              <article
                className={cn(
                  "prose",
                  READER_PROSE_SCALE[readerFontStep],
                  READER_PROSE_COMMON,
                  readerComfortableWidth ? "max-w-[65ch] mx-auto" : "max-w-none"
                )}
              >
                <ReactMarkdown>{conteudoMarkdown}</ReactMarkdown>
              </article>
            ) : (
              <p className="text-muted-foreground text-sm">Ainda não há conteúdo do parecer.</p>
            )}
          </div>
          <DialogFooter className="shrink-0 border-t px-4 py-3 flex-col sm:flex-row items-stretch sm:items-center gap-3 sm:justify-between">
            <div className="flex flex-col gap-2 flex-1 min-w-0">
              <div className="flex flex-wrap items-center gap-2">
                <span className="text-xs font-medium text-muted-foreground shrink-0">Auto-scroll</span>
                <Button
                  type="button"
                  variant={readerAutoScrollPlaying ? "secondary" : "outline"}
                  size="sm"
                  className="gap-2 shrink-0"
                  disabled={!conteudoMarkdown.trim()}
                  onClick={() => setReaderAutoScrollPlaying((p) => !p)}
                  aria-label={readerAutoScrollPlaying ? "Pausar auto-scroll" : "Iniciar auto-scroll"}
                >
                  {readerAutoScrollPlaying ? <Pause className="h-4 w-4" /> : <Play className="h-4 w-4" />}
                  {readerAutoScrollPlaying ? "Pausar" : "Iniciar"}
                </Button>
                <div className="flex items-center gap-1 rounded-md border border-border bg-muted/40 p-0.5 shrink-0">
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        disabled={!conteudoMarkdown.trim() || readerAutoScrollSpeedLevel <= 1}
                        onClick={() => setReaderAutoScrollSpeedLevel((s) => Math.max(1, s - 1))}
                        aria-label="Diminuir velocidade do auto-scroll"
                      >
                        <Minus className="h-4 w-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent side="bottom" sideOffset={6} className="z-[100]">
                      Velocidade menor (x1 = mais lento)
                    </TooltipContent>
                  </Tooltip>
                  <div className="flex flex-col items-center justify-center min-w-[4.25rem] px-0.5 py-0.5">
                    <span className="text-xs text-muted-foreground tabular-nums leading-none" aria-live="polite">
                      x{readerAutoScrollSpeedLevel}
                    </span>
                    <span className="text-[10px] text-muted-foreground leading-tight text-center max-w-[5.5rem] truncate">
                      {READER_AUTO_SCROLL_LEVEL_LABELS[readerAutoScrollSpeedLevel - 1]}
                    </span>
                  </div>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <Button
                        type="button"
                        variant="ghost"
                        size="icon"
                        className="h-8 w-8"
                        disabled={!conteudoMarkdown.trim() || readerAutoScrollSpeedLevel >= 5}
                        onClick={() => setReaderAutoScrollSpeedLevel((s) => Math.min(5, s + 1))}
                        aria-label="Aumentar velocidade do auto-scroll"
                      >
                        <Plus className="h-4 w-4" />
                      </Button>
                    </TooltipTrigger>
                    <TooltipContent side="bottom" sideOffset={6} className="z-[100]">
                      Velocidade maior (x5 = mais rápido)
                    </TooltipContent>
                  </Tooltip>
                </div>
                {readerAutoScrollPlaying && (
                  <span className="text-xs text-muted-foreground">Ligado</span>
                )}
              </div>
            </div>
            <Button type="button" variant="outline" className="shrink-0" onClick={() => setReaderModeOpen(false)}>
              Fechar
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={detailsOpen} onOpenChange={setDetailsOpen}>
        <DialogContent className="max-w-4xl w-[calc(100vw-2rem)] max-h-[90vh] flex flex-col gap-0 overflow-hidden p-0 sm:max-w-4xl">
          <DialogHeader className="shrink-0 px-6 pt-6 pb-2 pr-12">
            <DialogTitle>Detalhes do parecer</DialogTitle>
            <DialogDescription className="sr-only">Resumo do parecer</DialogDescription>
          </DialogHeader>
          {parecer && (
            <div className="min-h-0 flex-1 overflow-y-auto overscroll-contain px-6 pb-6">
              <div className="space-y-5 text-sm pr-1">
                <div className="grid gap-4 sm:grid-cols-2">
                  <div className="sm:col-span-2">
                    <Label className="text-muted-foreground text-xs">Título</Label>
                    <p className="mt-1 font-medium text-base">{parecer.titulo}</p>
                  </div>
                  <div>
                    <Label className="text-muted-foreground text-xs">Status</Label>
                    <p className="mt-1 capitalize">{parecer.status}</p>
                  </div>
                  <div>
                    <Label className="text-muted-foreground text-xs">Área</Label>
                    <p className="mt-1">
                      {parecer.area_nome?.trim() ||
                        areaItems.find((a) => a.id === parecer.area_id)?.nome ||
                        "—"}
                    </p>
                  </div>
                  <div className="sm:col-span-2">
                    <Label className="text-muted-foreground text-xs">Usuário</Label>
                    <p className="mt-1 break-all">{textoUsuarioParecer(parecer)}</p>
                  </div>
                  {textoAtualizadoPorValido(parecer.atualizado_por) && (
                    <div className="sm:col-span-2">
                      <Label className="text-muted-foreground text-xs">Atualizado por</Label>
                      <p className="mt-1 break-all">{textoAtualizadoPorValido(parecer.atualizado_por)}</p>
                    </div>
                  )}
                  <div>
                    <Label className="text-muted-foreground text-xs">Criado em</Label>
                    <p className="mt-1">{formatarDataDetalhe(parecer.created_at)}</p>
                  </div>
                  <div>
                    <Label className="text-muted-foreground text-xs">Atualizado em</Label>
                    <p className="mt-1">{formatarDataDetalhe(parecer.updated_at)}</p>
                  </div>
                  <div className="sm:col-span-2">
                    <Label htmlFor="detalhes-instrucao" className="text-muted-foreground text-xs">
                      Instrução enviada
                    </Label>
                    <Textarea
                      id="detalhes-instrucao"
                      readOnly
                      value={parecer.instrucao?.trim() ? parecer.instrucao : "—"}
                      className="mt-2 min-h-[120px] resize-y whitespace-pre-wrap text-sm leading-relaxed bg-muted/40 cursor-text"
                      aria-readonly="true"
                    />
                  </div>
                  <div className="sm:col-span-2">
                    <Label className="text-muted-foreground text-xs">Anexo</Label>
                    <div className="mt-2 flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-4">
                      <p className="text-foreground break-all">
                        {parecer.anexo_nome ?? (parecer.anexo_url ? "Arquivo anexado" : "—")}
                      </p>
                      {parecer.anexo_url ? (
                        <Button
                          type="button"
                          variant="outline"
                          size="sm"
                          className="w-fit shrink-0 gap-2"
                          onClick={() => void handleDownloadAnexo()}
                        >
                          <Download className="w-4 h-4" />
                          Download
                        </Button>
                      ) : null}
                    </div>
                  </div>
                </div>
                <div>
                  <Label htmlFor="detalhes-prompt" className="text-muted-foreground text-xs">
                    Prompt utilizado
                  </Label>
                  <Textarea
                    id="detalhes-prompt"
                    readOnly
                    value={parecer.prompt_conteudo?.trim() ? parecer.prompt_conteudo : "—"}
                    className="mt-2 min-h-[160px] resize-y whitespace-pre-wrap text-sm leading-relaxed bg-muted/40 cursor-text"
                    aria-readonly="true"
                  />
                </div>
              </div>
            </div>
          )}
          {parecer && (
            <DialogFooter className="shrink-0 border-t px-6 py-4 sm:justify-between gap-2">
              <Button type="button" variant="outline" onClick={() => setDetailsOpen(false)}>
                Fechar
              </Button>
              <Button type="button" className="gap-2" onClick={openEditFromDetailsModal}>
                <Pencil className="w-4 h-4" />
                Editar parecer
              </Button>
            </DialogFooter>
          )}
        </DialogContent>
      </Dialog>

      <Dialog
        open={editOpen}
        onOpenChange={(open) => {
          setEditOpen(open);
          if (open) {
            aplicarDadosAtuaisNoFormularioEdicao();
          }
        }}
      >
        <DialogContent className="max-w-md" key={editOpen && parecer ? `edit-${parecer.id}` : "edit-closed"}>
          <DialogHeader>
            <DialogTitle>Editar título e área</DialogTitle>
            <DialogDescription>Atualize os campos obrigatórios do parecer.</DialogDescription>
          </DialogHeader>

          <div className="space-y-4">
            <div className="space-y-2">
              <Label htmlFor="edit-titulo" className="flex flex-wrap items-baseline gap-1">
                <span>Título</span>
                <span className="text-destructive font-semibold" aria-hidden>
                  *
                </span>
                <span className="sr-only">obrigatório</span>
              </Label>
              <Input
                id="edit-titulo"
                value={editTitulo}
                onChange={(e) => setEditTitulo(e.target.value)}
                placeholder="Título do parecer"
                required
                aria-required="true"
              />
            </div>

            <div className="space-y-2">
              <Label htmlFor="edit-area" className="flex flex-wrap items-baseline gap-1">
                <span>Área</span>
                <span className="text-destructive font-semibold" aria-hidden>
                  *
                </span>
                <span className="sr-only">obrigatório</span>
              </Label>
              <Select
                value={editAreaId || "none"}
                onValueChange={(v) => setEditAreaId(v === "none" ? "" : v)}
                key={`area-select-${parecer?.id}-${editAreaId}`}
              >
                <SelectTrigger id="edit-area">
                  <SelectValue placeholder="Selecione a área" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="none">Selecione a área</SelectItem>
                  {parecer?.area_id &&
                    !areaItems.some((a) => a.id === parecer.area_id) &&
                    parecer.area_id.trim() !== "" && (
                      <SelectItem value={parecer.area_id}>
                        {parecer.area_nome?.trim() || `Área (${parecer.area_id.slice(0, 8)}…)`}
                      </SelectItem>
                    )}
                  {areaItems.map((a) => (
                    <SelectItem key={a.id} value={a.id}>
                      {a.nome}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          <DialogFooter className="gap-2">
            <Button type="button" variant="outline" onClick={() => setEditOpen(false)} disabled={editSaving}>
              Cancelar
            </Button>
            <Button type="button" onClick={() => void handleSalvarEdicao()} disabled={editSaving || !editTitulo.trim() || !editAreaId.trim()}>
              {editSaving ? "Salvando..." : "Salvar"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <AlertDialog open={deleteOpen} onOpenChange={(open) => !deleting && setDeleteOpen(open)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Excluir parecer</AlertDialogTitle>
            <AlertDialogDescription className="space-y-2">
              <span className="block">
                Tem certeza que deseja excluir o parecer <strong className="text-foreground">&quot;{titulo}&quot;</strong>?
              </span>
              <span className="block font-medium text-destructive">
                Esta ação é irreversível. O parecer será removido permanentemente.
              </span>
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={deleting}>Cancelar</AlertDialogCancel>
            <Button
              type="button"
              variant="destructive"
              disabled={deleting}
              onClick={handleExcluirParecer}
              className="gap-2"
            >
              {deleting ? <Loader2 className="w-4 h-4 animate-spin" /> : null}
              {deleting ? "Excluindo..." : "Excluir definitivamente"}
            </Button>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      <Dialog
        open={historicoOpen}
        onOpenChange={(open) => {
          setHistoricoOpen(open);
          if (!open) {
            setHistoricoItem(null);
            setHistoricoLoading(false);
          }
        }}
      >
        <DialogContent className="max-w-[min(96vw,1400px)] w-full max-h-[92vh] h-[85dvh] sm:h-[82vh] flex flex-col gap-0 p-0 overflow-hidden sm:max-w-[min(96vw,1400px)]">
          <DialogHeader className="px-6 pt-6 pb-3 shrink-0 border-b">
            <DialogTitle>Histórico da alteração</DialogTitle>
            <DialogDescription>
              {historicoItem?.created_at
                ? `Registro em ${formatarDataDetalhe(historicoItem.created_at)}`
                : "Compare o parecer antes e depois desta resposta do assistente."}
            </DialogDescription>
          </DialogHeader>
          <div className="flex-1 min-h-0 flex flex-col overflow-hidden">
            {historicoLoading && (
              <div className="flex flex-1 items-center justify-center gap-2 py-16 text-muted-foreground">
                <Loader2 className="w-8 h-8 animate-spin" />
                <span>Carregando histórico...</span>
              </div>
            )}
            {!historicoLoading && historicoItem && (
              <div className="grid grid-cols-1 lg:grid-cols-2 flex-1 min-h-0 gap-0 lg:divide-x border-t overflow-hidden lg:grid-rows-1">
                <div className="flex flex-col min-h-0 min-w-0 p-4 lg:h-full lg:min-h-0">
                  <div className="flex items-center justify-between gap-2 mb-2 shrink-0">
                    <h3 className="text-sm font-semibold">Parecer anterior</h3>
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      className="gap-1.5 h-8 shrink-0"
                      onClick={() => copiarTexto(historicoItem.parecer_anterior ?? "", "Parecer anterior")}
                    >
                      <Copy className="w-3.5 h-3.5" />
                      Copiar
                    </Button>
                  </div>
                  <div className="min-h-0 flex-1 overflow-y-auto overscroll-contain rounded-md border bg-muted/20 max-h-[38vh] lg:max-h-none touch-pan-y">
                    <div className="p-4 prose prose-sm prose-neutral dark:prose-invert max-w-none text-sm pb-8">
                      <ReactMarkdown>{historicoItem.parecer_anterior || "—"}</ReactMarkdown>
                    </div>
                  </div>
                </div>
                <div className="flex flex-col min-h-0 min-w-0 p-4 lg:h-full lg:min-h-0">
                  <div className="flex items-center justify-between gap-2 mb-2 shrink-0">
                    <h3 className="text-sm font-semibold text-emerald-700 dark:text-emerald-400">Parecer atual</h3>
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      className="gap-1.5 h-8 shrink-0"
                      onClick={() => copiarTexto(historicoItem.parecer_atual ?? "", "Parecer atual")}
                    >
                      <Copy className="w-3.5 h-3.5" />
                      Copiar
                    </Button>
                  </div>
                  <div className="min-h-0 flex-1 overflow-y-auto overscroll-contain rounded-md border border-emerald-500/30 bg-emerald-500/5 max-h-[38vh] lg:max-h-none touch-pan-y">
                    <div className="p-4 prose prose-sm prose-neutral dark:prose-invert max-w-none text-sm pb-8">
                      <ReactMarkdown>{historicoItem.parecer_atual || "—"}</ReactMarkdown>
                    </div>
                  </div>
                </div>
              </div>
            )}
          </div>
        </DialogContent>
      </Dialog>

      <div className="flex-1 flex flex-col md:flex-row min-h-0">
        <section className="flex-1 min-w-0 min-h-0 flex flex-col border-b md:border-b-0 md:border-r border-border bg-background">
          <ScrollArea className="flex-1">
            <div className="p-4 md:p-6 bg-background min-h-full">
              {conteudoMarkdown.trim() ? (
                <div className="flex flex-wrap items-center justify-end gap-2 mb-3">
                  <div className="flex items-center gap-2 rounded-md border border-border bg-muted/30 px-2 py-1.5">
                    <AlignJustify className="h-4 w-4 text-muted-foreground shrink-0" aria-hidden />
                    <Switch
                      id="main-comfortable-width"
                      checked={mainComfortableWidth}
                      onCheckedChange={setMainComfortableWidth}
                      aria-label="Leitura confortável: limitar largura da coluna de texto"
                    />
                    <Label htmlFor="main-comfortable-width" className="text-xs font-normal cursor-pointer whitespace-nowrap">
                      Leitura confortável
                    </Label>
                  </div>
                </div>
              ) : null}
              <article
                className={cn(
                  "prose prose-sm prose-neutral dark:prose-invert w-full text-foreground prose-headings:font-semibold prose-h1:text-xl prose-h2:text-lg prose-h3:text-base prose-p:leading-relaxed prose-ul:my-3 prose-ol:my-3 prose-li:my-0.5",
                  mainComfortableWidth ? "max-w-[65ch] mx-auto" : "max-w-none"
                )}
              >
                {conteudoMarkdown.trim() ? (
                  <ReactMarkdown>{conteudoMarkdown}</ReactMarkdown>
                ) : (
                  <p className="text-muted-foreground text-sm">Ainda não há conteúdo do parecer.</p>
                )}
              </article>
            </div>
          </ScrollArea>
        </section>

        {chatPanelExpanded ? (
        <aside
          id="parecer-chat-panel"
          className="w-full md:w-[min(100%,360px)] shrink-0 flex flex-col border-t md:border-t-0 md:border-l border-border bg-muted/30 max-h-[45vh] md:max-h-none min-h-0"
          aria-label="Conversa sobre o parecer"
        >
          <div className="p-3 border-b border-border flex items-center gap-2 min-w-0">
            <MessageSquare className="w-5 h-5 text-muted-foreground shrink-0" />
            <h2 className="font-semibold text-sm flex-1 min-w-0 truncate">Conversar sobre o parecer</h2>
            <Tooltip>
              <TooltipTrigger asChild>
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="h-8 w-8 shrink-0"
                  onClick={() => setChatPanelExpanded(false)}
                  aria-expanded={true}
                  aria-controls="parecer-chat-panel"
                  aria-label="Recolher painel de chat para ampliar a leitura do parecer"
                >
                  <ChevronsRight className="h-4 w-4" />
                </Button>
              </TooltipTrigger>
              <TooltipContent side="bottom" className="max-w-[220px]">
                Recolher chat e usar toda a largura para o parecer
              </TooltipContent>
            </Tooltip>
          </div>
          <ScrollArea className="flex-1 p-3 min-h-0">
            <div className="space-y-4">
              {chatLoading && (
                <div className="flex items-center justify-center gap-2 py-8 text-muted-foreground text-sm">
                  <Loader2 className="w-5 h-5 animate-spin" />
                  Carregando histórico...
                </div>
              )}
              {!chatLoading &&
                messages.map((msg) => {
                  const remetente =
                    msg.role === "assistant"
                      ? "Assistente (IA)"
                      : msg.user_email?.trim() || "Usuário não informado";
                  return (
                  <div key={msg.id} className={`flex flex-col gap-1 ${msg.role === "user" ? "items-end" : "items-start"}`}>
                    <div
                      className={`max-w-[85%] rounded-2xl px-4 py-3 text-sm leading-relaxed shadow-sm break-words ${
                        msg.role === "user"
                          ? "bg-primary text-primary-foreground rounded-br-md whitespace-pre-wrap"
                          : "bg-card border border-border text-card-foreground rounded-bl-md"
                      }`}
                    >
                      {msg.role === "assistant" ? (
                        <div className="prose prose-sm prose-neutral dark:prose-invert max-w-none prose-headings:font-semibold prose-p:leading-relaxed">
                          <ReactMarkdown>{msg.content}</ReactMarkdown>
                        </div>
                      ) : (
                        msg.content
                      )}
                    </div>
                    <div
                      className={`flex flex-wrap items-center gap-1 ${msg.role === "user" ? "flex-row-reverse justify-end" : "flex-row"}`}
                    >
                      {msg.created_at && (
                        <span className="text-[10px] text-muted-foreground px-0.5">
                          {formatarDataDetalhe(msg.created_at)}
                        </span>
                      )}
                      <Tooltip>
                        <TooltipTrigger asChild>
                          <button
                            type="button"
                            className="inline-flex rounded-full p-0.5 text-muted-foreground hover:text-foreground hover:bg-muted/80 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                            aria-label="Quem enviou esta mensagem"
                          >
                            <Info className="h-3.5 w-3.5 shrink-0" />
                          </button>
                        </TooltipTrigger>
                        <TooltipContent side="top" className="max-w-sm">
                          <p className="text-xs">
                            <span className="font-medium text-foreground">Enviado por:</span>
                            <br />
                            {remetente}
                          </p>
                        </TooltipContent>
                      </Tooltip>
                      {msg.role === "assistant" && msg.tipo_resposta && (
                        <span
                          className={[
                            "inline-flex items-center gap-0.5 rounded-md border px-1.5 py-0.5 text-[10px] font-medium",
                            msg.tipo_resposta === "chat"
                              ? "bg-primary/10 border-primary/30 text-primary"
                              : "bg-emerald-500/10 border-emerald-500/30 text-emerald-700 dark:text-emerald-400",
                          ].join(" ")}
                        >
                          {msg.tipo_resposta}
                        </span>
                      )}
                      {msg.role === "assistant" && msg.tipo_resposta === "agente" && (
                        <Tooltip>
                          <TooltipTrigger asChild>
                            <button
                              type="button"
                              onClick={() => abrirHistoricoResposta(msg.id)}
                              className="inline-flex items-center gap-0.5 rounded-md border border-border bg-background px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground hover:text-foreground hover:bg-muted/80 transition-colors"
                              aria-label="Ver histórico antes e depois desta resposta"
                            >
                              <History className="h-3 w-3 shrink-0" />
                              Histórico
                            </button>
                          </TooltipTrigger>
                          <TooltipContent side="top">Parecer anterior e atual desta alteração</TooltipContent>
                        </Tooltip>
                      )}
                    </div>
                  </div>
                ); })}
              {!chatLoading && modo === "chat" && chatInlineLoading && (
                <div className="flex items-center gap-2 py-4 text-muted-foreground text-sm">
                  <Loader2 className="w-4 h-4 animate-spin" />
                  Gerando resposta no chat...
                </div>
              )}
              <div ref={chatEndRef} aria-hidden className="h-0 w-full shrink-0" />
            </div>
          </ScrollArea>
          <div className="p-3 border-t border-border space-y-2">
            <div className="flex items-center justify-between gap-3">
              <div className="space-y-0.5">
                <Label className="text-sm font-medium">Modo</Label>
                <p className="text-xs text-muted-foreground">
                  {modo === "chat" ? "Apenas responde no chat" : "Agente (atualiza o parecer)"}
                </p>
              </div>
              <div className="flex items-center gap-2">
                <span className="text-xs text-muted-foreground">Chat</span>
                <Switch
                  checked={modo === "agente"}
                  onCheckedChange={(checked) => setModo(checked ? "agente" : "chat")}
                  disabled={chatProcessing}
                  aria-label="Alternar modo de resposta"
                />
                <span className="text-xs text-muted-foreground">Agente</span>
              </div>
            </div>

            <div className="flex gap-1 md:gap-2 items-end">
              <div className="flex-1 glass-effect rounded-xl overflow-hidden">
                <div
                  onMouseDown={handleResizeMouseDown}
                  className={`hidden md:flex w-full h-6 items-center justify-center cursor-ns-resize hover:bg-primary/10 transition-colors ${isDragging ? "bg-primary/20" : ""}`}
                  title="Arraste para cima para aumentar a altura"
                >
                  <GripHorizontal className="w-5 h-5 text-muted-foreground" />
                </div>
                <div className="px-2 md:px-3 pb-2 md:pb-3 pt-2 md:pt-0">
                  <Textarea
                    ref={chatInputRef}
                    placeholder="Solicitar alteração ou pergunta..."
                    value={chatInput}
                    onChange={(e) => setChatInput(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === "Enter" && !e.shiftKey) {
                        e.preventDefault();
                        handleSendMessage();
                      }
                    }}
                    style={{ height: `${textareaHeight}px` }}
                    className="resize-none border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 w-full p-0 overflow-y-auto text-sm min-h-[60px]"
                  />
                </div>
              </div>
              <Button
                size="icon"
                onClick={handleSendMessage}
                disabled={!chatInput.trim() || chatProcessing}
                className="shrink-0 h-10 w-10 md:h-11 md:w-11"
              >
                <Send className="w-4 h-4" />
              </Button>
            </div>
          </div>
        </aside>
        ) : (
          <>
            <div className="md:hidden shrink-0 border-t border-border bg-muted/30 px-3 py-2">
              <Button
                type="button"
                variant="outline"
                size="sm"
                className="gap-2 w-full"
                onClick={() => setChatPanelExpanded(true)}
                aria-expanded={false}
                aria-controls="parecer-chat-panel"
              >
                <MessageSquare className="w-4 h-4 shrink-0" />
                Mostrar conversa sobre o parecer
              </Button>
            </div>
            <div
              className="hidden md:flex w-11 shrink-0 flex-col items-center border-l border-border bg-muted/30 pt-3 px-1 gap-2"
              aria-label="Chat recolhido"
            >
              <Tooltip>
                <TooltipTrigger asChild>
                  <Button
                    type="button"
                    variant="ghost"
                    size="icon"
                    className="h-9 w-9"
                    onClick={() => setChatPanelExpanded(true)}
                    aria-expanded={false}
                    aria-controls="parecer-chat-panel"
                    aria-label="Abrir painel de chat sobre o parecer"
                  >
                    <ChevronsLeft className="h-4 w-4" />
                  </Button>
                </TooltipTrigger>
                <TooltipContent side="left">Abrir chat</TooltipContent>
              </Tooltip>
              <MessageSquare className="w-4 h-4 text-muted-foreground opacity-70" aria-hidden />
            </div>
          </>
        )}
      </div>
    </div>
    </>
  );
}
