-- ---------------------------------------------------------------------------
-- Os assistentes com a API da Anthropic, no lugar do Zapier: as colunas novas de
-- `assistentes` e as quatro tabelas da conversa, da cota e do uso (08/11/2026, a
-- fatia 133, ASSISTENTES-PORTA-DO-CLAUDE; o desenho
-- `docs/f3-telas-restantes/assistentes-anthropic.md`, secao 2.3; a decisao do dono de
-- 07/11/2026, "as fatias de assistentes serão substituídas do zapier para Anthropic", e as
-- respostas 366 (c), o Haiku 5.5 como padrao, e 369 (c), a conversa guardada para sempre).
--
--   mysql franquia_producao < scripts/migracao-assistentes-anthropic.sql
--
-- Roda no laco do passo 0 de `docs/procedimento-de-corte.md`, em PRODUCAO, e no laco da
-- copia do desenvolvimento de `docs/ensaio-geral-do-corte.md`, contra a `franquiabv_dev`;
-- os bancos da suite ja nascem com tudo (`mysql.sql`, e o `postgres/schema.sql` do
-- gerador). NA COPIA LOCAL DESDE 08/11/2026, nos dois bancos, pela resposta 83 do dono (a
-- opcao (a): o esquema que so acrescenta entra nas duas copias locais quando a resposta
-- pedir); o PostgreSQL da copia, por `postgres/migracao-assistentes-anthropic.sql`. A base
-- do teste do BVIP fica sem elas ate a proxima copia exportada daqui, pela mao do dono.
--
-- AS COLUNAS DE `assistentes` (as quatro linhas de hoje ficam como estao: todas aceitam
-- nulo ou tem padrao, e o assistente continua no Zapier ate a fatia 88):
--
--   instrucoes        o prompt de sistema; NULO = "ainda sendo preparado". COM O CONJUNTO
--                     utf8mb4 NA PROPRIA COLUNA: a tabela e utf8mb3, e a instrucao colada
--                     com emoji daria o erro 1366. Declarar o conjunto na coluna so
--                     acrescenta; a tabela nao e convertida;
--   modelo            o modelo, da lista branca do codigo; nasce `claude-haiku-5-5`, a
--                     resposta 366 (c) do dono;
--   esforco           o `output_config.effort`, `low`; muda por SQL, sem formulario;
--   limite_de_tokens  o `max_tokens` de cada resposta, 4096 (de 1024 a 8192);
--   pagina_publica    a pagina que leva ao assistente (a fatia 89), unica; nula aqui.
--
-- AS TABELAS NOVAS, em utf8mb4 (a conversa pode ter emoji), sem entidade do Doctrine:
--
--   assistentes_conversas  quem conversa, com qual assistente, o `system` e o modelo
--                          CONGELADOS no primeiro envio, e a marca do `drop_block`;
--   assistentes_mensagens  cada mensagem, a da pessoa como digitada e a resposta como a
--                          Anthropic devolveu (os blocos de raciocinio inclusive);
--   assistentes_cota       um contador por dia e por chave (`erp`, `pessoa:<id>`), com a
--                          chave primaria (`dia`, `chave`): a reserva sobe a linha com um
--                          UPDATE condicional, sem corrida;
--   assistentes_uso        os tokens e o custo estimado de cada pedido, sem conteudo.
--
-- NADA APAGA ESTAS LINHAS: a conversa fica para sempre (a resposta 369 (c)), e a cota e o
-- uso tambem; nao ha rotina de limpeza.
--
-- IDEMPOTENTE: as colunas so entram se `instrucoes` ainda nao existe (as cinco vem
-- juntas, num ALTER so), e as tabelas por `CREATE TABLE IF NOT EXISTS`. O DDL e o mesmo
-- do `mysql.sql` (menos o `AUTO_INCREMENT=1`), e o portao do passo 0 compara os dois.
--
-- ---------------------------------------------------------------------------
-- ESTA MIGRACAO PRECISA ESTAR EM PRODUCAO ANTES DO PASSO 1 -- o passo 0 (D323).
--
-- O passo 1 refaz o `mysql.sql` a partir da estrutura de producao. Sem as colunas e as
-- tabelas la, elas somem do `mysql.sql` e do `schema.sql`, e o assistente da tela nova fica
-- indisponivel: o codigo pergunta se elas existem (`ISBase\Doctrine\ColunaNoBanco`) e, sem
-- elas, responde "O assistente esta indisponivel no momento.", sem quebrar.
--
-- PARA O CODIGO DE PRODUCAO TUDO ISTO E INOFENSIVO: ele nao le nem escreve as colunas
-- novas (a entidade `Assistente` nao as mapeia) nem as tabelas. O ALTER nao copia a
-- tabela de 4 linhas; o indice unico de `pagina_publica` nasce sobre quatro nulos.
-- PARA DESFAZER: `DROP TABLE` das quatro (mensagens antes de conversas) e `DROP COLUMN`
-- das cinco, com o indice.
-- ---------------------------------------------------------------------------

SET @existe = (
    SELECT COUNT(*) FROM information_schema.columns
     WHERE table_schema = DATABASE()
       AND table_name = 'assistentes'
       AND column_name = 'instrucoes'
);

SET @sql = IF(@existe = 0,
    'ALTER TABLE assistentes
       ADD COLUMN instrucoes text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT ''As instrucoes do assistente (o system); nulo = ainda sendo preparado'' AFTER data_alteracao,
       ADD COLUMN modelo varchar(40) NOT NULL DEFAULT ''claude-haiku-5-5'' COMMENT ''O modelo da Anthropic, da lista branca de RegraDoAssistente::MODELOS'' AFTER instrucoes,
       ADD COLUMN esforco varchar(10) NOT NULL DEFAULT ''low'' COMMENT ''O output_config.effort: low, medium ou high'' AFTER modelo,
       ADD COLUMN limite_de_tokens int NOT NULL DEFAULT ''4096'' COMMENT ''O max_tokens de cada resposta, de 1024 a 8192'' AFTER esforco,
       ADD COLUMN pagina_publica varchar(30) DEFAULT NULL COMMENT ''A pagina que leva a este assistente (a fatia 89); nulo = so na tela de uso'' AFTER limite_de_tokens,
       ADD UNIQUE KEY UNQ_ASSISTENTES_pagina_publica (pagina_publica)',
    'SELECT ''assistentes: colunas ja existem, nada a fazer'' AS aviso'
);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

CREATE TABLE IF NOT EXISTS `assistentes_conversas` (
  `id` int NOT NULL AUTO_INCREMENT,
  `assistente` int NOT NULL,
  `usuario` int NOT NULL COMMENT 'Quem conversa: o usuario da sessao, sempre',
  `unidade` int NOT NULL COMMENT 'A unidade da sessao',
  `pagina` varchar(30) DEFAULT NULL COMMENT 'A pagina por onde a conversa foi aberta (a fatia 89); nulo = a tela de uso',
  `sistema` mediumtext NOT NULL COMMENT 'O JSON do system inteiro com que a conversa comecou (a base e as instrucoes): congelado',
  `modelo` varchar(40) NOT NULL COMMENT 'O modelo com que a conversa comecou: congelado',
  `descartar_blocos` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'O 400 do raciocinio veio: todo pedido seguinte vai com drop_block',
  `data_criacao` datetime NOT NULL,
  `data_ultima` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_ASSISTENTES_CONVERSAS_usuario_data` (`usuario`,`data_ultima`),
  KEY `FK_ASSISTENTES_CONVERSAS_assistente` (`assistente`),
  KEY `FK_ASSISTENTES_CONVERSAS_unidade` (`unidade`),
  CONSTRAINT `FK_ASSISTENTES_CONVERSAS_assistente` FOREIGN KEY (`assistente`) REFERENCES `assistentes` (`id`),
  CONSTRAINT `FK_ASSISTENTES_CONVERSAS_unidade` FOREIGN KEY (`unidade`) REFERENCES `unidades` (`id`),
  CONSTRAINT `FK_ASSISTENTES_CONVERSAS_usuario` FOREIGN KEY (`usuario`) REFERENCES `usuarios` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `assistentes_cota` (
  `dia` date NOT NULL,
  `chave` varchar(80) NOT NULL COMMENT 'O contador: erp, pessoa:<id> (e, com a fatia 89, os das paginas)',
  `usados` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`dia`,`chave`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `assistentes_mensagens` (
  `id` int NOT NULL AUTO_INCREMENT,
  `conversa` int NOT NULL,
  `papel` varchar(10) NOT NULL COMMENT 'user ou assistant',
  `conteudo` mediumtext NOT NULL COMMENT 'O texto da pessoa, ou o JSON dos blocos como a Anthropic devolveu',
  `motivo_de_parada` varchar(30) DEFAULT NULL,
  `modelo_que_respondeu` varchar(40) DEFAULT NULL,
  `fora_do_historico` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'A mensagem da pessoa recusada ou com erro: nao vai em pedido nenhum',
  `data_criacao` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_ASSISTENTES_MENSAGENS_conversa` (`conversa`),
  CONSTRAINT `FK_ASSISTENTES_MENSAGENS_conversa` FOREIGN KEY (`conversa`) REFERENCES `assistentes_conversas` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE IF NOT EXISTS `assistentes_uso` (
  `id` int NOT NULL AUTO_INCREMENT,
  `dia` date NOT NULL,
  `assistente` int NOT NULL,
  `usuario` int DEFAULT NULL,
  `unidade` int DEFAULT NULL,
  `pagina` varchar(30) DEFAULT NULL COMMENT 'Nulo = o lado do ERP; preenchido = o das paginas (a fatia 89)',
  `pedidos` int NOT NULL DEFAULT '0',
  `tokens_entrada` int NOT NULL DEFAULT '0',
  `tokens_saida` int NOT NULL DEFAULT '0',
  `tokens_cache_lidos` int NOT NULL DEFAULT '0',
  `tokens_cache_gravados` int NOT NULL DEFAULT '0',
  `custo_estimado_usd` decimal(12,6) NOT NULL DEFAULT '0.000000' COMMENT 'Os tokens vezes a tabela de precos datada do codigo',
  `recusas` int NOT NULL DEFAULT '0',
  `erros` int NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `IDX_ASSISTENTES_USO_dia` (`dia`),
  KEY `FK_ASSISTENTES_USO_assistente` (`assistente`),
  CONSTRAINT `FK_ASSISTENTES_USO_assistente` FOREIGN KEY (`assistente`) REFERENCES `assistentes` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Conferencia. O esperado: as cinco colunas de `assistentes` (o conjunto utf8mb4 so em
-- `instrucoes`), as quatro tabelas e as linhas (0 nas quatro).
SELECT column_name AS coluna, column_type AS tipo, character_set_name AS conjunto, column_default AS padrao
  FROM information_schema.columns
 WHERE table_schema = DATABASE()
   AND table_name = 'assistentes'
   AND column_name IN ('instrucoes', 'modelo', 'esforco', 'limite_de_tokens', 'pagina_publica')
 ORDER BY ordinal_position;

SELECT table_name AS tabela, table_collation AS colacao
  FROM information_schema.tables
 WHERE table_schema = DATABASE()
   AND table_name IN ('assistentes_conversas', 'assistentes_cota', 'assistentes_mensagens', 'assistentes_uso')
 ORDER BY table_name;

SELECT (SELECT COUNT(*) FROM assistentes_conversas) AS conversas,
       (SELECT COUNT(*) FROM assistentes_mensagens) AS mensagens,
       (SELECT COUNT(*) FROM assistentes_cota)      AS cota,
       (SELECT COUNT(*) FROM assistentes_uso)       AS uso;
