-- =============================================
-- BANCO DE DADOS: snglpi
-- DESCRIÇÃO: Sistema de integração entre ServiceNow e GLPI
-- OBS: Chamados sempre são abertos pelo ServiceNow
-- =============================================

CREATE DATABASE snglpi
    WITH
    OWNER = desenvolvimento
    ENCODING = 'UTF8'
    LC_COLLATE = 'en_US.UTF-8'
    LC_CTYPE = 'en_US.UTF-8'
    LOCALE_PROVIDER = 'libc'
    TABLESPACE = pg_default
    CONNECTION LIMIT = -1
    IS_TEMPLATE = False;


-- =============================================
-- TABELA: tickets_sn
-- DESCRIÇÃO: Armazena tickets importados do ServiceNow
-- =============================================
CREATE TABLE tickets_sn (
    id SERIAL PRIMARY KEY,                       -- ID único do registro no banco snglpi
    ticket_number VARCHAR(32) NOT NULL UNIQUE,   -- Número do ticket no ServiceNow (ex: INC0140378)
    sys_id VARCHAR(64) NOT NULL UNIQUE,          -- Identificador único do ticket no ServiceNow
    short_description TEXT,                      -- Descrição resumida do ticket
    tipo VARCHAR(10),                            -- Tipo do ticket: 'incidente' ou 'requisicao'
    status VARCHAR(55),                          -- Status atual do ticket no ServiceNow
    description TEXT,                            -- Descrição completa do ticket
    caller_id VARCHAR(255),                      -- Nome do solicitante do ticket
    caller_email VARCHAR(255),                   -- Email do solicitante
    location_id VARCHAR(64),                     -- ID da localização no ServiceNow
    location_name VARCHAR(255),                  -- Nome da localização no ServiceNow
    ramal VARCHAR(100),                          -- Ramal do solicitante
    telefone VARCHAR(100),                       -- Telefone do solicitante
    opened_at TIMESTAMP,                         -- Data e hora de abertura no ServiceNow
    created_at TIMESTAMP DEFAULT NOW(),          -- Data e hora de criação do registro
    updated_at TIMESTAMP DEFAULT NOW()           -- Data e hora da última atualização do registro
);

-- Índices para melhor performance nas consultas frequentes
CREATE INDEX idx_tickets_sn_status ON tickets_sn(status);
CREATE INDEX idx_tickets_sn_tipo ON tickets_sn(tipo);
CREATE INDEX idx_tickets_sn_opened_at ON tickets_sn(opened_at);
CREATE INDEX idx_tickets_sn_location_id ON tickets_sn(location_id);
CREATE INDEX idx_tickets_sn_location_name ON tickets_sn(location_name);

-- =============================================
-- TABELA: ticket_sync
-- DESCRIÇÃO: Controla o status de sincronização entre ServiceNow e GLPI
-- OBS: Chamados sempre são criados no ServiceNow primeiro
-- =============================================
CREATE TABLE ticket_sync (
    id SERIAL PRIMARY KEY,                       -- ID único do registro de sincronização
    sn_ticket_id INTEGER NOT NULL,               -- Referência ao ticket na tabela tickets_sn
    glpi_ticket_id INTEGER,                      -- ID do ticket correspondente no GLPI
    last_sn_sync TIMESTAMP,                      -- Data e hora da última sincronização com ServiceNow
    last_glpi_sync TIMESTAMP,                    -- Data e hora da última sincronização com GLPI
    sn_sync_status VARCHAR(20) DEFAULT 'pending',-- Status da sincronização com ServiceNow: 'pending', 'completed', 'error'
    glpi_sync_status VARCHAR(20) DEFAULT 'pending', -- Status da sincronização com GLPI: 'pending', 'completed', 'error'
    created_at TIMESTAMP DEFAULT NOW(),          -- Data e hora de criação do registro
    updated_at TIMESTAMP DEFAULT NOW(),          -- Data e hora da última atualização do registro
    
    -- Chaves estrangeiras
    CONSTRAINT fk_ticket_sync_sn_ticket 
        FOREIGN KEY (sn_ticket_id) 
        REFERENCES tickets_sn(id) 
        ON DELETE CASCADE
);

-- Índices para melhor performance nas consultas frequentes
CREATE INDEX idx_ticket_sync_sn_ticket ON ticket_sync(sn_ticket_id);
CREATE INDEX idx_ticket_sync_glpi_ticket ON ticket_sync(glpi_ticket_id);
CREATE INDEX idx_ticket_sync_status ON ticket_sync(sn_sync_status, glpi_sync_status);

-- =============================================
-- TABELA: ticket_updates
-- DESCRIÇÃO: Armazena as atualizações e tarefas relacionadas aos tickets
-- OBS: Atualizações podem vir de ambos os sistemas (ServiceNow e GLPI)
-- =============================================
CREATE TABLE ticket_updates (
    id SERIAL PRIMARY KEY,                       -- ID único da atualização
    ticket_sync_id INTEGER NOT NULL,             -- Referência ao registro de sincronização
    update_type VARCHAR(20) NOT NULL,            -- Tipo de atualização: 'task', 'note', 'status_change'
    source_system VARCHAR(10) NOT NULL,          -- Sistema de origem: 'sn' (ServiceNow) ou 'glpi'
    content TEXT,                                -- Conteúdo da atualização/tarefa
    author VARCHAR(255),                         -- Autor da atualização
    created_at TIMESTAMP,                        -- Data e hora de criação no sistema de origem
    updated_at TIMESTAMP DEFAULT NOW(),          -- Data e hora da última atualização do registro
    source_id VARCHAR(64),                       -- ID da atualização no sistema de origem (ex: sys_id no ServiceNow)
    
    -- Chaves estrangeiras
    CONSTRAINT fk_ticket_updates_sync 
        FOREIGN KEY (ticket_sync_id) 
        REFERENCES ticket_sync(id) 
        ON DELETE CASCADE
);

-- Índices para melhor performance nas consultas frequentes
CREATE INDEX idx_ticket_updates_sync ON ticket_updates(ticket_sync_id);
CREATE INDEX idx_ticket_updates_source ON ticket_updates(source_system);
CREATE INDEX idx_ticket_updates_type ON ticket_updates(update_type);
CREATE INDEX idx_ticket_updates_source_id ON ticket_updates(source_id);


-- =============================================
-- TABELA: location_mapping
-- DESCRIÇÃO: Mapeamento entre localizações do ServiceNow e entidades do GLPI
-- =============================================
CREATE TABLE location_mapping (
    id SERIAL PRIMARY KEY,                       -- ID único do mapeamento
    sn_location_id VARCHAR(255),                 -- ID da localização no ServiceNow
    sn_location_name VARCHAR(255) NOT NULL,      -- Nome da localização no ServiceNow
    glpi_entity_id INTEGER NOT NULL,             -- ID da entidade correspondente no GLPI
    glpi_entity_name VARCHAR(255) NOT NULL,      -- Nome da entidade no GLPI
    created_at TIMESTAMP DEFAULT NOW(),          -- Data e hora de criação do registro
    updated_at TIMESTAMP DEFAULT NOW()           -- Data e hora da última atualização do registro
);

-- Índices para melhor performance nas consultas frequentes
CREATE INDEX idx_location_mapping_sn_id ON location_mapping(sn_location_id);
CREATE INDEX idx_location_mapping_sn_name ON location_mapping(sn_location_name);
CREATE INDEX idx_location_mapping_glpi_id ON location_mapping(glpi_entity_id);
CREATE INDEX idx_location_mapping_glpi_name ON location_mapping(glpi_entity_name);

-- =============================================
-- TRIGGERS para atualizar automaticamente updated_at
-- =============================================

-- Função para atualizar o campo updated_at
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Trigger para tickets_sn
CREATE TRIGGER trigger_tickets_sn_updated_at
    BEFORE UPDATE ON tickets_sn
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- Trigger para ticket_sync
CREATE TRIGGER trigger_ticket_sync_updated_at
    BEFORE UPDATE ON ticket_sync
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- Trigger para ticket_updates
CREATE TRIGGER trigger_ticket_updates_updated_at
    BEFORE UPDATE ON ticket_updates
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- Trigger para location_mapping
CREATE TRIGGER trigger_location_mapping_updated_at
    BEFORE UPDATE ON location_mapping
    FOR EACH ROW
    EXECUTE FUNCTION update_updated_at_column();

-- =============================================
-- VIEWS para consultas úteis
-- =============================================

-- View para tickets pendentes de sincronização com GLPI
CREATE VIEW view_tickets_pending_glpi AS
SELECT 
    ts.ticket_number,
    ts.short_description,
    ts.status,
    ts.tipo,
    ts.opened_at,
    tsync.created_at as sync_created
FROM tickets_sn ts
JOIN ticket_sync tsync ON ts.id = tsync.sn_ticket_id
WHERE tsync.glpi_sync_status = 'pending';

-- View para tickets pendentes de sincronização com ServiceNow
CREATE VIEW view_tickets_pending_sn AS
SELECT 
    ts.ticket_number,
    ts.short_description,
    ts.status,
    ts.tipo,
    ts.opened_at,
    tsync.created_at as sync_created
FROM tickets_sn ts
JOIN ticket_sync tsync ON ts.id = tsync.sn_ticket_id
WHERE tsync.sn_sync_status = 'pending';

-- View para mapeamento de localizações completo
CREATE VIEW view_location_mapping_complete AS
SELECT 
    sn_location_id,
    sn_location_name,
    glpi_entity_id,
    glpi_entity_name,
    created_at,
    updated_at
FROM location_mapping
ORDER BY sn_location_name;

-- =============================================
-- COMENTÁRIOS NAS TABELAS E COLUNAS
-- =============================================

COMMENT ON TABLE tickets_sn IS 'Armazena tickets importados do ServiceNow';
COMMENT ON COLUMN tickets_sn.id IS 'ID único do registro no banco snglpi';
COMMENT ON COLUMN tickets_sn.ticket_number IS 'Número do ticket no ServiceNow (ex: INC0140378)';
COMMENT ON COLUMN tickets_sn.sys_id IS 'Identificador único do ticket no ServiceNow';
COMMENT ON COLUMN tickets_sn.short_description IS 'Descrição resumida do ticket';
COMMENT ON COLUMN tickets_sn.tipo IS 'Tipo do ticket: incidente ou requisicao';
COMMENT ON COLUMN tickets_sn.status IS 'Status atual do ticket no ServiceNow';
COMMENT ON COLUMN tickets_sn.description IS 'Descrição completa do ticket';
COMMENT ON COLUMN tickets_sn.caller_id IS 'Nome do solicitante do ticket';
COMMENT ON COLUMN tickets_sn.caller_email IS 'Email do solicitante';
COMMENT ON COLUMN tickets_sn.location_id IS 'ID da localização no ServiceNow';
COMMENT ON COLUMN tickets_sn.location_name IS 'Nome da localização no ServiceNow';
COMMENT ON COLUMN tickets_sn.ramal IS 'Ramal do solicitante';
COMMENT ON COLUMN tickets_sn.telefone IS 'Telefone do solicitante';
COMMENT ON COLUMN tickets_sn.opened_at IS 'Data e hora de abertura no ServiceNow';
COMMENT ON COLUMN tickets_sn.created_at IS 'Data e hora de criação do registro';
COMMENT ON COLUMN tickets_sn.updated_at IS 'Data e hora da última atualização do registro';

COMMENT ON TABLE ticket_sync IS 'Controla o status de sincronização entre ServiceNow e GLPI';
COMMENT ON COLUMN ticket_sync.id IS 'ID único do registro de sincronização';
COMMENT ON COLUMN ticket_sync.sn_ticket_id IS 'Referência ao ticket na tabela tickets_sn';
COMMENT ON COLUMN ticket_sync.glpi_ticket_id IS 'ID do ticket correspondente no GLPI';
COMMENT ON COLUMN ticket_sync.last_sn_sync IS 'Data e hora da última sincronização com ServiceNow';
COMMENT ON COLUMN ticket_sync.last_glpi_sync IS 'Data e hora da última sincronização com GLPI';
COMMENT ON COLUMN ticket_sync.sn_sync_status IS 'Status da sincronização com ServiceNow: pending, completed, error';
COMMENT ON COLUMN ticket_sync.glpi_sync_status IS 'Status da sincronização com GLPI: pending, completed, error';
COMMENT ON COLUMN ticket_sync.created_at IS 'Data e hora de criação do registro';
COMMENT ON COLUMN ticket_sync.updated_at IS 'Data e hora da última atualização do registro';

COMMENT ON TABLE ticket_updates IS 'Armazena as atualizações e tarefas relacionadas aos tickets';
COMMENT ON COLUMN ticket_updates.id IS 'ID único da atualização';
COMMENT ON COLUMN ticket_updates.ticket_sync_id IS 'Referência ao registro de sincronização';
COMMENT ON COLUMN ticket_updates.update_type IS 'Tipo de atualização: task, note, status_change';
COMMENT ON COLUMN ticket_updates.source_system IS 'Sistema de origem: sn (ServiceNow) ou glpi';
COMMENT ON COLUMN ticket_updates.content IS 'Conteúdo da atualização/tarefa';
COMMENT ON COLUMN ticket_updates.author IS 'Autor da atualização';
COMMENT ON COLUMN ticket_updates.created_at_source IS 'Data e hora de criação no sistema de origem';
COMMENT ON COLUMN ticket_updates.sync_status IS 'Status da sincronização: pending, completed, error';
COMMENT ON COLUMN ticket_updates.sync_date IS 'Data e hora da sincronização';
COMMENT ON COLUMN ticket_updates.created_at IS 'Data e hora de criação do registro';
COMMENT ON COLUMN ticket_updates.updated_at IS 'Data e hora da última atualização do registro';

COMMENT ON TABLE location_mapping IS 'Mapeamento entre localizações do ServiceNow e entidades do GLPI';
COMMENT ON COLUMN location_mapping.id IS 'ID único do mapeamento';
COMMENT ON COLUMN location_mapping.sn_location_id IS 'ID da localização no ServiceNow';
COMMENT ON COLUMN location_mapping.sn_location_name IS 'Nome da localização no ServiceNow';
COMMENT ON COLUMN location_mapping.glpi_entity_id IS 'ID da entidade correspondente no GLPI';
COMMENT ON COLUMN location_mapping.glpi_entity_name IS 'Nome da entidade no GLPI';
COMMENT ON COLUMN location_mapping.created_at IS 'Data e hora de criação do registro';
COMMENT ON COLUMN location_mapping.updated_at IS 'Data e hora da última atualização do registro';