-- ============================================================================
-- SISTEMA COMPLETO DE CONTROLE FINANCEIRO
-- ============================================================================
-- Autor: Sistema de Controle Financeiro Pessoal
-- Versão: 1.0
-- Database: MySQL/MariaDB (compatível com PostgreSQL com pequenos ajustes)
-- ============================================================================

-- Criar banco de dados
CREATE DATABASE IF NOT EXISTS controle_financeiro
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;

USE controle_financeiro;

-- ============================================================================
-- TABELA DE USUÁRIOS
-- ============================================================================
CREATE TABLE usuarios (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nome VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    senha_hash VARCHAR(255) NOT NULL,
    foto_perfil VARCHAR(255),
    tema_preferido ENUM('claro', 'escuro') DEFAULT 'claro',
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    data_atualizacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    ativo BOOLEAN DEFAULT TRUE,
    INDEX idx_email (email),
    INDEX idx_ativo (ativo)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE INSTITUIÇÕES FINANCEIRAS
-- ============================================================================
CREATE TABLE instituicoes_financeiras (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nome VARCHAR(100) NOT NULL,
    codigo_banco VARCHAR(10),
    logo_url VARCHAR(255),
    site VARCHAR(255),
    telefone VARCHAR(20),
    ativo BOOLEAN DEFAULT TRUE,
    INDEX idx_nome (nome),
    INDEX idx_codigo (codigo_banco)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE CONTAS BANCÁRIAS
-- ============================================================================
CREATE TABLE contas_bancarias (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT NOT NULL,
    instituicao_id INT,
    nome_conta VARCHAR(100) NOT NULL,
    tipo_conta ENUM('corrente', 'poupanca', 'investimento', 'carteira', 'outro') NOT NULL,
    numero_conta VARCHAR(20),
    agencia VARCHAR(10),
    saldo_inicial DECIMAL(15, 2) DEFAULT 0.00,
    saldo_atual DECIMAL(15, 2) DEFAULT 0.00,
    limite_credito DECIMAL(15, 2) DEFAULT 0.00,
    cor_identificacao VARCHAR(7) DEFAULT '#007bff',
    icone VARCHAR(50) DEFAULT 'bank',
    observacoes TEXT,
    incluir_saldo_total BOOLEAN DEFAULT TRUE,
    ativo BOOLEAN DEFAULT TRUE,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    data_atualizacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    FOREIGN KEY (instituicao_id) REFERENCES instituicoes_financeiras(id) ON DELETE SET NULL,
    INDEX idx_usuario (usuario_id),
    INDEX idx_instituicao (instituicao_id),
    INDEX idx_ativo (ativo)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE CARTÕES DE CRÉDITO
-- ============================================================================
CREATE TABLE cartoes_credito (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT NOT NULL,
    conta_bancaria_id INT,
    instituicao_id INT,
    nome_cartao VARCHAR(100) NOT NULL,
    bandeira ENUM('visa', 'mastercard', 'elo', 'amex', 'hipercard', 'diners', 'outro') NOT NULL,
    numero_final VARCHAR(4),
    limite_total DECIMAL(15, 2) NOT NULL,
    limite_disponivel DECIMAL(15, 2) NOT NULL,
    dia_vencimento INT NOT NULL CHECK (dia_vencimento BETWEEN 1 AND 31),
    dia_fechamento INT NOT NULL CHECK (dia_fechamento BETWEEN 1 AND 31),
    cor_identificacao VARCHAR(7) DEFAULT '#ff6b6b',
    icone VARCHAR(50) DEFAULT 'credit-card',
    taxa_anuidade DECIMAL(10, 2) DEFAULT 0.00,
    programa_pontos VARCHAR(100),
    observacoes TEXT,
    ativo BOOLEAN DEFAULT TRUE,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    data_atualizacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    FOREIGN KEY (conta_bancaria_id) REFERENCES contas_bancarias(id) ON DELETE SET NULL,
    FOREIGN KEY (instituicao_id) REFERENCES instituicoes_financeiras(id) ON DELETE SET NULL,
    INDEX idx_usuario (usuario_id),
    INDEX idx_conta (conta_bancaria_id),
    INDEX idx_ativo (ativo),
    INDEX idx_vencimento (dia_vencimento)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE CATEGORIAS
-- ============================================================================
CREATE TABLE categorias (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT,
    nome VARCHAR(100) NOT NULL,
    tipo ENUM('receita', 'despesa', 'transferencia') NOT NULL,
    cor VARCHAR(7) DEFAULT '#6c757d',
    icone VARCHAR(50) DEFAULT 'folder',
    descricao TEXT,
    categoria_pai_id INT,
    ordem_exibicao INT DEFAULT 0,
    ativo BOOLEAN DEFAULT TRUE,
    padrao_sistema BOOLEAN DEFAULT FALSE,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    FOREIGN KEY (categoria_pai_id) REFERENCES categorias(id) ON DELETE SET NULL,
    INDEX idx_usuario (usuario_id),
    INDEX idx_tipo (tipo),
    INDEX idx_pai (categoria_pai_id),
    INDEX idx_ativo (ativo)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE SUBCATEGORIAS
-- ============================================================================
CREATE TABLE subcategorias (
    id INT AUTO_INCREMENT PRIMARY KEY,
    categoria_id INT NOT NULL,
    usuario_id INT,
    nome VARCHAR(100) NOT NULL,
    cor VARCHAR(7),
    icone VARCHAR(50),
    descricao TEXT,
    ordem_exibicao INT DEFAULT 0,
    ativo BOOLEAN DEFAULT TRUE,
    padrao_sistema BOOLEAN DEFAULT FALSE,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (categoria_id) REFERENCES categorias(id) ON DELETE CASCADE,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    INDEX idx_categoria (categoria_id),
    INDEX idx_usuario (usuario_id),
    INDEX idx_ativo (ativo)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE TRANSAÇÕES
-- ============================================================================
CREATE TABLE transacoes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT NOT NULL,
    tipo ENUM('receita', 'despesa', 'transferencia') NOT NULL,
    descricao VARCHAR(255) NOT NULL,
    valor DECIMAL(15, 2) NOT NULL,
    data_transacao DATE NOT NULL,
    data_vencimento DATE,
    categoria_id INT,
    subcategoria_id INT,
    conta_origem_id INT,
    conta_destino_id INT,
    cartao_credito_id INT,
    status ENUM('pendente', 'pago', 'cancelado', 'agendado') DEFAULT 'pendente',
    recorrente BOOLEAN DEFAULT FALSE,
    frequencia_recorrencia ENUM('diaria', 'semanal', 'quinzenal', 'mensal', 'bimestral', 'trimestral', 'semestral', 'anual'),
    numero_parcelas INT DEFAULT 1,
    parcela_atual INT DEFAULT 1,
    transacao_pai_id INT,
    anexo_url VARCHAR(255),
    observacoes TEXT,
    tags VARCHAR(255),
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    data_atualizacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    FOREIGN KEY (categoria_id) REFERENCES categorias(id) ON DELETE SET NULL,
    FOREIGN KEY (subcategoria_id) REFERENCES subcategorias(id) ON DELETE SET NULL,
    FOREIGN KEY (conta_origem_id) REFERENCES contas_bancarias(id) ON DELETE SET NULL,
    FOREIGN KEY (conta_destino_id) REFERENCES contas_bancarias(id) ON DELETE SET NULL,
    FOREIGN KEY (cartao_credito_id) REFERENCES cartoes_credito(id) ON DELETE SET NULL,
    FOREIGN KEY (transacao_pai_id) REFERENCES transacoes(id) ON DELETE CASCADE,
    INDEX idx_usuario (usuario_id),
    INDEX idx_tipo (tipo),
    INDEX idx_data_transacao (data_transacao),
    INDEX idx_data_vencimento (data_vencimento),
    INDEX idx_categoria (categoria_id),
    INDEX idx_subcategoria (subcategoria_id),
    INDEX idx_conta_origem (conta_origem_id),
    INDEX idx_conta_destino (conta_destino_id),
    INDEX idx_cartao (cartao_credito_id),
    INDEX idx_status (status),
    INDEX idx_recorrente (recorrente)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE FATURAS DE CARTÃO
-- ============================================================================
CREATE TABLE faturas_cartao (
    id INT AUTO_INCREMENT PRIMARY KEY,
    cartao_credito_id INT NOT NULL,
    usuario_id INT NOT NULL,
    mes_referencia INT NOT NULL CHECK (mes_referencia BETWEEN 1 AND 12),
    ano_referencia INT NOT NULL,
    data_fechamento DATE NOT NULL,
    data_vencimento DATE NOT NULL,
    valor_total DECIMAL(15, 2) DEFAULT 0.00,
    valor_pago DECIMAL(15, 2) DEFAULT 0.00,
    status ENUM('aberta', 'fechada', 'paga', 'vencida') DEFAULT 'aberta',
    conta_pagamento_id INT,
    data_pagamento DATE,
    observacoes TEXT,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (cartao_credito_id) REFERENCES cartoes_credito(id) ON DELETE CASCADE,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    FOREIGN KEY (conta_pagamento_id) REFERENCES contas_bancarias(id) ON DELETE SET NULL,
    UNIQUE KEY uk_fatura (cartao_credito_id, mes_referencia, ano_referencia),
    INDEX idx_cartao (cartao_credito_id),
    INDEX idx_usuario (usuario_id),
    INDEX idx_periodo (ano_referencia, mes_referencia),
    INDEX idx_vencimento (data_vencimento),
    INDEX idx_status (status)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE ORÇAMENTOS
-- ============================================================================
CREATE TABLE orcamentos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT NOT NULL,
    categoria_id INT,
    subcategoria_id INT,
    nome VARCHAR(100) NOT NULL,
    valor_planejado DECIMAL(15, 2) NOT NULL,
    valor_gasto DECIMAL(15, 2) DEFAULT 0.00,
    mes_referencia INT NOT NULL CHECK (mes_referencia BETWEEN 1 AND 12),
    ano_referencia INT NOT NULL,
    tipo_periodo ENUM('mensal', 'trimestral', 'semestral', 'anual') DEFAULT 'mensal',
    alerta_percentual INT DEFAULT 80,
    notificar_limite BOOLEAN DEFAULT TRUE,
    observacoes TEXT,
    ativo BOOLEAN DEFAULT TRUE,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    FOREIGN KEY (categoria_id) REFERENCES categorias(id) ON DELETE CASCADE,
    FOREIGN KEY (subcategoria_id) REFERENCES subcategorias(id) ON DELETE SET NULL,
    INDEX idx_usuario (usuario_id),
    INDEX idx_categoria (categoria_id),
    INDEX idx_periodo (ano_referencia, mes_referencia),
    INDEX idx_ativo (ativo)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE METAS FINANCEIRAS
-- ============================================================================
CREATE TABLE metas_financeiras (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT NOT NULL,
    nome VARCHAR(100) NOT NULL,
    descricao TEXT,
    valor_alvo DECIMAL(15, 2) NOT NULL,
    valor_atual DECIMAL(15, 2) DEFAULT 0.00,
    conta_destino_id INT,
    data_inicio DATE NOT NULL,
    data_alvo DATE NOT NULL,
    categoria_meta ENUM('reserva_emergencia', 'aposentadoria', 'viagem', 'compra', 'investimento', 'educacao', 'outro') DEFAULT 'outro',
    prioridade ENUM('baixa', 'media', 'alta', 'urgente') DEFAULT 'media',
    status ENUM('em_progresso', 'concluida', 'cancelada', 'pausada') DEFAULT 'em_progresso',
    valor_mensal_sugerido DECIMAL(15, 2),
    cor VARCHAR(7) DEFAULT '#28a745',
    icone VARCHAR(50) DEFAULT 'target',
    observacoes TEXT,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    data_conclusao TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    FOREIGN KEY (conta_destino_id) REFERENCES contas_bancarias(id) ON DELETE SET NULL,
    INDEX idx_usuario (usuario_id),
    INDEX idx_status (status),
    INDEX idx_data_alvo (data_alvo)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE LOGS DE EXPORTAÇÃO
-- ============================================================================
CREATE TABLE logs_exportacao (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT NOT NULL,
    tipo_exportacao ENUM('excel', 'csv', 'pdf', 'json') NOT NULL,
    filtros_aplicados JSON,
    periodo_inicio DATE,
    periodo_fim DATE,
    nome_arquivo VARCHAR(255),
    url_arquivo VARCHAR(500),
    tamanho_arquivo INT,
    status ENUM('processando', 'concluido', 'erro') DEFAULT 'processando',
    mensagem_erro TEXT,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    data_expiracao TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    INDEX idx_usuario (usuario_id),
    INDEX idx_data (data_criacao),
    INDEX idx_status (status)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE CONFIGURAÇÕES DO SISTEMA
-- ============================================================================
CREATE TABLE configuracoes_sistema (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT NOT NULL,
    chave VARCHAR(100) NOT NULL,
    valor TEXT,
    tipo_dado ENUM('string', 'integer', 'boolean', 'json') DEFAULT 'string',
    descricao VARCHAR(255),
    data_atualizacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    UNIQUE KEY uk_config (usuario_id, chave),
    INDEX idx_usuario (usuario_id),
    INDEX idx_chave (chave)
) ENGINE=InnoDB;

-- ============================================================================
-- TABELA DE NOTIFICAÇÕES
-- ============================================================================
CREATE TABLE notificacoes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    usuario_id INT NOT NULL,
    tipo ENUM('vencimento', 'orcamento', 'meta', 'fatura', 'sistema') NOT NULL,
    titulo VARCHAR(255) NOT NULL,
    mensagem TEXT NOT NULL,
    referencia_tipo VARCHAR(50),
    referencia_id INT,
    prioridade ENUM('baixa', 'media', 'alta') DEFAULT 'media',
    lida BOOLEAN DEFAULT FALSE,
    data_leitura TIMESTAMP NULL,
    data_criacao TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON DELETE CASCADE,
    INDEX idx_usuario (usuario_id),
    INDEX idx_lida (lida),
    INDEX idx_tipo (tipo),
    INDEX idx_data (data_criacao)
) ENGINE=InnoDB;

-- ============================================================================
-- INSERÇÃO DE DADOS INICIAIS
-- ============================================================================

-- Instituições Financeiras Brasileiras
INSERT INTO instituicoes_financeiras (nome, codigo_banco, ativo) VALUES
('Banco do Brasil', '001', TRUE),
('Banco Bradesco', '237', TRUE),
('Banco Itaú', '341', TRUE),
('Caixa Econômica Federal', '104', TRUE),
('Banco Santander', '033', TRUE),
('Nubank', '260', TRUE),
('Banco Inter', '077', TRUE),
('Banco C6', '336', TRUE),
('Banco Original', '212', TRUE),
('Banco Next', '237', TRUE),
('PagBank', '290', TRUE),
('Banco Neon', '655', TRUE),
('Mercado Pago', '323', TRUE),
('Picpay', '380', TRUE);

-- Categorias Padrão de Receitas
INSERT INTO categorias (nome, tipo, cor, icone, padrao_sistema, ordem_exibicao) VALUES
('Salário', 'receita', '#28a745', 'briefcase', TRUE, 1),
('Freelance', 'receita', '#20c997', 'laptop', TRUE, 2),
('Investimentos', 'receita', '#17a2b8', 'trending-up', TRUE, 3),
('Aluguel Recebido', 'receita', '#6f42c1', 'home', TRUE, 4),
('Vendas', 'receita', '#fd7e14', 'shopping-bag', TRUE, 5),
('Prêmios', 'receita', '#ffc107', 'award', TRUE, 6),
('Restituição', 'receita', '#6610f2', 'rotate-ccw', TRUE, 7),
('Outras Receitas', 'receita', '#6c757d', 'plus-circle', TRUE, 8);

-- Categorias Padrão de Despesas
INSERT INTO categorias (nome, tipo, cor, icone, padrao_sistema, ordem_exibicao) VALUES
('Alimentação', 'despesa', '#dc3545', 'utensils', TRUE, 1),
('Transporte', 'despesa', '#fd7e14', 'car', TRUE, 2),
('Moradia', 'despesa', '#6f42c1', 'home', TRUE, 3),
('Saúde', 'despesa', '#e83e8c', 'heart', TRUE, 4),
('Educação', 'despesa', '#007bff', 'book', TRUE, 5),
('Lazer', 'despesa', '#20c997', 'coffee', TRUE, 6),
('Vestuário', 'despesa', '#6610f2', 'shopping-bag', TRUE, 7),
('Beleza', 'despesa', '#d63384', 'scissors', TRUE, 8),
('Pets', 'despesa', '#fd7e14', 'github', TRUE, 9),
('Impostos', 'despesa', '#6c757d', 'file-text', TRUE, 10),
('Seguros', 'despesa', '#17a2b8', 'shield', TRUE, 11),
('Assinaturas', 'despesa', '#ffc107', 'repeat', TRUE, 12),
('Investimentos', 'despesa', '#28a745', 'trending-up', TRUE, 13),
('Outras Despesas', 'despesa', '#6c757d', 'minus-circle', TRUE, 14);

-- Subcategorias de Alimentação
INSERT INTO subcategorias (categoria_id, nome, icone, padrao_sistema, ordem_exibicao) VALUES
((SELECT id FROM categorias WHERE nome = 'Alimentação' AND tipo = 'despesa'), 'Supermercado', 'shopping-cart', TRUE, 1),
((SELECT id FROM categorias WHERE nome = 'Alimentação' AND tipo = 'despesa'), 'Restaurantes', 'utensils', TRUE, 2),
((SELECT id FROM categorias WHERE nome = 'Alimentação' AND tipo = 'despesa'), 'Lanchonetes', 'coffee', TRUE, 3),
((SELECT id FROM categorias WHERE nome = 'Alimentação' AND tipo = 'despesa'), 'Delivery', 'truck', TRUE, 4),
((SELECT id FROM categorias WHERE nome = 'Alimentação' AND tipo = 'despesa'), 'Padaria', 'gift', TRUE, 5);

-- Subcategorias de Transporte
INSERT INTO subcategorias (categoria_id, nome, icone, padrao_sistema, ordem_exibicao) VALUES
((SELECT id FROM categorias WHERE nome = 'Transporte' AND tipo = 'despesa'), 'Combustível', 'droplet', TRUE, 1),
((SELECT id FROM categorias WHERE nome = 'Transporte' AND tipo = 'despesa'), 'Transporte Público', 'bus', TRUE, 2),
((SELECT id FROM categorias WHERE nome = 'Transporte' AND tipo = 'despesa'), 'Uber/Taxi', 'smartphone', TRUE, 3),
((SELECT id FROM categorias WHERE nome = 'Transporte' AND tipo = 'despesa'), 'Manutenção Veículo', 'tool', TRUE, 4),
((SELECT id FROM categorias WHERE nome = 'Transporte' AND tipo = 'despesa'), 'IPVA/Licenciamento', 'file-text', TRUE, 5),
((SELECT id FROM categorias WHERE nome = 'Transporte' AND tipo = 'despesa'), 'Estacionamento', 'square', TRUE, 6);

-- Subcategorias de Moradia
INSERT INTO subcategorias (categoria_id, nome, icone, padrao_sistema, ordem_exibicao) VALUES
((SELECT id FROM categorias WHERE nome = 'Moradia' AND tipo = 'despesa'), 'Aluguel', 'home', TRUE, 1),
((SELECT id FROM categorias WHERE nome = 'Moradia' AND tipo = 'despesa'), 'Condomínio', 'building', TRUE, 2),
((SELECT id FROM categorias WHERE nome = 'Moradia' AND tipo = 'despesa'), 'Energia Elétrica', 'zap', TRUE, 3),
((SELECT id FROM categorias WHERE nome = 'Moradia' AND tipo = 'despesa'), 'Água', 'droplet', TRUE, 4),
((SELECT id FROM categorias WHERE nome = 'Moradia' AND tipo = 'despesa'), 'Internet', 'wifi', TRUE, 5),
((SELECT id FROM categorias WHERE nome = 'Moradia' AND tipo = 'despesa'), 'Gás', 'wind', TRUE, 6),
((SELECT id FROM categorias WHERE nome = 'Moradia' AND tipo = 'despesa'), 'IPTU', 'file-text', TRUE, 7),
((SELECT id FROM categorias WHERE nome = 'Moradia' AND tipo = 'despesa'), 'Manutenção', 'tool', TRUE, 8);

-- Subcategorias de Saúde
INSERT INTO subcategorias (categoria_id, nome, icone, padrao_sistema, ordem_exibicao) VALUES
((SELECT id FROM categorias WHERE nome = 'Saúde' AND tipo = 'despesa'), 'Plano de Saúde', 'heart', TRUE, 1),
((SELECT id FROM categorias WHERE nome = 'Saúde' AND tipo = 'despesa'), 'Consultas', 'user-check', TRUE, 2),
((SELECT id FROM categorias WHERE nome = 'Saúde' AND tipo = 'despesa'), 'Medicamentos', 'package', TRUE, 3),
((SELECT id FROM categorias WHERE nome = 'Saúde' AND tipo = 'despesa'), 'Exames', 'activity', TRUE, 4),
((SELECT id FROM categorias WHERE nome = 'Saúde' AND tipo = 'despesa'), 'Dentista', 'smile', TRUE, 5),
((SELECT id FROM categorias WHERE nome = 'Saúde' AND tipo = 'despesa'), 'Academia', 'activity', TRUE, 6);

-- Subcategorias de Assinaturas
INSERT INTO subcategorias (categoria_id, nome, icone, padrao_sistema, ordem_exibicao) VALUES
((SELECT id FROM categorias WHERE nome = 'Assinaturas' AND tipo = 'despesa'), 'Streaming (Netflix, etc)', 'tv', TRUE, 1),
((SELECT id FROM categorias WHERE nome = 'Assinaturas' AND tipo = 'despesa'), 'Música (Spotify, etc)', 'music', TRUE, 2),
((SELECT id FROM categorias WHERE nome = 'Assinaturas' AND tipo = 'despesa'), 'Software', 'code', TRUE, 3),
((SELECT id FROM categorias WHERE nome = 'Assinaturas' AND tipo = 'despesa'), 'Jornais/Revistas', 'book-open', TRUE, 4),
((SELECT id FROM categorias WHERE nome = 'Assinaturas' AND tipo = 'despesa'), 'Cloud Storage', 'cloud', TRUE, 5);

-- ============================================================================
-- VIEWS PARA RELATÓRIOS
-- ============================================================================

-- View: Resumo de Contas
CREATE OR REPLACE VIEW vw_resumo_contas AS
SELECT 
    cb.id,
    cb.usuario_id,
    cb.nome_conta,
    cb.tipo_conta,
    if_.nome AS instituicao,
    cb.saldo_atual,
    cb.limite_credito,
    (cb.saldo_atual + cb.limite_credito) AS saldo_total_disponivel,
    cb.cor_identificacao,
    cb.ativo
FROM contas_bancarias cb
LEFT JOIN instituicoes_financeiras if_ ON cb.instituicao_id = if_.id;

-- View: Resumo de Cartões
CREATE OR REPLACE VIEW vw_resumo_cartoes AS
SELECT 
    cc.id,
    cc.usuario_id,
    cc.nome_cartao,
    cc.bandeira,
    if_.nome AS instituicao,
    cc.limite_total,
    cc.limite_disponivel,
    (cc.limite_total - cc.limite_disponivel) AS valor_utilizado,
    ROUND(((cc.limite_total - cc.limite_disponivel) / cc.limite_total * 100), 2) AS percentual_utilizado,
    cc.dia_vencimento,
    cc.dia_fechamento,
    cc.ativo
FROM cartoes_credito cc
LEFT JOIN instituicoes_financeiras if_ ON cc.instituicao_id = if_.id;

-- View: Transações Detalhadas
CREATE OR REPLACE VIEW vw_transacoes_detalhadas AS
SELECT 
    t.id,
    t.usuario_id,
    t.tipo,
    t.descricao,
    t.valor,
    t.data_transacao,
    t.data_vencimento,
    t.status,
    c.nome AS categoria,
    sc.nome AS subcategoria,
    co.nome_conta AS conta_origem,
    cd.nome_conta AS conta_destino,
    cc.nome_cartao AS cartao,
    t.numero_parcelas,
    t.parcela_atual,
    CONCAT(t.parcela_atual, '/', t.numero_parcelas) AS parcelas_info,
    t.recorrente,
    t.observacoes,
    t.data_criacao
FROM transacoes t
LEFT JOIN categorias c ON t.categoria_id = c.id
LEFT JOIN subcategorias sc ON t.subcategoria_id = sc.id
LEFT JOIN contas_bancarias co ON t.conta_origem_id = co.id
LEFT JOIN contas_bancarias cd ON t.conta_destino_id = cd.id
LEFT JOIN cartoes_credito cc ON t.cartao_credito_id = cc.id;

-- View: Fluxo de Caixa Mensal
CREATE OR REPLACE VIEW vw_fluxo_caixa_mensal AS
SELECT 
    usuario_id,
    YEAR(data_transacao) AS ano,
    MONTH(data_transacao) AS mes,
    DATE_FORMAT(data_transacao, '%Y-%m') AS periodo,
    SUM(CASE WHEN tipo = 'receita' AND status = 'pago' THEN valor ELSE 0 END) AS total_receitas,
    SUM(CASE WHEN tipo = 'despesa' AND status = 'pago' THEN valor ELSE 0 END) AS total_despesas,
    (SUM(CASE WHEN tipo = 'receita' AND status = 'pago' THEN valor ELSE 0 END) - 
     SUM(CASE WHEN tipo = 'despesa' AND status = 'pago' THEN valor ELSE 0 END)) AS saldo_mensal,
    COUNT(*) AS total_transacoes
FROM transacoes
WHERE tipo IN ('receita', 'despesa')
GROUP BY usuario_id, YEAR(data_transacao), MONTH(data_transacao)
ORDER BY ano DESC, mes DESC;

-- View: Despesas por Categoria
CREATE OR REPLACE VIEW vw_despesas_por_categoria AS
SELECT 
    t.usuario_id,
    YEAR(t.data_transacao) AS ano,
    MONTH(t.data_transacao) AS mes,
    c.id AS categoria_id,
    c.nome AS categoria,
    c.cor AS cor_categoria,
    SUM(t.valor) AS total_gasto,
    COUNT(t.id) AS quantidade_transacoes,
    AVG(t.valor) AS ticket_medio
FROM transacoes t
INNER JOIN categorias c ON t.categoria_id = c.id
WHERE t.tipo = 'despesa' AND t.status = 'pago'
GROUP BY t.usuario_id, YEAR(t.data_transacao), MONTH(t.data_transacao), c.id
ORDER BY total_gasto DESC;

-- View: Orçamento vs Realizado
CREATE OR REPLACE VIEW vw_orcamento_realizado AS
SELECT 
    o.id,
    o.usuario_id,
    o.nome,
    o.mes_referencia,
    o.ano_referencia,
    c.nome AS categoria,
    sc.nome AS subcategoria,
    o.valor_planejado,
    COALESCE(SUM(t.valor), 0) AS valor_gasto,
    (o.valor_planejado - COALESCE(SUM(t.valor), 0)) AS saldo_restante,
    ROUND((COALESCE(SUM(t.valor), 0) / o.valor_planejado * 100), 2) AS percentual_utilizado,
    CASE 
        WHEN COALESCE(SUM(t.valor), 0) > o.valor_planejado THEN 'excedido'
        WHEN COALESCE(SUM(t.valor), 0) >= (o.valor_planejado * o.alerta_percentual / 100) THEN 'alerta'
        ELSE 'normal'
    END AS status_orcamento
FROM orcamentos o
LEFT JOIN categorias c ON o.categoria_id = c.id
LEFT JOIN subcategorias sc ON o.subcategoria_id = sc.id
LEFT JOIN transacoes t ON t.categoria_id = o.categoria_id 
    AND (t.subcategoria_id = o.subcategoria_id OR o.subcategoria_id IS NULL)
    AND t.usuario_id = o.usuario_id
    AND YEAR(t.data_transacao) = o.ano_referencia
    AND MONTH(t.data_transacao) = o.mes_referencia
    AND t.tipo = 'despesa'
    AND t.status = 'pago'
WHERE o.ativo = TRUE
GROUP BY o.id;

-- View: Progresso de Metas
CREATE OR REPLACE VIEW vw_progresso_metas AS
SELECT 
    mf.id,
    mf.usuario_id,
    mf.nome,
    mf.descricao,
    mf.valor_alvo,
    mf.valor_atual,
    (mf.valor_alvo - mf.valor_atual) AS valor_faltante,
    ROUND((mf.valor_atual / mf.valor_alvo * 100), 2) AS percentual_concluido,
    mf.data_inicio,
    mf.data_alvo,
    DATEDIFF(mf.data_alvo, CURDATE()) AS dias_restantes,
    mf.valor_mensal_sugerido,
    mf.prioridade,
    mf.status,
    cb.nome_conta AS conta_destino,
    CASE 
        WHEN mf.valor_atual >= mf.valor_alvo THEN 'concluida'
        WHEN DATEDIFF(mf.data_alvo, CURDATE()) < 0 THEN 'vencida'
        WHEN DATEDIFF(mf.data_alvo, CURDATE()) <= 30 THEN 'urgente'
        ELSE 'em_dia'
    END AS situacao
FROM metas_financeiras mf
LEFT JOIN contas_bancarias cb ON mf.conta_destino_id = cb.id;

-- View: Faturas de Cartão Detalhadas
CREATE OR REPLACE VIEW vw_faturas_detalhadas AS
SELECT 
    f.id,
    f.usuario_id,
    cc.nome_cartao,
    cc.bandeira,
    f.mes_referencia,
    f.ano_referencia,
    DATE_FORMAT(CONCAT(f.ano_referencia, '-', LPAD(f.mes_referencia, 2, '0'), '-01'), '%M/%Y') AS periodo,
    f.data_fechamento,
    f.data_vencimento,
    f.valor_total,
    f.valor_pago,
    (f.valor_total - f.valor_pago) AS saldo_devedor,
    f.status,
    cb.nome_conta AS conta_pagamento,
    f.data_pagamento,
    DATEDIFF(f.data_vencimento, CURDATE()) AS dias_para_vencimento,
    CASE 
        WHEN f.status = 'paga' THEN 'paga'
        WHEN f.data_vencimento < CURDATE() THEN 'vencida'
        WHEN DATEDIFF(f.data_vencimento, CURDATE()) <= 3 THEN 'vence_em_breve'
        ELSE 'em_dia'
    END AS situacao
FROM faturas_cartao f
INNER JOIN cartoes_credito cc ON f.cartao_credito_id = cc.id
LEFT JOIN contas_bancarias cb ON f.conta_pagamento_id = cb.id;

-- ============================================================================
-- STORED PROCEDURES
-- ============================================================================

DELIMITER //

-- Procedure: Calcular Saldo Atual de Conta
CREATE PROCEDURE sp_calcular_saldo_conta(IN p_conta_id INT)
BEGIN
    DECLARE v_saldo_inicial DECIMAL(15,2);
    DECLARE v_total_receitas DECIMAL(15,2);
    DECLARE v_total_despesas DECIMAL(15,2);
    DECLARE v_total_transferencias_entrada DECIMAL(15,2);
    DECLARE v_total_transferencias_saida DECIMAL(15,2);
    DECLARE v_saldo_atual DECIMAL(15,2);
    
    -- Obter saldo inicial
    SELECT saldo_inicial INTO v_saldo_inicial 
    FROM contas_bancarias 
    WHERE id = p_conta_id;
    
    -- Calcular total de receitas pagas
    SELECT COALESCE(SUM(valor), 0) INTO v_total_receitas
    FROM transacoes
    WHERE conta_origem_id = p_conta_id 
        AND tipo = 'receita' 
        AND status = 'pago';
    
    -- Calcular total de despesas pagas
    SELECT COALESCE(SUM(valor), 0) INTO v_total_despesas
    FROM transacoes
    WHERE conta_origem_id = p_conta_id 
        AND tipo = 'despesa' 
        AND status = 'pago';
    
    -- Calcular transferências de entrada
    SELECT COALESCE(SUM(valor), 0) INTO v_total_transferencias_entrada
    FROM transacoes
    WHERE conta_destino_id = p_conta_id 
        AND tipo = 'transferencia' 
        AND status = 'pago';
    
    -- Calcular transferências de saída
    SELECT COALESCE(SUM(valor), 0) INTO v_total_transferencias_saida
    FROM transacoes
    WHERE conta_origem_id = p_conta_id 
        AND tipo = 'transferencia' 
        AND status = 'pago';
    
    -- Calcular saldo atual
    SET v_saldo_atual = v_saldo_inicial + v_total_receitas - v_total_despesas 
                       + v_total_transferencias_entrada - v_total_transferencias_saida;
    
    -- Atualizar saldo da conta
    UPDATE contas_bancarias 
    SET saldo_atual = v_saldo_atual 
    WHERE id = p_conta_id;
    
    SELECT v_saldo_atual AS saldo_calculado;
END //

-- Procedure: Atualizar Limite Disponível do Cartão
CREATE PROCEDURE sp_atualizar_limite_cartao(IN p_cartao_id INT)
BEGIN
    DECLARE v_limite_total DECIMAL(15,2);
    DECLARE v_total_utilizado DECIMAL(15,2);
    DECLARE v_limite_disponivel DECIMAL(15,2);
    
    -- Obter limite total
    SELECT limite_total INTO v_limite_total
    FROM cartoes_credito
    WHERE id = p_cartao_id;
    
    -- Calcular total utilizado (faturas abertas e fechadas não pagas)
    SELECT COALESCE(SUM(t.valor), 0) INTO v_total_utilizado
    FROM transacoes t
    INNER JOIN faturas_cartao f ON f.cartao_credito_id = t.cartao_credito_id
        AND YEAR(t.data_transacao) = f.ano_referencia
        AND MONTH(t.data_transacao) = f.mes_referencia
    WHERE t.cartao_credito_id = p_cartao_id
        AND t.tipo = 'despesa'
        AND f.status IN ('aberta', 'fechada');
    
    -- Calcular limite disponível
    SET v_limite_disponivel = v_limite_total - v_total_utilizado;
    
    -- Atualizar limite disponível
    UPDATE cartoes_credito
    SET limite_disponivel = v_limite_disponivel
    WHERE id = p_cartao_id;
    
    SELECT v_limite_disponivel AS limite_disponivel;
END //

-- Procedure: Registrar Transação com Atualização Automática
CREATE PROCEDURE sp_registrar_transacao(
    IN p_usuario_id INT,
    IN p_tipo VARCHAR(20),
    IN p_descricao VARCHAR(255),
    IN p_valor DECIMAL(15,2),
    IN p_data_transacao DATE,
    IN p_categoria_id INT,
    IN p_subcategoria_id INT,
    IN p_conta_origem_id INT,
    IN p_conta_destino_id INT,
    IN p_cartao_credito_id INT,
    IN p_status VARCHAR(20),
    IN p_numero_parcelas INT,
    OUT p_transacao_id INT
)
BEGIN
    DECLARE v_parcela INT DEFAULT 1;
    DECLARE v_data_parcela DATE;
    
    -- Se for parcelado, criar todas as parcelas
    IF p_numero_parcelas > 1 THEN
        WHILE v_parcela <= p_numero_parcelas DO
            SET v_data_parcela = DATE_ADD(p_data_transacao, INTERVAL (v_parcela - 1) MONTH);
            
            INSERT INTO transacoes (
                usuario_id, tipo, descricao, valor, data_transacao, data_vencimento,
                categoria_id, subcategoria_id, conta_origem_id, conta_destino_id,
                cartao_credito_id, status, numero_parcelas, parcela_atual,
                transacao_pai_id
            ) VALUES (
                p_usuario_id, p_tipo, 
                CONCAT(p_descricao, ' (', v_parcela, '/', p_numero_parcelas, ')'),
                p_valor / p_numero_parcelas, v_data_parcela, v_data_parcela,
                p_categoria_id, p_subcategoria_id, p_conta_origem_id, p_conta_destino_id,
                p_cartao_credito_id, p_status, p_numero_parcelas, v_parcela,
                IF(v_parcela = 1, NULL, LAST_INSERT_ID())
            );
            
            IF v_parcela = 1 THEN
                SET p_transacao_id = LAST_INSERT_ID();
            END IF;
            
            SET v_parcela = v_parcela + 1;
        END WHILE;
    ELSE
        -- Transação simples (não parcelada)
        INSERT INTO transacoes (
            usuario_id, tipo, descricao, valor, data_transacao, data_vencimento,
            categoria_id, subcategoria_id, conta_origem_id, conta_destino_id,
            cartao_credito_id, status, numero_parcelas, parcela_atual
        ) VALUES (
            p_usuario_id, p_tipo, p_descricao, p_valor, p_data_transacao, p_data_transacao,
            p_categoria_id, p_subcategoria_id, p_conta_origem_id, p_conta_destino_id,
            p_cartao_credito_id, p_status, 1, 1
        );
        
        SET p_transacao_id = LAST_INSERT_ID();
    END IF;
    
    -- Atualizar saldo da conta se for transação paga
    IF p_status = 'pago' THEN
        IF p_conta_origem_id IS NOT NULL THEN
            CALL sp_calcular_saldo_conta(p_conta_origem_id);
        END IF;
        IF p_conta_destino_id IS NOT NULL THEN
            CALL sp_calcular_saldo_conta(p_conta_destino_id);
        END IF;
    END IF;
    
    -- Atualizar limite do cartão se aplicável
    IF p_cartao_credito_id IS NOT NULL THEN
        CALL sp_atualizar_limite_cartao(p_cartao_credito_id);
    END IF;
END //

-- Procedure: Gerar Faturas do Mês
CREATE PROCEDURE sp_gerar_faturas_mes(
    IN p_usuario_id INT,
    IN p_mes INT,
    IN p_ano INT
)
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE v_cartao_id INT;
    DECLARE v_dia_fechamento INT;
    DECLARE v_dia_vencimento INT;
    DECLARE v_data_fechamento DATE;
    DECLARE v_data_vencimento DATE;
    
    DECLARE cursor_cartoes CURSOR FOR 
        SELECT id, dia_fechamento, dia_vencimento 
        FROM cartoes_credito 
        WHERE usuario_id = p_usuario_id AND ativo = TRUE;
    
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
    OPEN cursor_cartoes;
    
    read_loop: LOOP
        FETCH cursor_cartoes INTO v_cartao_id, v_dia_fechamento, v_dia_vencimento;
        IF done THEN
            LEAVE read_loop;
        END IF;
        
        -- Calcular datas de fechamento e vencimento
        SET v_data_fechamento = DATE(CONCAT(p_ano, '-', LPAD(p_mes, 2, '0'), '-', LPAD(v_dia_fechamento, 2, '0')));
        SET v_data_vencimento = DATE(CONCAT(p_ano, '-', LPAD(p_mes, 2, '0'), '-', LPAD(v_dia_vencimento, 2, '0')));
        
        -- Inserir fatura se não existir
        INSERT IGNORE INTO faturas_cartao (
            cartao_credito_id, usuario_id, mes_referencia, ano_referencia,
            data_fechamento, data_vencimento, status
        ) VALUES (
            v_cartao_id, p_usuario_id, p_mes, p_ano,
            v_data_fechamento, v_data_vencimento, 'aberta'
        );
    END LOOP;
    
    CLOSE cursor_cartoes;
END //

-- Procedure: Fechar Fatura
CREATE PROCEDURE sp_fechar_fatura(IN p_fatura_id INT)
BEGIN
    DECLARE v_cartao_id INT;
    DECLARE v_mes INT;
    DECLARE v_ano INT;
    DECLARE v_total DECIMAL(15,2);
    
    -- Obter dados da fatura
    SELECT cartao_credito_id, mes_referencia, ano_referencia
    INTO v_cartao_id, v_mes, v_ano
    FROM faturas_cartao
    WHERE id = p_fatura_id;
    
    -- Calcular valor total
    SELECT COALESCE(SUM(valor), 0) INTO v_total
    FROM transacoes
    WHERE cartao_credito_id = v_cartao_id
        AND YEAR(data_transacao) = v_ano
        AND MONTH(data_transacao) = v_mes
        AND tipo = 'despesa'
        AND status = 'pago';
    
    -- Atualizar fatura
    UPDATE faturas_cartao
    SET valor_total = v_total,
        status = 'fechada'
    WHERE id = p_fatura_id;
    
    SELECT v_total AS valor_fatura;
END //

DELIMITER ;

-- ============================================================================
-- TRIGGERS
-- ============================================================================

DELIMITER //

-- Trigger: Atualizar saldo após inserir transação
CREATE TRIGGER trg_after_insert_transacao
AFTER INSERT ON transacoes
FOR EACH ROW
BEGIN
    IF NEW.status = 'pago' THEN
        -- Atualizar conta origem
        IF NEW.conta_origem_id IS NOT NULL THEN
            CALL sp_calcular_saldo_conta(NEW.conta_origem_id);
        END IF;
        
        -- Atualizar conta destino
        IF NEW.conta_destino_id IS NOT NULL THEN
            CALL sp_calcular_saldo_conta(NEW.conta_destino_id);
        END IF;
        
        -- Atualizar limite do cartão
        IF NEW.cartao_credito_id IS NOT NULL THEN
            CALL sp_atualizar_limite_cartao(NEW.cartao_credito_id);
        END IF;
    END IF;
END //

-- Trigger: Atualizar saldo após atualizar transação
CREATE TRIGGER trg_after_update_transacao
AFTER UPDATE ON transacoes
FOR EACH ROW
BEGIN
    -- Se o status mudou para 'pago'
    IF OLD.status != 'pago' AND NEW.status = 'pago' THEN
        IF NEW.conta_origem_id IS NOT NULL THEN
            CALL sp_calcular_saldo_conta(NEW.conta_origem_id);
        END IF;
        IF NEW.conta_destino_id IS NOT NULL THEN
            CALL sp_calcular_saldo_conta(NEW.conta_destino_id);
        END IF;
        IF NEW.cartao_credito_id IS NOT NULL THEN
            CALL sp_atualizar_limite_cartao(NEW.cartao_credito_id);
        END IF;
    END IF;
    
    -- Se o status mudou de 'pago' para outro
    IF OLD.status = 'pago' AND NEW.status != 'pago' THEN
        IF OLD.conta_origem_id IS NOT NULL THEN
            CALL sp_calcular_saldo_conta(OLD.conta_origem_id);
        END IF;
        IF OLD.conta_destino_id IS NOT NULL THEN
            CALL sp_calcular_saldo_conta(OLD.conta_destino_id);
        END IF;
        IF OLD.cartao_credito_id IS NOT NULL THEN
            CALL sp_atualizar_limite_cartao(OLD.cartao_credito_id);
        END IF;
    END IF;
END //

-- Trigger: Atualizar orçamento após transação
CREATE TRIGGER trg_after_insert_transacao_orcamento
AFTER INSERT ON transacoes
FOR EACH ROW
BEGIN
    IF NEW.tipo = 'despesa' AND NEW.status = 'pago' THEN
        UPDATE orcamentos
        SET valor_gasto = valor_gasto + NEW.valor
        WHERE usuario_id = NEW.usuario_id
            AND categoria_id = NEW.categoria_id
            AND (subcategoria_id = NEW.subcategoria_id OR subcategoria_id IS NULL)
            AND mes_referencia = MONTH(NEW.data_transacao)
            AND ano_referencia = YEAR(NEW.data_transacao)
            AND ativo = TRUE;
    END IF;
END //

DELIMITER ;

-- ============================================================================
-- FUNÇÕES PARA EXPORTAÇÃO (QUERIES OTIMIZADAS)
-- ============================================================================

-- Função auxiliar para exportar transações para Excel
DELIMITER //

CREATE PROCEDURE sp_exportar_transacoes_excel(
    IN p_usuario_id INT,
    IN p_data_inicio DATE,
    IN p_data_fim DATE,
    IN p_tipo VARCHAR(20),
    IN p_categoria_id INT,
    IN p_conta_id INT,
    IN p_cartao_id INT
)
BEGIN
    SELECT 
        t.id AS 'ID',
        DATE_FORMAT(t.data_transacao, '%d/%m/%Y') AS 'Data',
        t.tipo AS 'Tipo',
        t.descricao AS 'Descrição',
        CONCAT('R$ ', FORMAT(t.valor, 2, 'pt_BR')) AS 'Valor',
        c.nome AS 'Categoria',
        sc.nome AS 'Subcategoria',
        co.nome_conta AS 'Conta Origem',
        cd.nome_conta AS 'Conta Destino',
        cc.nome_cartao AS 'Cartão',
        t.status AS 'Status',
        CASE 
            WHEN t.numero_parcelas > 1 THEN CONCAT(t.parcela_atual, '/', t.numero_parcelas)
            ELSE '-'
        END AS 'Parcelas',
        CASE WHEN t.recorrente = 1 THEN 'Sim' ELSE 'Não' END AS 'Recorrente',
        t.observacoes AS 'Observações'
    FROM transacoes t
    LEFT JOIN categorias c ON t.categoria_id = c.id
    LEFT JOIN subcategorias sc ON t.subcategoria_id = sc.id
    LEFT JOIN contas_bancarias co ON t.conta_origem_id = co.id
    LEFT JOIN contas_bancarias cd ON t.conta_destino_id = cd.id
    LEFT JOIN cartoes_credito cc ON t.cartao_credito_id = cc.id
    WHERE t.usuario_id = p_usuario_id
        AND (p_data_inicio IS NULL OR t.data_transacao >= p_data_inicio)
        AND (p_data_fim IS NULL OR t.data_transacao <= p_data_fim)
        AND (p_tipo IS NULL OR t.tipo = p_tipo)
        AND (p_categoria_id IS NULL OR t.categoria_id = p_categoria_id)
        AND (p_conta_id IS NULL OR t.conta_origem_id = p_conta_id OR t.conta_destino_id = p_conta_id)
        AND (p_cartao_id IS NULL OR t.cartao_credito_id = p_cartao_id)
    ORDER BY t.data_transacao DESC, t.id DESC;
END //

DELIMITER ;

-- ============================================================================
-- ÍNDICES ADICIONAIS PARA PERFORMANCE
-- ============================================================================

CREATE INDEX idx_transacoes_usuario_data ON transacoes(usuario_id, data_transacao);
CREATE INDEX idx_transacoes_categoria_data ON transacoes(categoria_id, data_transacao);
CREATE INDEX idx_faturas_periodo ON faturas_cartao(ano_referencia, mes_referencia);
CREATE INDEX idx_orcamentos_periodo ON orcamentos(ano_referencia, mes_referencia);

-- ============================================================================
-- COMENTÁRIOS DAS TABELAS
-- ============================================================================

ALTER TABLE usuarios COMMENT = 'Tabela de usuários do sistema';
ALTER TABLE instituicoes_financeiras COMMENT = 'Cadastro de bancos e instituições financeiras';
ALTER TABLE contas_bancarias COMMENT = 'Contas bancárias dos usuários';
ALTER TABLE cartoes_credito COMMENT = 'Cartões de crédito dos usuários';
ALTER TABLE categorias COMMENT = 'Categorias de transações';
ALTER TABLE subcategorias COMMENT = 'Subcategorias vinculadas às categorias';
ALTER TABLE transacoes COMMENT = 'Registro de todas as transações financeiras';
ALTER TABLE faturas_cartao COMMENT = 'Faturas mensais dos cartões de crédito';
ALTER TABLE orcamentos COMMENT = 'Orçamentos planejados por categoria';
ALTER TABLE metas_financeiras COMMENT = 'Metas e objetivos financeiros';
ALTER TABLE logs_exportacao COMMENT = 'Histórico de exportações realizadas';
ALTER TABLE configuracoes_sistema COMMENT = 'Configurações personalizadas por usuário';
ALTER TABLE notificacoes COMMENT = 'Notificações e alertas do sistema';

-- ============================================================================
-- FIM DO SCRIPT
-- ============================================================================

SELECT 'Sistema de Controle Financeiro criado com sucesso!' AS Status;
SELECT 'Tabelas, Views, Procedures, Triggers e Dados iniciais carregados.' AS Detalhes;
