-- Schema para Ranking de Consultores CAPES
-- Versão: 1.0
-- Data: 2025-01-15

-- Tabela principal de ranking
CREATE TABLE TB_RANKING_CONSULTOR (
    ID_PESSOA         NUMBER(10) NOT NULL,
    NOME              VARCHAR2(200) NOT NULL,
    POSICAO           NUMBER(10),
    PONTUACAO_TOTAL   NUMBER(10,2) NOT NULL,
    COMPONENTE_A      NUMBER(10,2) DEFAULT 0,
    COMPONENTE_B      NUMBER(10,2) DEFAULT 0,
    COMPONENTE_C      NUMBER(10,2) DEFAULT 0,
    COMPONENTE_D      NUMBER(10,2) DEFAULT 0,
    ATIVO             CHAR(1) DEFAULT 'N',
    ANOS_ATUACAO      NUMBER(5,1) DEFAULT 0,
    DT_CALCULO        TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    JSON_DETALHES     CLOB,
    CONSTRAINT PK_RANKING_CONSULTOR PRIMARY KEY (ID_PESSOA),
    CONSTRAINT CHK_ATIVO CHECK (ATIVO IN ('S', 'N'))
);

-- Índices para performance
CREATE INDEX IDX_RANKING_POSICAO ON TB_RANKING_CONSULTOR(POSICAO);
CREATE INDEX IDX_RANKING_PONTUACAO ON TB_RANKING_CONSULTOR(PONTUACAO_TOTAL DESC);
CREATE INDEX IDX_RANKING_ATIVO ON TB_RANKING_CONSULTOR(ATIVO);
CREATE INDEX IDX_RANKING_DT_CALCULO ON TB_RANKING_CONSULTOR(DT_CALCULO DESC);

-- Procedure para atualizar posições após processamento
CREATE OR REPLACE PROCEDURE SP_ATUALIZAR_POSICOES AS
BEGIN
    MERGE INTO TB_RANKING_CONSULTOR t
    USING (
        SELECT ID_PESSOA,
               ROW_NUMBER() OVER (ORDER BY PONTUACAO_TOTAL DESC, ID_PESSOA) AS NOVA_POSICAO
        FROM TB_RANKING_CONSULTOR
    ) s
    ON (t.ID_PESSOA = s.ID_PESSOA)
    WHEN MATCHED THEN UPDATE SET t.POSICAO = s.NOVA_POSICAO;
    COMMIT;
END SP_ATUALIZAR_POSICOES;
/

-- View para estatísticas do ranking
CREATE OR REPLACE VIEW VW_RANKING_ESTATISTICAS AS
SELECT
    COUNT(*) AS TOTAL_CONSULTORES,
    COUNT(CASE WHEN ATIVO = 'S' THEN 1 END) AS TOTAL_ATIVOS,
    COUNT(CASE WHEN ATIVO = 'N' THEN 1 END) AS TOTAL_INATIVOS,
    MAX(DT_CALCULO) AS ULTIMA_ATUALIZACAO,
    AVG(PONTUACAO_TOTAL) AS PONTUACAO_MEDIA,
    MAX(PONTUACAO_TOTAL) AS PONTUACAO_MAXIMA,
    MIN(PONTUACAO_TOTAL) AS PONTUACAO_MINIMA,
    AVG(COMPONENTE_A) AS MEDIA_COMP_A,
    AVG(COMPONENTE_B) AS MEDIA_COMP_B,
    AVG(COMPONENTE_C) AS MEDIA_COMP_C,
    AVG(COMPONENTE_D) AS MEDIA_COMP_D
FROM TB_RANKING_CONSULTOR;

-- View para distribuição por faixas de pontuação
CREATE OR REPLACE VIEW VW_RANKING_DISTRIBUICAO AS
SELECT
    CASE
        WHEN PONTUACAO_TOTAL >= 800 THEN '800+'
        WHEN PONTUACAO_TOTAL >= 600 THEN '600-799'
        WHEN PONTUACAO_TOTAL >= 400 THEN '400-599'
        WHEN PONTUACAO_TOTAL >= 200 THEN '200-399'
        ELSE '0-199'
    END AS FAIXA,
    COUNT(*) AS QUANTIDADE,
    ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM TB_RANKING_CONSULTOR), 2) AS PERCENTUAL
FROM TB_RANKING_CONSULTOR
GROUP BY
    CASE
        WHEN PONTUACAO_TOTAL >= 800 THEN '800+'
        WHEN PONTUACAO_TOTAL >= 600 THEN '600-799'
        WHEN PONTUACAO_TOTAL >= 400 THEN '400-599'
        WHEN PONTUACAO_TOTAL >= 200 THEN '200-399'
        ELSE '0-199'
    END
ORDER BY
    CASE
        WHEN FAIXA = '800+' THEN 1
        WHEN FAIXA = '600-799' THEN 2
        WHEN FAIXA = '400-599' THEN 3
        WHEN FAIXA = '200-399' THEN 4
        ELSE 5
    END;

-- Comentários nas tabelas e colunas
COMMENT ON TABLE TB_RANKING_CONSULTOR IS 'Tabela de ranking pré-calculado de consultores CAPES';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.ID_PESSOA IS 'ID da pessoa no sistema AtuaCAPES';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.NOME IS 'Nome completo do consultor';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.POSICAO IS 'Posição no ranking (1 = primeiro lugar)';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.PONTUACAO_TOTAL IS 'Pontuação total calculada (soma dos 4 componentes)';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.COMPONENTE_A IS 'Pontuação do Componente A (Coordenação CAPES)';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.COMPONENTE_B IS 'Pontuação do Componente B (Coordenação PPG)';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.COMPONENTE_C IS 'Pontuação do Componente C (Consultoria)';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.COMPONENTE_D IS 'Pontuação do Componente D (Premiações)';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.ATIVO IS 'Indicador se o consultor está ativo (S/N)';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.ANOS_ATUACAO IS 'Anos de atuação do consultor';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.DT_CALCULO IS 'Data/hora do último cálculo';
COMMENT ON COLUMN TB_RANKING_CONSULTOR.JSON_DETALHES IS 'Dados completos do consultor em JSON para exibição';

-- Grant de permissões para o usuário de aplicação (ajustar conforme necessário)
-- GRANT SELECT, INSERT, UPDATE, DELETE ON TB_RANKING_CONSULTOR TO app_user;
-- GRANT SELECT ON VW_RANKING_ESTATISTICAS TO app_user;
-- GRANT SELECT ON VW_RANKING_DISTRIBUICAO TO app_user;
-- GRANT EXECUTE ON SP_ATUALIZAR_POSICOES TO app_user;
