CREATE DATABASE IF NOT EXISTS bulo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE bulo;

CREATE TABLE IF NOT EXISTS usuarios (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nome VARCHAR(120) NOT NULL,
  primeiro_nome VARCHAR(80) NULL,
  sobrenome VARCHAR(120) NULL,
  cpf VARCHAR(20) NOT NULL UNIQUE,
  email VARCHAR(160) NOT NULL UNIQUE,
  celular VARCHAR(20) NOT NULL,
  telefone_verificado TINYINT(1) NOT NULL DEFAULT 0,
  telefone_verificado_em DATETIME NULL,
  firebase_phone_uid VARCHAR(128) NULL,
  firebase_phone VARCHAR(24) NULL,
  senha_hash VARCHAR(255) NOT NULL,
  tipo ENUM('passageiro', 'motorista') NOT NULL DEFAULT 'passageiro',
  codigoind VARCHAR(20) NOT NULL UNIQUE,
  indicador_codigo VARCHAR(20) NULL,
  cep VARCHAR(10) NULL,
  endereco_logradouro VARCHAR(160) NULL,
  endereco_numero VARCHAR(20) NULL,
  endereco_complemento VARCHAR(80) NULL,
  endereco_bairro VARCHAR(100) NULL,
  endereco_cidade VARCHAR(100) NULL,
  endereco_uf CHAR(2) NULL,
  foto_url VARCHAR(255) NULL,
  cnh_url VARCHAR(255) NULL,
  documento_veiculo_url VARCHAR(255) NULL,
  selfie_url VARCHAR(255) NULL,
  cnh_status ENUM('pendente', 'aprovado', 'reprovado') NOT NULL DEFAULT 'pendente',
  cnh_observacao VARCHAR(255) NULL,
  cnh_vencimento DATE NULL,
  cnh_aprovado_por VARCHAR(80) NULL,
  cnh_aprovado_em DATETIME NULL,
  documento_veiculo_status ENUM('pendente', 'aprovado', 'reprovado') NOT NULL DEFAULT 'pendente',
  documento_veiculo_observacao VARCHAR(255) NULL,
  documento_veiculo_vencimento DATE NULL,
  documento_veiculo_aprovado_por VARCHAR(80) NULL,
  documento_veiculo_aprovado_em DATETIME NULL,
  selfie_status ENUM('pendente', 'aprovado', 'reprovado') NOT NULL DEFAULT 'pendente',
  selfie_observacao VARCHAR(255) NULL,
  selfie_aprovado_por VARCHAR(80) NULL,
  selfie_aprovado_em DATETIME NULL,
  status_verificacao ENUM('pendente', 'aprovado', 'reprovado') NOT NULL DEFAULT 'pendente',
  observacao_verificacao VARCHAR(255) NULL,
  disponivel ENUM('sim', 'nao') NOT NULL DEFAULT 'nao',
  id_veiculo_ativo INT NULL,
  ultimo_lat DECIMAL(10,7) NULL,
  ultimo_lng DECIMAL(10,7) NULL,
  ultimo_rumo DECIMAL(6,2) NULL,
  localizacao_atualizada_em DATETIME NULL,
  banco_nome VARCHAR(80) NULL,
  banco_agencia VARCHAR(20) NULL,
  banco_conta VARCHAR(30) NULL,
  banco_tipo_conta ENUM('corrente', 'poupanca', 'pagamento') NULL,
  banco_titular_nome VARCHAR(120) NULL,
  banco_titular_documento VARCHAR(20) NULL,
  pix_tipo ENUM('cpf', 'cnpj', 'email', 'celular', 'aleatoria') NULL,
  pix_chave VARCHAR(120) NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  INDEX idx_usuarios_tipo (tipo),
  INDEX idx_usuarios_codigoind (codigoind),
  INDEX idx_usuarios_telefone_verificado (telefone_verificado),
  INDEX idx_usuarios_firebase_phone_uid (firebase_phone_uid),
  INDEX idx_usuarios_veiculo_ativo (id_veiculo_ativo),
  INDEX idx_usuarios_tempo_real (tipo, disponivel, localizacao_atualizada_em)
);

CREATE TABLE IF NOT EXISTS veiculos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_motorista INT NOT NULL,
  id_marca_catalogo INT NULL,
  id_modelo_catalogo INT NULL,
  id_cor_catalogo INT NULL,
  marca VARCHAR(80) NULL,
  modelo VARCHAR(80) NULL,
  ano_fabricacao INT NULL,
  ano_modelo INT NULL,
  cor VARCHAR(40) NULL,
  placa VARCHAR(10) NULL,
  documento_url VARCHAR(255) NULL,
  status ENUM('pendente', 'aprovado', 'reprovado') NOT NULL DEFAULT 'pendente',
  observacao_revisao VARCHAR(255) NULL,
  documento_vencimento DATE NULL,
  aprovado_por VARCHAR(80) NULL,
  aprovado_em DATETIME NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  INDEX idx_veiculos_placa (placa),
  CONSTRAINT fk_veiculos_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id)
);

CREATE TABLE IF NOT EXISTS veiculo_marcas_catalogo (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nome VARCHAR(80) NOT NULL,
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY uk_veiculo_marcas_nome (nome),
  INDEX idx_veiculo_marcas_ativo (ativo)
);

CREATE TABLE IF NOT EXISTS veiculo_modelos_catalogo (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_marca INT NOT NULL,
  nome VARCHAR(120) NOT NULL,
  categoria_economica TINYINT(1) NOT NULL DEFAULT 1,
  categoria_plus TINYINT(1) NOT NULL DEFAULT 0,
  categoria_pro TINYINT(1) NOT NULL DEFAULT 0,
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_modelos_catalogo_marca FOREIGN KEY (id_marca) REFERENCES veiculo_marcas_catalogo(id),
  UNIQUE KEY uk_modelos_catalogo_marca_nome (id_marca, nome),
  INDEX idx_modelos_catalogo_marca (id_marca),
  INDEX idx_modelos_catalogo_ativo (ativo),
  INDEX idx_modelos_catalogo_categorias (categoria_economica, categoria_plus, categoria_pro)
);

CREATE TABLE IF NOT EXISTS veiculo_cores_catalogo (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nome VARCHAR(60) NOT NULL,
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY uk_veiculo_cores_nome (nome),
  INDEX idx_veiculo_cores_ativo (ativo)
);

INSERT INTO veiculo_marcas_catalogo (nome) VALUES
  ('Audi'), ('BMW'), ('BYD'), ('Caoa Chery'), ('Chevrolet'), ('Citroen'),
  ('Fiat'), ('Ford'), ('GWM'), ('Honda'), ('Hyundai'), ('Jeep'), ('Kia'),
  ('Land Rover'), ('Mercedes-Benz'), ('Mitsubishi'), ('Nissan'), ('Peugeot'),
  ('RAM'), ('Renault'), ('Toyota'), ('Volkswagen'), ('Volvo')
ON DUPLICATE KEY UPDATE ativo = VALUES(ativo);

INSERT INTO veiculo_modelos_catalogo (id_marca, nome, categoria_economica, categoria_plus, categoria_pro)
SELECT m.id, x.modelo, 1, 0, 0
FROM veiculo_marcas_catalogo m
INNER JOIN (
  SELECT 'Chevrolet' marca, 'Onix' modelo UNION ALL
  SELECT 'Chevrolet', 'Onix Plus' UNION ALL
  SELECT 'Chevrolet', 'Tracker' UNION ALL
  SELECT 'Chevrolet', 'Spin' UNION ALL
  SELECT 'Chevrolet', 'Montana' UNION ALL
  SELECT 'Chevrolet', 'S10' UNION ALL
  SELECT 'Chevrolet', 'Cruze' UNION ALL
  SELECT 'Fiat', 'Argo' UNION ALL
  SELECT 'Fiat', 'Cronos' UNION ALL
  SELECT 'Fiat', 'Mobi' UNION ALL
  SELECT 'Fiat', 'Pulse' UNION ALL
  SELECT 'Fiat', 'Fastback' UNION ALL
  SELECT 'Fiat', 'Strada' UNION ALL
  SELECT 'Fiat', 'Toro' UNION ALL
  SELECT 'Fiat', 'Fiorino' UNION ALL
  SELECT 'Fiat', 'Palio' UNION ALL
  SELECT 'Fiat', 'Uno' UNION ALL
  SELECT 'Fiat', 'Grand Siena' UNION ALL
  SELECT 'Volkswagen', 'Polo' UNION ALL
  SELECT 'Volkswagen', 'Virtus' UNION ALL
  SELECT 'Volkswagen', 'Nivus' UNION ALL
  SELECT 'Volkswagen', 'T-Cross' UNION ALL
  SELECT 'Volkswagen', 'Taos' UNION ALL
  SELECT 'Volkswagen', 'Saveiro' UNION ALL
  SELECT 'Volkswagen', 'Jetta' UNION ALL
  SELECT 'Volkswagen', 'Gol' UNION ALL
  SELECT 'Volkswagen', 'Voyage' UNION ALL
  SELECT 'Volkswagen', 'Fox' UNION ALL
  SELECT 'Volkswagen', 'Up' UNION ALL
  SELECT 'Hyundai', 'HB20' UNION ALL
  SELECT 'Hyundai', 'HB20S' UNION ALL
  SELECT 'Hyundai', 'Creta' UNION ALL
  SELECT 'Hyundai', 'Tucson' UNION ALL
  SELECT 'Hyundai', 'Santa Fe' UNION ALL
  SELECT 'Toyota', 'Corolla' UNION ALL
  SELECT 'Toyota', 'Corolla Cross' UNION ALL
  SELECT 'Toyota', 'Yaris Hatch' UNION ALL
  SELECT 'Toyota', 'Yaris Sedan' UNION ALL
  SELECT 'Toyota', 'Hilux' UNION ALL
  SELECT 'Toyota', 'SW4' UNION ALL
  SELECT 'Toyota', 'RAV4' UNION ALL
  SELECT 'Toyota', 'Etios Hatch' UNION ALL
  SELECT 'Toyota', 'Etios Sedan' UNION ALL
  SELECT 'Honda', 'City Hatchback' UNION ALL
  SELECT 'Honda', 'City Sedan' UNION ALL
  SELECT 'Honda', 'Civic' UNION ALL
  SELECT 'Honda', 'HR-V' UNION ALL
  SELECT 'Honda', 'ZR-V' UNION ALL
  SELECT 'Honda', 'Fit' UNION ALL
  SELECT 'Honda', 'WR-V' UNION ALL
  SELECT 'Renault', 'Kwid' UNION ALL
  SELECT 'Renault', 'Stepway' UNION ALL
  SELECT 'Renault', 'Duster' UNION ALL
  SELECT 'Renault', 'Oroch' UNION ALL
  SELECT 'Renault', 'Kardian' UNION ALL
  SELECT 'Renault', 'Sandero' UNION ALL
  SELECT 'Renault', 'Logan' UNION ALL
  SELECT 'Nissan', 'Kicks' UNION ALL
  SELECT 'Nissan', 'Versa' UNION ALL
  SELECT 'Nissan', 'Sentra' UNION ALL
  SELECT 'Nissan', 'Frontier' UNION ALL
  SELECT 'Nissan', 'March' UNION ALL
  SELECT 'Jeep', 'Renegade' UNION ALL
  SELECT 'Jeep', 'Compass' UNION ALL
  SELECT 'Jeep', 'Commander' UNION ALL
  SELECT 'Peugeot', '208' UNION ALL
  SELECT 'Peugeot', '2008' UNION ALL
  SELECT 'Peugeot', '3008' UNION ALL
  SELECT 'Citroen', 'C3' UNION ALL
  SELECT 'Citroen', 'C3 Aircross' UNION ALL
  SELECT 'Citroen', 'Basalt' UNION ALL
  SELECT 'Ford', 'Territory' UNION ALL
  SELECT 'Ford', 'Ranger' UNION ALL
  SELECT 'Ford', 'Maverick' UNION ALL
  SELECT 'Ford', 'Ka' UNION ALL
  SELECT 'Ford', 'Fiesta' UNION ALL
  SELECT 'Ford', 'EcoSport' UNION ALL
  SELECT 'Ford', 'Focus' UNION ALL
  SELECT 'Mitsubishi', 'Outlander' UNION ALL
  SELECT 'Mitsubishi', 'Eclipse Cross' UNION ALL
  SELECT 'Mitsubishi', 'L200 Triton' UNION ALL
  SELECT 'Caoa Chery', 'Tiggo 5X' UNION ALL
  SELECT 'Caoa Chery', 'Tiggo 7' UNION ALL
  SELECT 'Caoa Chery', 'Tiggo 8' UNION ALL
  SELECT 'Caoa Chery', 'Arrizo 6' UNION ALL
  SELECT 'BYD', 'Dolphin' UNION ALL
  SELECT 'BYD', 'Dolphin Mini' UNION ALL
  SELECT 'BYD', 'Song Plus' UNION ALL
  SELECT 'BYD', 'Song Pro' UNION ALL
  SELECT 'BYD', 'Yuan Plus' UNION ALL
  SELECT 'BYD', 'Seal' UNION ALL
  SELECT 'GWM', 'Haval H6' UNION ALL
  SELECT 'GWM', 'Ora 03' UNION ALL
  SELECT 'Kia', 'Sportage' UNION ALL
  SELECT 'Kia', 'Stonic' UNION ALL
  SELECT 'Kia', 'Cerato' UNION ALL
  SELECT 'Mercedes-Benz', 'Classe A' UNION ALL
  SELECT 'Mercedes-Benz', 'Classe C' UNION ALL
  SELECT 'Mercedes-Benz', 'GLA' UNION ALL
  SELECT 'Mercedes-Benz', 'GLB' UNION ALL
  SELECT 'BMW', 'Serie 1' UNION ALL
  SELECT 'BMW', 'Serie 3' UNION ALL
  SELECT 'BMW', 'X1' UNION ALL
  SELECT 'BMW', 'X3' UNION ALL
  SELECT 'Audi', 'A3' UNION ALL
  SELECT 'Audi', 'A4' UNION ALL
  SELECT 'Audi', 'Q3' UNION ALL
  SELECT 'Audi', 'Q5' UNION ALL
  SELECT 'Volvo', 'XC40' UNION ALL
  SELECT 'Volvo', 'XC60' UNION ALL
  SELECT 'Volvo', 'EX30' UNION ALL
  SELECT 'Land Rover', 'Discovery Sport' UNION ALL
  SELECT 'Land Rover', 'Range Rover Evoque' UNION ALL
  SELECT 'RAM', 'Rampage' UNION ALL
  SELECT 'RAM', '1500'
) x ON x.marca = m.nome
ON DUPLICATE KEY UPDATE categoria_economica = VALUES(categoria_economica);

INSERT INTO veiculo_cores_catalogo (nome) VALUES
  ('Branco'), ('Preto'), ('Prata'), ('Cinza'), ('Grafite'), ('Vermelho'),
  ('Azul'), ('Verde'), ('Amarelo'), ('Bege'), ('Marrom'), ('Laranja'),
  ('Dourado'), ('Vinho')
ON DUPLICATE KEY UPDATE ativo = VALUES(ativo);

ALTER TABLE usuarios
  ADD CONSTRAINT fk_usuarios_veiculo_ativo
  FOREIGN KEY (id_veiculo_ativo) REFERENCES veiculos(id)
  ON DELETE SET NULL;

CREATE TABLE IF NOT EXISTS corridas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_passageiro INT NOT NULL,
  id_motorista INT NULL,
  origem_lat DECIMAL(10,7) NULL,
  origem_lng DECIMAL(10,7) NULL,
  origem_endereco VARCHAR(255) NULL,
  destino_lat DECIMAL(10,7) NULL,
  destino_lng DECIMAL(10,7) NULL,
  destino_endereco VARCHAR(255) NULL,
  distancia DECIMAL(10,2) NULL,
  tempo_estimado VARCHAR(60) NULL,
  valor DECIMAL(10,2) NULL,
  valor_base DECIMAL(10,2) NULL,
  multiplicador_dinamico DECIMAL(4,2) NOT NULL DEFAULT 1.00,
  valor_dinamico_adicional DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  dinamica_celula_id VARCHAR(80) NULL,
  dinamica_motivo VARCHAR(255) NULL,
  dinamica_dados_json LONGTEXT NULL,
  saldo_negativo_cobrado DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  categoria_veiculo ENUM('economica', 'plus', 'pro') NOT NULL DEFAULT 'economica',
  id_tarifa_regiao INT NULL,
  forma_pagamento ENUM('dinheiro', 'online') NOT NULL DEFAULT 'dinheiro',
  forma_pagamento_detalhe VARCHAR(30) NULL,
  codigo_embarque CHAR(4) NULL,
  avaliacao_motorista TINYINT NULL,
  avaliacao_comentario TEXT NULL,
  avaliado_em DATETIME NULL,
  avaliacao_passageiro TINYINT NULL,
  avaliacao_passageiro_comentario TEXT NULL,
  passageiro_avaliado_em DATETIME NULL,
  status ENUM('pendente', 'aceita', 'aguardando_embarque', 'em_andamento', 'finalizada', 'cancelada') NOT NULL DEFAULT 'pendente',
  oferta_lista_liberada TINYINT(1) NOT NULL DEFAULT 0,
  oferta_lista_em DATETIME NULL,
  aceita_em DATETIME NULL,
  distancia_motorista_aceite_km DECIMAL(10,3) NULL,
  tempo_motorista_aceite_min DECIMAL(10,2) NULL,
  chegou_embarque_em DATETIME NULL,
  iniciou_viagem_em DATETIME NULL,
  cancelada_em DATETIME NULL,
  cancelada_por ENUM('passageiro', 'motorista', 'admin', 'sistema') NULL,
  cancelamento_motivo VARCHAR(120) NULL,
  cancelamento_observacao TEXT NULL,
  cancelamento_taxa DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  cancelamento_valor_motorista DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  distancia_motorista_cancelamento_km DECIMAL(10,3) NULL,
  finalizada_em DATETIME NULL,
  criada_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizada_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_corridas_passageiro FOREIGN KEY (id_passageiro) REFERENCES usuarios(id),
  CONSTRAINT fk_corridas_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id),
  INDEX idx_corridas_status (status),
  INDEX idx_corridas_passageiro (id_passageiro),
  INDEX idx_corridas_motorista (id_motorista),
  INDEX idx_corridas_tarifa_regiao (id_tarifa_regiao)
);

CREATE TABLE IF NOT EXISTS corrida_paradas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_corrida INT NOT NULL,
  ordem TINYINT NOT NULL,
  lat DECIMAL(10,7) NOT NULL,
  lng DECIMAL(10,7) NOT NULL,
  endereco VARCHAR(255) NULL,
  confirmada_em DATETIME NULL,
  criada_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_corrida_paradas_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE CASCADE,
  UNIQUE KEY uk_corrida_parada_ordem (id_corrida, ordem),
  INDEX idx_corrida_paradas_corrida (id_corrida, ordem)
);

CREATE TABLE IF NOT EXISTS corrida_compartilhamentos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_corrida INT NOT NULL,
  token_hash CHAR(64) NOT NULL,
  criado_por_usuario INT NULL,
  criado_por_tipo ENUM('passageiro', 'motorista', 'admin', 'sistema') NOT NULL DEFAULT 'sistema',
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  expira_em DATETIME NULL,
  ultimo_acesso_em DATETIME NULL,
  acessos INT NOT NULL DEFAULT 0,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_corrida_compartilhamentos_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE CASCADE,
  CONSTRAINT fk_corrida_compartilhamentos_usuario FOREIGN KEY (criado_por_usuario) REFERENCES usuarios(id) ON DELETE SET NULL,
  UNIQUE KEY uk_corrida_compartilhamento_token (token_hash),
  INDEX idx_corrida_compartilhamentos_corrida (id_corrida, ativo)
);

CREATE TABLE IF NOT EXISTS corrida_ofertas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_corrida INT NOT NULL,
  id_motorista INT NOT NULL,
  rodada TINYINT NOT NULL DEFAULT 1,
  ordem TINYINT NOT NULL DEFAULT 1,
  status ENUM('pendente', 'aceita', 'recusada', 'expirada', 'cancelada') NOT NULL DEFAULT 'pendente',
  distancia_ate_origem_km DECIMAL(10,3) NULL,
  enviado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  expira_em DATETIME NOT NULL,
  respondido_em DATETIME NULL,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_corrida_ofertas_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE CASCADE,
  CONSTRAINT fk_corrida_ofertas_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id) ON DELETE CASCADE,
  UNIQUE KEY uk_corrida_motorista_rodada (id_corrida, id_motorista, rodada),
  INDEX idx_corrida_ofertas_motorista (id_motorista, status, expira_em),
  INDEX idx_corrida_ofertas_corrida (id_corrida, status, rodada)
);

CREATE TABLE IF NOT EXISTS motorista_metricas_corridas (
  id_motorista INT PRIMARY KEY,
  periodo_dias INT NOT NULL DEFAULT 30,
  periodo_inicio DATE NULL,
  periodo_fim DATE NULL,
  chamadas_recebidas INT NOT NULL DEFAULT 0,
  chamadas_contabilizadas INT NOT NULL DEFAULT 0,
  chamadas_aceitas INT NOT NULL DEFAULT 0,
  chamadas_recusadas INT NOT NULL DEFAULT 0,
  chamadas_expiradas INT NOT NULL DEFAULT 0,
  chamadas_canceladas_sistema INT NOT NULL DEFAULT 0,
  chamadas_pendentes INT NOT NULL DEFAULT 0,
  corridas_finalizadas INT NOT NULL DEFAULT 0,
  corridas_canceladas_motorista INT NOT NULL DEFAULT 0,
  corridas_encerradas_motorista INT NOT NULL DEFAULT 0,
  taxa_aceitacao DECIMAL(5,2) NOT NULL DEFAULT 0.00,
  taxa_cancelamento DECIMAL(5,2) NOT NULL DEFAULT 0.00,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_motorista_metricas_corridas_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_motorista_metricas_aceitacao (taxa_aceitacao),
  INDEX idx_motorista_metricas_cancelamento (taxa_cancelamento)
);

CREATE TABLE IF NOT EXISTS motorista_filtros_corrida (
  id_motorista INT PRIMARY KEY,
  aceita_dinheiro TINYINT(1) NOT NULL DEFAULT 1,
  aceita_economica TINYINT(1) NOT NULL DEFAULT 1,
  aceita_plus TINYINT(1) NOT NULL DEFAULT 1,
  aceita_pro TINYINT(1) NOT NULL DEFAULT 1,
  destino_ativo TINYINT(1) NOT NULL DEFAULT 0,
  destino_lat DECIMAL(10,7) NULL,
  destino_lng DECIMAL(10,7) NULL,
  destino_endereco VARCHAR(255) NULL,
  destino_ativado_em DATETIME NULL,
  destino_usos_data DATE NULL,
  destino_usos INT NOT NULL DEFAULT 0,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_motorista_filtros_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_motorista_filtros_destino (destino_ativo, destino_usos_data)
);

CREATE TABLE IF NOT EXISTS motorista_destinos_corrida (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_motorista INT NOT NULL,
  tipo ENUM('favorito', 'recente') NOT NULL,
  titulo VARCHAR(80) NULL,
  endereco VARCHAR(255) NOT NULL,
  lat DECIMAL(10,7) NOT NULL,
  lng DECIMAL(10,7) NOT NULL,
  usado_em DATETIME NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_motorista_destinos_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_motorista_destinos_motorista (id_motorista, tipo, atualizado_em)
);

CREATE TABLE IF NOT EXISTS corrida_pontos_rota (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_corrida INT NOT NULL,
  id_motorista INT NOT NULL,
  lat DECIMAL(10,7) NOT NULL,
  lng DECIMAL(10,7) NOT NULL,
  rumo DECIMAL(8,2) NULL,
  velocidade DECIMAL(8,2) NULL,
  precisao DECIMAL(8,2) NULL,
  registrado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_corrida_pontos_rota_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE CASCADE,
  CONSTRAINT fk_corrida_pontos_rota_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_corrida_pontos_rota_corrida_data (id_corrida, registrado_em),
  INDEX idx_corrida_pontos_rota_motorista_data (id_motorista, registrado_em)
);

CREATE TABLE IF NOT EXISTS corrida_mensagens (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_corrida INT NOT NULL,
  remetente_tipo ENUM('motorista', 'passageiro', 'sistema') NOT NULL,
  id_remetente INT NOT NULL,
  nome_remetente VARCHAR(120) NULL,
  mensagem TEXT NOT NULL,
  lida_motorista TINYINT(1) NOT NULL DEFAULT 0,
  lida_passageiro TINYINT(1) NOT NULL DEFAULT 0,
  criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_corrida_mensagens_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE CASCADE,
  CONSTRAINT fk_corrida_mensagens_usuario FOREIGN KEY (id_remetente) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_corrida_mensagens_corrida (id_corrida, criado_em),
  INDEX idx_corrida_mensagens_motorista (id_corrida, lida_motorista),
  INDEX idx_corrida_mensagens_passageiro (id_corrida, lida_passageiro)
);

CREATE TABLE IF NOT EXISTS corrida_eventos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_corrida INT NOT NULL,
  id_usuario INT NULL,
  tipo_usuario ENUM('passageiro', 'motorista', 'admin', 'sistema') NULL,
  evento VARCHAR(80) NOT NULL,
  status_anterior VARCHAR(40) NULL,
  status_novo VARCHAR(40) NULL,
  motivo VARCHAR(120) NULL,
  observacao TEXT NULL,
  dados_json JSON NULL,
  criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_corrida_eventos_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE CASCADE,
  CONSTRAINT fk_corrida_eventos_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios(id) ON DELETE SET NULL,
  INDEX idx_corrida_eventos_corrida_data (id_corrida, criado_em),
  INDEX idx_corrida_eventos_usuario_data (id_usuario, criado_em),
  INDEX idx_corrida_eventos_evento (evento)
);

CREATE TABLE IF NOT EXISTS passageiro_enderecos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_passageiro INT NOT NULL,
  rotulo VARCHAR(60) NOT NULL,
  endereco VARCHAR(255) NOT NULL,
  latitude DECIMAL(10,7) NULL,
  longitude DECIMAL(10,7) NULL,
  ordem TINYINT NOT NULL DEFAULT 0,
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_pass_enderecos_usuario FOREIGN KEY (id_passageiro) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_pass_enderecos_usuario (id_passageiro, ativo, ordem)
);

CREATE TABLE IF NOT EXISTS passageiro_enderecos_recentes (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_passageiro INT NOT NULL,
  endereco VARCHAR(255) NOT NULL,
  latitude DECIMAL(10,7) NULL,
  longitude DECIMAL(10,7) NULL,
  tipo ENUM('origem', 'destino') NOT NULL DEFAULT 'destino',
  usado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_pass_enderecos_recentes_usuario FOREIGN KEY (id_passageiro) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_pass_enderecos_recentes_usuario (id_passageiro, usado_em)
);

CREATE TABLE IF NOT EXISTS passageiro_carteira_movimentos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_passageiro INT NOT NULL,
  id_corrida INT NULL,
  tipo ENUM('credito', 'debito', 'recarga_pix', 'estorno', 'ajuste') NOT NULL DEFAULT 'credito',
  origem ENUM('pix', 'cartao', 'corrida', 'admin', 'sistema') NOT NULL DEFAULT 'sistema',
  valor DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  descricao VARCHAR(180) NOT NULL,
  status ENUM('confirmado', 'pendente', 'cancelado') NOT NULL DEFAULT 'confirmado',
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_pass_carteira_usuario FOREIGN KEY (id_passageiro) REFERENCES usuarios(id),
  CONSTRAINT fk_pass_carteira_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE SET NULL,
  INDEX idx_pass_carteira_usuario (id_passageiro, criado_em),
  INDEX idx_pass_carteira_status (status)
);

CREATE TABLE IF NOT EXISTS passageiro_pix_recargas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_passageiro INT NOT NULL,
  valor DECIMAL(10,2) NOT NULL,
  status ENUM('pendente', 'pago', 'cancelado', 'expirado') NOT NULL DEFAULT 'pendente',
  txid VARCHAR(80) NULL,
  pix_copia_cola TEXT NULL,
  observacao VARCHAR(180) NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_pass_pix_usuario FOREIGN KEY (id_passageiro) REFERENCES usuarios(id),
  INDEX idx_pass_pix_usuario (id_passageiro, criado_em),
  INDEX idx_pass_pix_status (status)
);

CREATE TABLE IF NOT EXISTS passageiro_cartoes (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_passageiro INT NOT NULL,
  apelido VARCHAR(80) NULL,
  bandeira VARCHAR(40) NULL,
  ultimos4 CHAR(4) NOT NULL,
  validade_mes TINYINT NULL,
  validade_ano SMALLINT NULL,
  token_gateway VARCHAR(160) NULL,
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_pass_cartoes_usuario FOREIGN KEY (id_passageiro) REFERENCES usuarios(id),
  INDEX idx_pass_cartoes_usuario (id_passageiro, ativo)
);

CREATE TABLE IF NOT EXISTS motorista_elogios (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_motorista INT NOT NULL,
  id_passageiro INT NULL,
  id_corrida INT NULL,
  selo ENUM('bom_condutor', 'simpatico', 'veiculo_limpo', 'boa_rota', 'boa_conversa') NOT NULL,
  criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_motorista_elogios_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id) ON DELETE CASCADE,
  CONSTRAINT fk_motorista_elogios_passageiro FOREIGN KEY (id_passageiro) REFERENCES usuarios(id) ON DELETE SET NULL,
  CONSTRAINT fk_motorista_elogios_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE SET NULL,
  INDEX idx_motorista_elogios_motorista (id_motorista, selo),
  INDEX idx_motorista_elogios_corrida (id_corrida)
);

CREATE TABLE IF NOT EXISTS ganhos_diarios (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_motorista INT NOT NULL,
  data_ref DATE NOT NULL,
  total_corridas INT NOT NULL DEFAULT 0,
  total_valor DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_ganhos_diarios_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id),
  UNIQUE KEY uk_ganhos_diarios_motorista_data (id_motorista, data_ref),
  INDEX idx_ganhos_diarios_data (data_ref)
);

CREATE TABLE IF NOT EXISTS motorista_sessoes_online (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_motorista INT NOT NULL,
  inicio_em DATETIME NOT NULL,
  fim_em DATETIME NULL,
  duracao_segundos INT NOT NULL DEFAULT 0,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_sessoes_online_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id),
  INDEX idx_sessoes_online_motorista_inicio (id_motorista, inicio_em),
  INDEX idx_sessoes_online_fim (fim_em)
);

CREATE TABLE IF NOT EXISTS configuracoes (
  chave VARCHAR(80) PRIMARY KEY,
  valor DECIMAL(10,2) NOT NULL,
  descricao VARCHAR(255) NULL,
  atualizado_por VARCHAR(80) NULL,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS configuracoes_historico (
  id INT AUTO_INCREMENT PRIMARY KEY,
  chave VARCHAR(80) NOT NULL,
  valor_anterior DECIMAL(10,2) NULL,
  valor_novo DECIMAL(10,2) NOT NULL,
  alterado_por VARCHAR(80) NOT NULL,
  alterado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_config_historico_chave (chave),
  INDEX idx_config_historico_alterado_em (alterado_em)
);

CREATE TABLE IF NOT EXISTS tarifa_regioes (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nome VARCHAR(120) NOT NULL,
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  ordem INT NOT NULL DEFAULT 100,
  geocerca_json LONGTEXT NOT NULL,
  centro_lat DECIMAL(10,7) NULL,
  centro_lng DECIMAL(10,7) NULL,
  preco_base DECIMAL(10,2) NOT NULL DEFAULT 5.00,
  preco_por_km DECIMAL(10,2) NOT NULL DEFAULT 2.50,
  preco_por_minuto DECIMAL(10,2) NOT NULL DEFAULT 0.35,
  taxa_servico DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  valor_minimo DECIMAL(10,2) NOT NULL DEFAULT 5.00,
  plus_preco_base DECIMAL(10,2) NOT NULL DEFAULT 5.00,
  plus_preco_por_km DECIMAL(10,2) NOT NULL DEFAULT 2.50,
  plus_preco_por_minuto DECIMAL(10,2) NOT NULL DEFAULT 0.35,
  plus_taxa_servico DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  plus_valor_minimo DECIMAL(10,2) NOT NULL DEFAULT 5.00,
  pro_preco_base DECIMAL(10,2) NOT NULL DEFAULT 5.00,
  pro_preco_por_km DECIMAL(10,2) NOT NULL DEFAULT 2.50,
  pro_preco_por_minuto DECIMAL(10,2) NOT NULL DEFAULT 0.35,
  pro_taxa_servico DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  pro_valor_minimo DECIMAL(10,2) NOT NULL DEFAULT 5.00,
  economica_ativo TINYINT(1) NOT NULL DEFAULT 1,
  plus_ativo TINYINT(1) NOT NULL DEFAULT 1,
  pro_ativo TINYINT(1) NOT NULL DEFAULT 1,
  dinamica_ativa TINYINT(1) NOT NULL DEFAULT 0,
  dinamica_multiplicador_max DECIMAL(4,2) NOT NULL DEFAULT 1.80,
  dinamica_sensibilidade VARCHAR(12) NOT NULL DEFAULT 'media',
  dinamica_celula_km DECIMAL(5,2) NOT NULL DEFAULT 2.00,
  dinamica_janela_minutos INT NOT NULL DEFAULT 12,
  criado_por VARCHAR(80) NULL,
  atualizado_por VARCHAR(80) NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  INDEX idx_tarifa_regioes_ativo_ordem (ativo, ordem),
  INDEX idx_tarifa_regioes_centro (centro_lat, centro_lng)
);

CREATE TABLE IF NOT EXISTS usuario_feedbacks (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_usuario INT NOT NULL,
  id_corrida INT NULL,
  tipo ENUM('elogio', 'reclamacao', 'observacao') NOT NULL DEFAULT 'observacao',
  origem ENUM('admin', 'passageiro', 'motorista', 'sistema') NOT NULL DEFAULT 'admin',
  nota TINYINT NULL,
  comentario TEXT NOT NULL,
  registrado_por VARCHAR(80) NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_feedbacks_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios(id),
  CONSTRAINT fk_feedbacks_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE SET NULL,
  INDEX idx_feedbacks_usuario (id_usuario),
  INDEX idx_feedbacks_tipo (tipo),
  INDEX idx_feedbacks_criado_em (criado_em)
);

CREATE TABLE IF NOT EXISTS indicacao_retiradas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_usuario INT NOT NULL,
  valor DECIMAL(10,2) NOT NULL,
  saldo_no_pedido DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  status ENUM('pendente', 'em_processamento', 'paga', 'reprovada', 'cancelada') NOT NULL DEFAULT 'pendente',
  pix_tipo ENUM('cpf', 'cnpj', 'email', 'celular', 'aleatoria') NULL,
  pix_chave VARCHAR(120) NULL,
  banco_nome VARCHAR(80) NULL,
  banco_agencia VARCHAR(20) NULL,
  banco_conta VARCHAR(30) NULL,
  banco_tipo_conta ENUM('corrente', 'poupanca', 'pagamento') NULL,
  banco_titular_nome VARCHAR(120) NULL,
  banco_titular_documento VARCHAR(20) NULL,
  prazo_limite DATE NULL,
  observacao VARCHAR(255) NULL,
  solicitado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  processado_por VARCHAR(80) NULL,
  processado_em DATETIME NULL,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_indicacao_retiradas_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios(id),
  INDEX idx_indicacao_retiradas_usuario (id_usuario),
  INDEX idx_indicacao_retiradas_status (status),
  INDEX idx_indicacao_retiradas_solicitado (solicitado_em)
);

CREATE TABLE IF NOT EXISTS carteira_retiradas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_motorista INT NOT NULL,
  valor DECIMAL(10,2) NOT NULL,
  saldo_no_pedido DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  status ENUM('pendente', 'em_processamento', 'paga', 'reprovada', 'cancelada') NOT NULL DEFAULT 'pendente',
  pix_tipo ENUM('cpf', 'cnpj', 'email', 'celular', 'aleatoria') NULL,
  pix_chave VARCHAR(120) NULL,
  banco_nome VARCHAR(80) NULL,
  banco_agencia VARCHAR(20) NULL,
  banco_conta VARCHAR(30) NULL,
  banco_tipo_conta ENUM('corrente', 'poupanca', 'pagamento') NULL,
  banco_titular_nome VARCHAR(120) NULL,
  banco_titular_documento VARCHAR(20) NULL,
  prazo_limite DATE NULL,
  observacao VARCHAR(255) NULL,
  solicitado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  processado_por VARCHAR(80) NULL,
  processado_em DATETIME NULL,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_carteira_retiradas_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id),
  INDEX idx_carteira_retiradas_motorista (id_motorista),
  INDEX idx_carteira_retiradas_status (status),
  INDEX idx_carteira_retiradas_solicitado (solicitado_em)
);

CREATE TABLE IF NOT EXISTS financeiro_auditoria (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  codigo CHAR(36) NOT NULL,
  tipo ENUM(
    'corrida_finalizada',
    'retirada_carteira_solicitada',
    'retirada_carteira_status',
    'retirada_indicacao_solicitada',
    'retirada_indicacao_status',
    'recarga_pix_criada',
    'recarga_pix_status',
    'passageiro_carteira_movimento',
    'ajuste',
    'sistema'
  ) NOT NULL,
  origem_tabela VARCHAR(80) NOT NULL,
  origem_id INT NULL,
  id_usuario INT NULL,
  id_motorista INT NULL,
  id_passageiro INT NULL,
  id_corrida INT NULL,
  direcao ENUM('credito', 'debito', 'neutro') NOT NULL DEFAULT 'neutro',
  valor DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  saldo_anterior DECIMAL(10,2) NULL,
  saldo_posterior DECIMAL(10,2) NULL,
  status_anterior VARCHAR(40) NULL,
  status_novo VARCHAR(40) NULL,
  descricao VARCHAR(255) NULL,
  payload_json LONGTEXT NULL,
  criado_por VARCHAR(80) NOT NULL DEFAULT 'sistema',
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uk_financeiro_auditoria_codigo (codigo),
  INDEX idx_fin_aud_tipo_data (tipo, criado_em),
  INDEX idx_fin_aud_usuario (id_usuario, criado_em),
  INDEX idx_fin_aud_motorista (id_motorista, criado_em),
  INDEX idx_fin_aud_passageiro (id_passageiro, criado_em),
  INDEX idx_fin_aud_corrida (id_corrida),
  INDEX idx_fin_aud_origem (origem_tabela, origem_id)
);

CREATE TABLE IF NOT EXISTS avisos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  destino ENUM('motoristas', 'passageiros', 'todos') NOT NULL DEFAULT 'todos',
  titulo VARCHAR(140) NOT NULL,
  mensagem TEXT NOT NULL,
  enviado_por VARCHAR(80) NOT NULL,
  criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_avisos_destino (destino),
  INDEX idx_avisos_criado_em (criado_em)
);

CREATE TABLE IF NOT EXISTS avisos_leituras (
  id_aviso INT NOT NULL,
  id_usuario INT NOT NULL,
  lido_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id_aviso, id_usuario),
  CONSTRAINT fk_avisos_leituras_aviso FOREIGN KEY (id_aviso) REFERENCES avisos(id) ON DELETE CASCADE,
  CONSTRAINT fk_avisos_leituras_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_avisos_leituras_usuario (id_usuario, lido_em)
);

CREATE TABLE IF NOT EXISTS push_tokens (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_usuario INT NOT NULL,
  tipo_usuario ENUM('motorista', 'passageiro') NOT NULL,
  token VARCHAR(255) NOT NULL,
  plataforma ENUM('android', 'ios', 'web') NOT NULL DEFAULT 'android',
  app VARCHAR(40) NULL,
  ativo TINYINT(1) NOT NULL DEFAULT 1,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY uk_push_tokens_token (token),
  CONSTRAINT fk_push_tokens_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios(id) ON DELETE CASCADE,
  INDEX idx_push_tokens_usuario (id_usuario, tipo_usuario, ativo),
  INDEX idx_push_tokens_destino (tipo_usuario, ativo)
);

CREATE TABLE IF NOT EXISTS suporte_chamados (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_usuario INT NOT NULL,
  tipo_usuario ENUM('motorista', 'passageiro') NOT NULL DEFAULT 'motorista',
  id_corrida INT NULL,
  id_veiculo INT NULL,
  categoria ENUM(
    'corrida',
    'conta',
    'documentos',
    'veiculo',
    'ganhos_pagamentos',
    'item_encontrado',
    'seguranca',
    'problema_app',
    'outros'
  ) NOT NULL DEFAULT 'outros',
  subcategoria VARCHAR(80) NULL,
  prioridade ENUM('baixa', 'normal', 'alta', 'urgente') NOT NULL DEFAULT 'normal',
  status ENUM('aberto', 'em_atendimento', 'aguardando_motorista', 'resolvido', 'fechado') NOT NULL DEFAULT 'aberto',
  titulo VARCHAR(140) NOT NULL,
  descricao TEXT NOT NULL,
  admin_responsavel VARCHAR(80) NULL,
  criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  ultima_mensagem_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_suporte_chamados_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios(id),
  CONSTRAINT fk_suporte_chamados_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE SET NULL,
  CONSTRAINT fk_suporte_chamados_veiculo FOREIGN KEY (id_veiculo) REFERENCES veiculos(id) ON DELETE SET NULL,
  INDEX idx_suporte_chamados_usuario (id_usuario, tipo_usuario),
  INDEX idx_suporte_chamados_status (status),
  INDEX idx_suporte_chamados_categoria (categoria),
  INDEX idx_suporte_chamados_ultima (ultima_mensagem_em)
);

CREATE TABLE IF NOT EXISTS suporte_mensagens (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_chamado INT NOT NULL,
  remetente_tipo ENUM('motorista', 'passageiro', 'admin', 'sistema') NOT NULL,
  id_remetente INT NULL,
  nome_remetente VARCHAR(120) NULL,
  mensagem TEXT NOT NULL,
  anexo_url VARCHAR(255) NULL,
  lido_motorista TINYINT(1) NOT NULL DEFAULT 0,
  lido_admin TINYINT(1) NOT NULL DEFAULT 0,
  criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_suporte_mensagens_chamado FOREIGN KEY (id_chamado) REFERENCES suporte_chamados(id) ON DELETE CASCADE,
  CONSTRAINT fk_suporte_mensagens_remetente FOREIGN KEY (id_remetente) REFERENCES usuarios(id) ON DELETE SET NULL,
  INDEX idx_suporte_mensagens_chamado (id_chamado, criado_em),
  INDEX idx_suporte_mensagens_lido_admin (lido_admin),
  INDEX idx_suporte_mensagens_lido_motorista (lido_motorista)
);

INSERT INTO configuracoes (chave, valor, descricao, atualizado_por) VALUES
  ('preco_base', 5.00, 'Valor inicial fixo da corrida', 'sistema'),
  ('preco_por_km', 2.50, 'Valor cobrado por quilometro', 'sistema'),
  ('preco_por_minuto', 0.35, 'Valor cobrado por minuto estimado', 'sistema'),
  ('taxa_servico', 0.00, 'Taxa fixa adicional da plataforma', 'sistema'),
  ('valor_minimo', 5.00, 'Menor valor permitido para a corrida', 'sistema'),
  ('plus_preco_base', 5.00, 'Plus: valor inicial fixo da corrida', 'sistema'),
  ('plus_preco_por_km', 2.50, 'Plus: valor cobrado por quilometro', 'sistema'),
  ('plus_preco_por_minuto', 0.35, 'Plus: valor cobrado por minuto estimado', 'sistema'),
  ('plus_taxa_servico', 0.00, 'Plus: taxa fixa adicional da plataforma', 'sistema'),
  ('plus_valor_minimo', 5.00, 'Plus: menor valor permitido para a corrida', 'sistema'),
  ('pro_preco_base', 5.00, 'Pro: valor inicial fixo da corrida', 'sistema'),
  ('pro_preco_por_km', 2.50, 'Pro: valor cobrado por quilometro', 'sistema'),
  ('pro_preco_por_minuto', 0.35, 'Pro: valor cobrado por minuto estimado', 'sistema'),
  ('pro_taxa_servico', 0.00, 'Pro: taxa fixa adicional da plataforma', 'sistema'),
  ('pro_valor_minimo', 5.00, 'Pro: menor valor permitido para a corrida', 'sistema')
ON DUPLICATE KEY UPDATE
  valor = VALUES(valor),
  descricao = VALUES(descricao),
  atualizado_por = COALESCE(configuracoes.atualizado_por, VALUES(atualizado_por));

CREATE TABLE IF NOT EXISTS mercado_pago_contas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_usuario INT NOT NULL,
  tipo_usuario ENUM('motorista', 'passageiro', 'plataforma') NOT NULL,
  mp_user_id VARCHAR(80) NULL,
  mp_nickname VARCHAR(120) NULL,
  mp_email VARCHAR(160) NULL,
  access_token TEXT NULL,
  refresh_token TEXT NULL,
  token_expires_at DATETIME NULL,
  public_key VARCHAR(160) NULL,
  status ENUM('nao_conectado', 'pendente', 'conectado', 'desconectado', 'erro') NOT NULL DEFAULT 'pendente',
  modo ENUM('sandbox', 'producao') NOT NULL DEFAULT 'sandbox',
  observacao VARCHAR(255) NULL,
  conectado_em DATETIME NULL,
  desconectado_em DATETIME NULL,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uk_mp_conta_usuario_tipo (id_usuario, tipo_usuario),
  INDEX idx_mp_contas_status (status),
  CONSTRAINT fk_mp_contas_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS pagamentos_corridas (
  id INT AUTO_INCREMENT PRIMARY KEY,
  id_corrida INT NULL,
  id_passageiro INT NULL,
  id_motorista INT NULL,
  provedor ENUM('mercado_pago') NOT NULL DEFAULT 'mercado_pago',
  ambiente ENUM('sandbox', 'producao') NOT NULL DEFAULT 'sandbox',
  external_reference VARCHAR(160) NOT NULL,
  mp_payment_id VARCHAR(100) NULL,
  mp_preference_id VARCHAR(100) NULL,
  mp_customer_id VARCHAR(100) NULL,
  mp_card_id VARCHAR(100) NULL,
  metodo ENUM('pix_online', 'cartao_credito', 'dinheiro_pix') NOT NULL,
  status ENUM('criado', 'pendente', 'autorizado', 'aprovado', 'recusado', 'cancelado', 'estornado', 'erro') NOT NULL DEFAULT 'criado',
  valor_total DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  valor_motorista DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  valor_plataforma DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  taxa_gateway DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  application_fee DECIMAL(10,2) NOT NULL DEFAULT 0.00,
  raw_request JSON NULL,
  raw_response JSON NULL,
  erro_mensagem VARCHAR(255) NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY uk_pagamentos_external_reference (external_reference),
  INDEX idx_pagamentos_corrida (id_corrida),
  INDEX idx_pagamentos_status (status),
  INDEX idx_pagamentos_motorista (id_motorista),
  CONSTRAINT fk_pagamentos_corrida FOREIGN KEY (id_corrida) REFERENCES corridas(id) ON DELETE SET NULL,
  CONSTRAINT fk_pagamentos_passageiro FOREIGN KEY (id_passageiro) REFERENCES usuarios(id) ON DELETE SET NULL,
  CONSTRAINT fk_pagamentos_motorista FOREIGN KEY (id_motorista) REFERENCES usuarios(id) ON DELETE SET NULL
);

CREATE TABLE IF NOT EXISTS pagamento_eventos_webhook (
  id INT AUTO_INCREMENT PRIMARY KEY,
  provedor ENUM('mercado_pago') NOT NULL DEFAULT 'mercado_pago',
  event_id VARCHAR(120) NULL,
  event_type VARCHAR(80) NULL,
  resource_id VARCHAR(120) NULL,
  acao VARCHAR(80) NULL,
  payload JSON NULL,
  processado TINYINT(1) NOT NULL DEFAULT 0,
  erro VARCHAR(255) NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uk_mp_webhook_event (provedor, event_id),
  INDEX idx_mp_webhook_resource (resource_id),
  INDEX idx_mp_webhook_processado (processado)
);

CREATE TABLE IF NOT EXISTS mercado_pago_configuracoes (
  chave VARCHAR(80) PRIMARY KEY,
  valor TEXT NULL,
  descricao VARCHAR(255) NULL,
  sensivel TINYINT(1) NOT NULL DEFAULT 0,
  atualizado_por VARCHAR(80) NULL,
  atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS mercado_pago_oauth_states (
  id INT AUTO_INCREMENT PRIMARY KEY,
  state VARCHAR(96) NOT NULL,
  id_usuario INT NOT NULL,
  tipo_usuario ENUM('motorista', 'passageiro', 'plataforma') NOT NULL DEFAULT 'motorista',
  redirect_uri VARCHAR(255) NOT NULL,
  code_verifier VARCHAR(160) NULL,
  usado TINYINT(1) NOT NULL DEFAULT 0,
  erro VARCHAR(255) NULL,
  criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  expira_em DATETIME NOT NULL,
  UNIQUE KEY uk_mp_oauth_state (state),
  INDEX idx_mp_oauth_usuario (id_usuario, tipo_usuario),
  CONSTRAINT fk_mp_oauth_usuario FOREIGN KEY (id_usuario) REFERENCES usuarios(id) ON DELETE CASCADE
);

ALTER TABLE passageiro_cartoes
  ADD COLUMN IF NOT EXISTS mp_customer_id VARCHAR(100) NULL AFTER token_gateway,
  ADD COLUMN IF NOT EXISTS mp_card_id VARCHAR(100) NULL AFTER mp_customer_id,
  ADD COLUMN IF NOT EXISTS mp_payment_method_id VARCHAR(60) NULL AFTER mp_card_id,
  ADD COLUMN IF NOT EXISTS token_status ENUM('referencia', 'tokenizado', 'removido', 'erro') NOT NULL DEFAULT 'referencia' AFTER mp_payment_method_id,
  ADD COLUMN IF NOT EXISTS observacao_gateway VARCHAR(255) NULL AFTER token_status;

ALTER TABLE passageiro_pix_recargas
  ADD COLUMN IF NOT EXISTS id_pagamento_gateway INT NULL AFTER id_passageiro,
  ADD COLUMN IF NOT EXISTS mp_payment_id VARCHAR(100) NULL AFTER txid,
  ADD COLUMN IF NOT EXISTS external_reference VARCHAR(160) NULL AFTER mp_payment_id;

ALTER TABLE corridas
  ADD COLUMN IF NOT EXISTS id_pagamento_gateway INT NULL AFTER forma_pagamento_detalhe,
  ADD COLUMN IF NOT EXISTS status_pagamento ENUM('nao_aplicavel', 'pendente', 'autorizado', 'aprovado', 'recusado', 'cancelado', 'estornado', 'erro') NOT NULL DEFAULT 'nao_aplicavel' AFTER id_pagamento_gateway,
  ADD COLUMN IF NOT EXISTS valor_motorista_liquido DECIMAL(10,2) NULL AFTER valor,
  ADD COLUMN IF NOT EXISTS valor_plataforma_bruto DECIMAL(10,2) NULL AFTER valor_motorista_liquido,
  ADD COLUMN IF NOT EXISTS taxa_gateway DECIMAL(10,2) NULL AFTER valor_plataforma_bruto,
  ADD COLUMN IF NOT EXISTS mp_payment_id VARCHAR(100) NULL AFTER status_pagamento,
  ADD COLUMN IF NOT EXISTS mp_external_reference VARCHAR(160) NULL AFTER mp_payment_id;

INSERT INTO configuracoes (chave, valor, descricao, atualizado_por)
VALUES
  ('mp_ambiente_sandbox', 1.00, 'Mercado Pago em modo sandbox: 1 sim, 0 producao', 'sistema'),
  ('mp_marketplace_ativo', 0.00, 'Marketplace Mercado Pago ativo: 1 sim, 0 nao', 'sistema'),
  ('mp_taxa_gateway_percentual', 0.00, 'Percentual estimado cobrado pelo gateway, usado somente para conferencia', 'sistema')
ON DUPLICATE KEY UPDATE
  descricao = VALUES(descricao),
  atualizado_por = COALESCE(configuracoes.atualizado_por, VALUES(atualizado_por));

INSERT INTO mercado_pago_configuracoes (chave, valor, descricao, sensivel, atualizado_por)
VALUES
  ('mp_client_id', NULL, 'Client ID do aplicativo Mercado Pago', 0, 'sistema'),
  ('mp_client_secret', NULL, 'Client Secret do aplicativo Mercado Pago', 1, 'sistema'),
  ('mp_public_key', NULL, 'Public Key da plataforma para Checkout Transparente', 0, 'sistema'),
  ('mp_access_token_plataforma', NULL, 'Access Token da conta plataforma', 1, 'sistema'),
  ('mp_redirect_uri', 'http://localhost/bulo_backend/auth/mercado_pago_callback.php', 'URL de retorno OAuth cadastrada no Mercado Pago', 0, 'sistema'),
  ('mp_webhook_url', 'http://localhost/bulo_backend/pagamentos/mercado_pago_webhook.php', 'URL de webhook cadastrada no Mercado Pago', 0, 'sistema')
ON DUPLICATE KEY UPDATE
  descricao = VALUES(descricao),
  sensivel = VALUES(sensivel),
  atualizado_por = COALESCE(mercado_pago_configuracoes.atualizado_por, VALUES(atualizado_por));
