-- 066 — CENTRAL DE ATENDIMENTO (docs/CENTRAL-ATENDIMENTO.md)
--
-- Unifica /ai/conversations + /atendimento-kanban numa central omnichannel.
-- Tudo aditivo: nenhuma coluna existente muda de tipo ou semântica, e o
-- estado da conversa continua DERIVADO dos campos que já governam a IA
-- (manual_mode/status) — a central não inventa uma segunda fonte da verdade.
--
-- ⚠ Índices simples aqui TÊM que ser espelhados em shared/schema.ts: o
-- drizzle-kit push dropa índice que não está no schema (queimou 2x — a
-- última em 05/08/2026, quando o dedupe de MO ficou sem índice único).

-- ── Atendimento humano na conversa ─────────────────────────────────────────
-- assigned_user_id: quem está atendendo. É o mecanismo anti-colisão da v1
-- (atribuição + aviso visual); NÃO é lock — o servidor não recusa envio de
-- outro operador, porque conversa travada em quem saiu para o almoço é pior
-- que duas respostas. closed_at é a fonte da verdade de "resolvida"
-- (status='CLOSED' é gravado junto só para a IA dormir de graça).
ALTER TABLE ai_conversations
  ADD COLUMN IF NOT EXISTS assigned_user_id   varchar REFERENCES users(id) ON DELETE SET NULL,
  ADD COLUMN IF NOT EXISTS assigned_at        timestamptz,
  ADD COLUMN IF NOT EXISTS closed_at          timestamptz,
  ADD COLUMN IF NOT EXISTS closed_by_user_id  varchar;

-- ── Autoria e mídia nas mensagens ──────────────────────────────────────────
-- author_user_id: até aqui uma mensagem AGENT não dizia QUEM respondeu (só
-- "operador"). Nota interna (role NOTE) sempre carrega autor.
-- media_url/media_type: a mídia recebida era DESCARTADA (virava só o marcador
-- "[📷 Imagem recebida]" e a URL do vendor morria no log).
-- ⚠ CORREÇÃO (07/08/2026): este comentário AFIRMAVA que "a mídia é baixada no
-- ingest e servida pela plataforma". Isso NUNCA foi implementado — as colunas
-- existem, o código não. Hoje só o envio manual do operador escreve media_url
-- (URL informada por ele). No caminho de ENTRADA a mídia continua virando
-- marcador textual e o id da Meta é descartado. Migration não é lugar de
-- promessa: descreve o que a migration faz, e ela só cria as colunas.
-- ⚠ A IA continua recebendo apenas o marcador textual (regra viva de custo:
-- a IA nunca interpreta mídia). Isto é para o operador humano ver e ouvir.
ALTER TABLE ai_conversation_messages
  ADD COLUMN IF NOT EXISTS author_user_id varchar,
  ADD COLUMN IF NOT EXISTS media_url      text,
  ADD COLUMN IF NOT EXISTS media_type     varchar(20);   -- imagem|audio|video|documento|sticker

-- ── Respostas rápidas (canned responses) ───────────────────────────────────
-- Por CONTA (owner_user_id = o CLIENTE), acionadas por "/" no composer.
-- Escopo de conta e não de usuário: o atalho /pix é da empresa, não do
-- atendente que o escreveu.
CREATE TABLE IF NOT EXISTS canned_responses (
  id                  varchar PRIMARY KEY DEFAULT gen_random_uuid(),
  owner_user_id       varchar NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  shortcut            varchar(40) NOT NULL,          -- sem a barra: "pix", "boleto"
  titulo              varchar(120),
  conteudo            text NOT NULL,
  created_by_user_id  varchar,
  created_at          timestamptz DEFAULT now(),
  updated_at          timestamptz DEFAULT now(),
  CONSTRAINT canned_responses_owner_shortcut_uniq UNIQUE (owner_user_id, shortcut)
);

-- ── Índices ────────────────────────────────────────────────────────────────
-- owner+closed: predicado de TODAS as abas do inbox (abertas/minhas/bot são
-- closed_at IS NULL). conv+created: ordenação da timeline e da LATERAL que
-- busca a última mensagem de cada conversa no inbox.
CREATE INDEX IF NOT EXISTS idx_ai_conversations_assigned      ON ai_conversations (assigned_user_id);
CREATE INDEX IF NOT EXISTS idx_ai_conversations_owner_closed  ON ai_conversations (owner_user_id, closed_at);
CREATE INDEX IF NOT EXISTS idx_ai_conv_msgs_conv_created      ON ai_conversation_messages (conversation_id, created_at);
CREATE INDEX IF NOT EXISTS idx_canned_responses_owner         ON canned_responses (owner_user_id);
