-- Delivery v16 SQL (Supabase)
-- Run in Supabase SQL editor
CREATE TABLE IF NOT EXISTS usuarios (
  id SERIAL PRIMARY KEY,
  tipo TEXT CHECK (tipo IN ('entregador','estabelecimento','central')) NOT NULL,
  nome TEXT,
  whatsapp TEXT UNIQUE,
  saldo NUMERIC DEFAULT 0,
  ativo BOOLEAN DEFAULT TRUE,
  ultima_lat NUMERIC(10,6),
  ultima_lng NUMERIC(10,6),
  ultima_atualizacao TIMESTAMP,
  created_at TIMESTAMP DEFAULT now()
);

CREATE TABLE IF NOT EXISTS entregas (
  id SERIAL PRIMARY KEY,
  estabelecimento_id INT REFERENCES usuarios(id),
  entregador_id INT REFERENCES usuarios(id),
  tipo_entrega TEXT DEFAULT 'comercial',
  descricao TEXT,
  retirada_endereco TEXT,
  retirada_lat NUMERIC(10,6),
  retirada_lng NUMERIC(10,6),
  entrega_endereco TEXT,
  entrega_lat NUMERIC(10,6),
  entrega_lng NUMERIC(10,6),
  valor NUMERIC(10,2) DEFAULT 0,
  forma_pagamento TEXT,
  status TEXT DEFAULT 'pendente',
  data_agendada TIMESTAMP,
  pago BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP DEFAULT now()
);

CREATE TABLE IF NOT EXISTS pagamentos (
  id SERIAL PRIMARY KEY,
  entrega_id INT REFERENCES entregas(id),
  cliente_id INT REFERENCES usuarios(id),
  metodo TEXT,
  gateway TEXT,
  gateway_payment_id TEXT,
  status TEXT DEFAULT 'pending',
  amount NUMERIC(10,2),
  created_at TIMESTAMP DEFAULT now(),
  paid_at TIMESTAMP NULL
);

CREATE TABLE IF NOT EXISTS rastreio_posicoes (
  id SERIAL PRIMARY KEY,
  entregador_id INT REFERENCES usuarios(id),
  latitude NUMERIC(10,6),
  longitude NUMERIC(10,6),
  atualizado_em TIMESTAMP DEFAULT now(),
  entrega_id INT NULL REFERENCES entregas(id)
);

CREATE TABLE IF NOT EXISTS configuracoes_sistema (
  id SERIAL PRIMARY KEY,
  modo_despacho TEXT DEFAULT 'automatico',
  raio_busca_km NUMERIC DEFAULT 5,
  valor_base_entrega NUMERIC DEFAULT 10.00,
  desconto_pix_percent NUMERIC DEFAULT 5.00,
  comissao_central_percent NUMERIC DEFAULT 10.00,
  cashback_entregador_percent NUMERIC DEFAULT 2.00,
  cashback_estabelecimento_percent NUMERIC DEFAULT 2.00,
  gateway_ativo TEXT DEFAULT 'mercadopago',
  forma_pagamento_central TEXT DEFAULT 'mensal',
  forma_pagamento_entregador TEXT DEFAULT 'semanal',
  saldo_minimo_estabelecimento NUMERIC DEFAULT 0,
  tempo_limite_resposta INT DEFAULT 60,
  tema_padrao TEXT DEFAULT 'claro',
  idioma TEXT DEFAULT 'pt-BR',
  created_at TIMESTAMP DEFAULT now()
);

-- RPC: accept delivery with advisory lock
CREATE OR REPLACE FUNCTION aceita_entrega(p_entrega_id INT, p_entregador_id INT)
RETURNS JSON LANGUAGE plpgsql AS $$
BEGIN
  PERFORM pg_advisory_xact_lock(p_entrega_id);
  IF EXISTS(SELECT 1 FROM entregas WHERE id = p_entrega_id AND (status = 'pendente' OR status='agendada') AND entregador_id IS NULL) THEN
    UPDATE entregas SET entregador_id = p_entregador_id, status='em_rota' WHERE id = p_entrega_id;
    RETURN json_build_object('ok', true, 'message', 'Entrega aceita');
  ELSE
    RETURN json_build_object('ok', false, 'message', 'Entrega indisponível');
  END IF;
END;
$$;

-- RPC: get_nearest_drivers (Haversine)
CREATE OR REPLACE FUNCTION get_nearest_drivers(p_lat double precision, p_lon double precision, p_raio_km double precision DEFAULT 5)
RETURNS TABLE(entregador_id int, nome text, distancia_metros double precision) AS $$
BEGIN
  RETURN QUERY
  SELECT u.id, u.nome,
    ( 6371000 * acos( least(1, cos(radians(p_lat)) * cos(radians(u.ultima_lat)) * cos(radians(u.ultima_lng) - radians(p_lon)) + sin(radians(p_lat)) * sin(radians(u.ultima_lat)) ) ) )::double precision as distancia_metros
  FROM usuarios u
  WHERE u.tipo = 'entregador' AND u.ativo = true AND u.ultima_lat IS NOT NULL AND u.ultima_lng IS NOT NULL
  HAVING ( 6371 * acos( least(1, cos(radians(p_lat)) * cos(radians(u.ultima_lat)) * cos(radians(u.ultima_lng) - radians(p_lon)) + sin(radians(p_lat)) * sin(radians(u.ultima_lat)) ) ) ) <= p_raio_km
  ORDER BY distancia_metros ASC;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
