-- ============================================================
-- Migration 001: Módulo de Autenticação
-- Tabelas: usuários, provedores, perfis de acesso e auditoria
-- ============================================================


-- ------------------------------------------------------------
-- Tabela: usuarios
-- Representa qualquer pessoa que acessa o sistema,
-- independente de como ela se autenticou
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS usuarios (
    id          SERIAL PRIMARY KEY,
    nome        VARCHAR(255) NOT NULL,
    email       VARCHAR(255) UNIQUE,           -- pode ser nulo em contas só com LDAP sem email
    ativo       BOOLEAN NOT NULL DEFAULT TRUE,
    created_at  TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at  TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_usuarios_email ON usuarios (email);


-- ------------------------------------------------------------
-- Tabela: usuarios_provedores
-- Vincula um usuário a um ou mais provedores de autenticação
-- Um mesmo usuário pode logar via LDAP e via Microsoft
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS usuarios_provedores (
    id                  SERIAL PRIMARY KEY,
    -- FK para o usuário correspondente
    usuario_id          INTEGER NOT NULL REFERENCES usuarios (id) ON DELETE CASCADE,
    -- Provedor de autenticação: 'ldap' | 'microsoft' | 'google' | etc.
    provedor            VARCHAR(50) NOT NULL,
    -- ID do usuário dentro do provedor (azure_id, username do AD, sub do Google...)
    provedor_user_id    VARCHAR(255) NOT NULL,
    -- Evita duplicidade do mesmo provedor pro mesmo usuário
    CONSTRAINT uq_provedor_user UNIQUE (provedor, provedor_user_id),

    created_at          TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_usuarios_provedores_usuario ON usuarios_provedores (usuario_id);
CREATE INDEX IF NOT EXISTS idx_usuarios_provedores_lookup  ON usuarios_provedores (provedor, provedor_user_id);


-- ------------------------------------------------------------
-- Tabela: perfis_acesso
-- Define os papéis disponíveis no sistema
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS perfis_acesso (
    id          SERIAL PRIMARY KEY,
    nome        VARCHAR(100) NOT NULL UNIQUE,
    descricao   TEXT,
    created_at  TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at  TIMESTAMP NOT NULL DEFAULT NOW()
);


-- ------------------------------------------------------------
-- Tabela: usuarios_perfis
-- Relacionamento entre usuários e perfis (muitos-para-muitos)
-- Um usuário pode ter mais de um perfil se necessário
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS usuarios_perfis (
    id          SERIAL PRIMARY KEY,
    usuario_id  INTEGER NOT NULL REFERENCES usuarios (id) ON DELETE CASCADE,
    perfil_id   INTEGER NOT NULL REFERENCES perfis_acesso (id) ON DELETE CASCADE,

    CONSTRAINT uq_usuario_perfil UNIQUE (usuario_id, perfil_id),

    created_at  TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_usuarios_perfis_usuario ON usuarios_perfis (usuario_id);
CREATE INDEX IF NOT EXISTS idx_usuarios_perfis_perfil  ON usuarios_perfis (perfil_id);


-- ------------------------------------------------------------
-- Tabela: logs_auditoria
-- Registra ações relevantes feitas por usuários ou pelo sistema
-- usuario_id NULL = ação do sistema (ex: tentativa de login falha)
-- ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS logs_auditoria (
    id          SERIAL PRIMARY KEY,
    usuario_id  INTEGER REFERENCES usuarios (id) ON DELETE SET NULL,

    -- Ação realizada — ex: 'LOGIN_LDAP', 'LOGIN_MICROSOFT', 'LOGIN_FALHOU', 'USUARIO_CRIADO'
    acao        VARCHAR(100) NOT NULL,

    -- Dados extras livres — ex: { "ip": "...", "provedor": "microsoft", "motivo": "..." }
    detalhes    JSONB,

    ip_origem   VARCHAR(45),

    created_at  TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_logs_usuario    ON logs_auditoria (usuario_id);
CREATE INDEX IF NOT EXISTS idx_logs_acao       ON logs_auditoria (acao);
CREATE INDEX IF NOT EXISTS idx_logs_created_at ON logs_auditoria (created_at);


-- ------------------------------------------------------------
-- Dados iniciais: perfis de acesso
-- ON CONFLICT garante que pode rodar mais de uma vez sem erro
-- ------------------------------------------------------------
INSERT INTO perfis_acesso (nome, descricao) VALUES
    ('Agente',  'Atendente responsável por responder e encaminhar chamados'),
    ('Supervisor', 'Gestor com visibilidade de filas e relatórios'),
    ('Admin',      'Administrador com acesso total ao sistema')
ON CONFLICT (nome) DO NOTHING;