#!/usr/bin/env python3
"""
Script para gerar 500 dados mockados de rotas para o ERP SAAS PraFrota
Baseado nas especificações da documentação técnica
"""

import json
import random
from datetime import datetime, timedelta
from typing import List, Dict, Any

# Dados reais extraídos do CSV
REAL_PLATES = [
    "TAS4J92", "MSO5821", "TAS2F98", "RJZ7H79", "TAO3J98",
    "TAN6I73", "SGD4H03", "NGF2A53", "TAS2F32", "RTT1B46",
    "EZQ2E60", "TDZ4J93", "SGL8D98", "TAS2F83", "RVC0J58",
    "EYP4H76", "FVV7660", "RUN2B51", "RUQ9D16", "TAS5A49",
    "RUN2B49", "SHX0J21", "FHT5D54", "SVG0I32", "RUN2B50",
    "FYU9G72", "TAS4J93", "SRZ9B83", "TAQ4G32", "RUP2B50",
    "SRG6H41", "SQX8J75", "TAS4J96", "RTT1B44", "RTM9F10",
    "FLE2F99", "RUN2B63", "RVC0J65", "RUN2B52", "TUE1A37",
    "RUP4H86", "RUP4H94", "RUN2B48", "SVF4I52", "STL5A43",
    "TAS2J46", "TAO3I97", "TAS5A46", "SUT1B94", "LUJ7E05",
    "SST4C72", "SRH6C66", "TAO6E76", "RUN2B55", "RVC8B13",
    "SVF2E84", "SRO2J16", "RVT2J97", "RUN2B58", "SHB4B37",
    "IWB9C17", "FJE7I82", "TAQ4G22", "SGJ9F81", "SVP9H73",
    "OVM5B05", "TAO3J94", "RUP2B56", "TAO4F04", "RUN2B64",
    "GGL2J42", "SRN7H36", "SFM8D30", "TAO6E80", "SVK8G96",
    "SIA7J06", "TAR3E11", "RVC0J64", "RJW6G71", "SSV6C52",
    "RUN2B54", "TAN6I66", "SPA0001", "SVH9G53", "RUN2B62",
    "RVC0J85", "TAR3D02", "RVC4G70", "RUP4H92", "RUN2B56",
    "SGL8F08", "TAO3J93", "LUC4H25", "TAN6H93", "TAQ4G30",
    "RUP4H87", "SHB4B36", "SGC2B17", "RVC0J70", "SVL1G82",
    "RVC0J63", "RVT2J98", "SPA0001", "RVT4F18", "TAR3C45",
    "TAO4E80", "TAN6I62", "SHB4B38", "RTO9B22", "RJE8B51",
    "TAO4F02", "SGJ9G23", "SRU2H94", "RTT1B48", "TAN6I69",
    "RUP2B49", "RUW9C02", "RUP4H91", "RVC0J74", "TAN6H99",
    "FZG8F72", "RUP4H88", "TAS2E35", "RUN2B60", "RTO9B84",
    "GHM7A76", "RTM9F11", "TAN6H97", "SQX9G04", "RVU9160",
    "SGL8E65", "RTT1B43", "TAO4F05", "TOG3H62", "TAS5A47",
    "TAQ6J50", "SRH4E56", "NSZ5318", "RUN2B53", "TAO3J97",
    "SGL8E73", "SHX0J22", "SFP6G82", "SRZ9C22", "RTT1B45",
    "TAN6163", "LTO7G84", "SGL8D26", "TAN6I59", "TAO4E89",
    "TAO4E90", "TAS2J51", "SGL8F81", "RTM9F14", "FKP9A34",
    "TAS2J45", "QUS3C30", "GDM8I81", "TAQ4G36", "RVC0J59",
    "TAS5A44", "RUN2B61", "RVC4G71", "TAS4J95", "TAQ4G37",
    "SPA0001", "RTB7E19", "TAS2E31", "RUP4H81", "SGD9A92",
    "RJF7I82", "EVU9280", "SPA0001", "SSC1E94", "TAR3E21",
    "TAN6I71", "TAS4J92", "TAN6I57", "TAO4F90", "SGJ2F13",
    "SGJ2D96", "SGJ2G40", "TAR3E14", "KRQ9A48", "RUP2B53",
    "SRN5C38", "SGJ2G98", "SRA7J03", "RIU1G19", "EUQ4159",
    "SRH5C60", "SSB6H85", "SRN6F73", "SRY4B65", "SGL8C62",
    "STU7F45", "SGJ9G45", "RVT4F19"
]

PRODUCT_TYPES = [
    "Medicamentos", "Eletrônicos", "Alimentos Perecíveis", "Alimentos Não Perecíveis",
    "Roupas e Acessórios", "Livros e Papelaria", "Casa e Decoração", 
    "Cosméticos", "Automotive", "Brinquedos"
]

MARKETPLACES = ["Mercado Livre", "Shopee", "Amazon"]

# Coordenadas das regiões
REGIONS = {
    "rioDeJaneiro": {
        "center": {"lat": -22.9068, "lng": -43.1729},
        "bounds": {"north": -22.7000, "south": -23.1000, "east": -43.0000, "west": -43.8000},
        "addresses": [
            "Rua das Flores, 123 - Copacabana, Rio de Janeiro - RJ",
            "Av. Atlântica, 456 - Ipanema, Rio de Janeiro - RJ", 
            "Rua Barata Ribeiro, 789 - Copacabana, Rio de Janeiro - RJ",
            "Av. Nossa Senhora de Copacabana, 321 - Copacabana, Rio de Janeiro - RJ",
            "Rua Visconde de Pirajá, 654 - Ipanema, Rio de Janeiro - RJ",
            "Av. Rio Branco, 987 - Centro, Rio de Janeiro - RJ",
            "Rua da Carioca, 147 - Centro, Rio de Janeiro - RJ",
            "Av. Presidente Vargas, 258 - Centro, Rio de Janeiro - RJ",
            "Rua Santa Clara, 369 - Copacabana, Rio de Janeiro - RJ",
            "Av. Princesa Isabel, 741 - Copacabana, Rio de Janeiro - RJ"
        ]
    },
    "saoPaulo": {
        "center": {"lat": -23.5505, "lng": -46.6333},
        "bounds": {"north": -23.3000, "south": -23.8000, "east": -46.3000, "west": -47.0000},
        "addresses": [
            "Av. Paulista, 1578 - Bela Vista, São Paulo - SP",
            "Rua Augusta, 1000 - Consolação, São Paulo - SP",
            "Av. Faria Lima, 2000 - Pinheiros, São Paulo - SP",
            "Rua Oscar Freire, 500 - Jardins, São Paulo - SP",
            "Av. Rebouças, 3000 - Pinheiros, São Paulo - SP",
            "Rua da Consolação, 1200 - Consolação, São Paulo - SP",
            "Av. Brigadeiro Faria Lima, 1500 - Jardim Paulistano, São Paulo - SP",
            "Rua Haddock Lobo, 800 - Cerqueira César, São Paulo - SP",
            "Av. Nove de Julho, 2500 - Jardim Paulista, São Paulo - SP",
            "Rua Estados Unidos, 600 - Jardim América, São Paulo - SP"
        ]
    },
    "minasGerais": {
        "center": {"lat": -19.9167, "lng": -43.9345},
        "bounds": {"north": -19.7000, "south": -20.2000, "east": -43.7000, "west": -44.2000},
        "addresses": [
            "Av. Afonso Pena, 1000 - Centro, Belo Horizonte - MG",
            "Rua da Bahia, 500 - Centro, Belo Horizonte - MG",
            "Av. do Contorno, 2000 - Santa Efigênia, Belo Horizonte - MG",
            "Rua Rio de Janeiro, 800 - Centro, Belo Horizonte - MG",
            "Av. Amazonas, 1500 - Centro, Belo Horizonte - MG",
            "Rua Curitiba, 300 - Centro, Belo Horizonte - MG",
            "Av. Brasil, 2500 - Santa Efigênia, Belo Horizonte - MG",
            "Rua Tupis, 600 - Centro, Belo Horizonte - MG",
            "Av. Francisco Sales, 1200 - Santa Efigênia, Belo Horizonte - MG",
            "Rua Espírito Santo, 400 - Centro, Belo Horizonte - MG"
        ]
    },
    "vitoria": {
        "center": {"lat": -20.2976, "lng": -40.2958},
        "bounds": {"north": -20.1000, "south": -20.5000, "east": -40.1000, "west": -40.5000},
        "addresses": [
            "Av. Princesa Isabel, 500 - Centro, Vitória - ES",
            "Rua Sete de Setembro, 200 - Centro, Vitória - ES",
            "Av. Jerônimo Monteiro, 800 - Centro, Vitória - ES",
            "Rua do Comércio, 300 - Centro, Vitória - ES",
            "Av. Marechal Mascarenhas de Moraes, 1000 - Bento Ferreira, Vitória - ES",
            "Rua General Osório, 150 - Centro, Vitória - ES",
            "Av. Nossa Senhora da Penha, 600 - Santa Lúcia, Vitória - ES",
            "Rua Chapot Presvot, 400 - Praia do Canto, Vitória - ES",
            "Av. Saturnino de Brito, 900 - Praia do Canto, Vitória - ES",
            "Rua Joaquim Lírio, 250 - Praia do Canto, Vitória - ES"
        ]
    }
}

# Nomes fictícios
FIRST_NAMES = [
    "João", "Maria", "José", "Ana", "Carlos", "Fernanda", "Pedro", "Juliana",
    "Roberto", "Mariana", "Ricardo", "Camila", "Marcos", "Patrícia", "André",
    "Luciana", "Fernando", "Carla", "Rafael", "Daniela", "Paulo", "Renata",
    "Gustavo", "Vanessa", "Bruno", "Cristina", "Diego", "Tatiana", "Felipe",
    "Amanda", "Rodrigo", "Priscila", "Thiago", "Natália", "Leonardo", "Bianca"
]

LAST_NAMES = [
    "Silva", "Santos", "Oliveira", "Souza", "Rodrigues", "Ferreira", "Alves",
    "Pereira", "Lima", "Gomes", "Costa", "Ribeiro", "Martins", "Carvalho",
    "Almeida", "Lopes", "Soares", "Fernandes", "Vieira", "Barbosa", "Rocha",
    "Dias", "Monteiro", "Cardoso", "Reis", "Araújo", "Moreira", "Freitas",
    "Mendes", "Ramos", "Castro", "Pinto", "Teixeira", "Correia", "Machado"
]

def generate_random_name():
    """Gera um nome aleatório"""
    return f"{random.choice(FIRST_NAMES)} {random.choice(LAST_NAMES)}"

def generate_phone(area_code):
    """Gera um telefone aleatório"""
    return f"+55 {area_code} {random.randint(90000, 99999)}-{random.randint(1000, 9999)}"

def generate_coordinates_in_region(region_name):
    """Gera coordenadas aleatórias dentro de uma região"""
    region = REGIONS[region_name]
    bounds = region["bounds"]
    
    lat = random.uniform(bounds["south"], bounds["north"])
    lng = random.uniform(bounds["west"], bounds["east"])
    
    return {"lat": round(lat, 6), "lng": round(lng, 6)}

def generate_route_data(route_id: int, route_type: str, region: str) -> Dict[str, Any]:
    """Gera dados de uma rota específica"""
    
    # Definir códigos de área por região
    area_codes = {
        "rioDeJaneiro": "21",
        "saoPaulo": "11", 
        "minasGerais": "31",
        "vitoria": "27"
    }
    
    area_code = area_codes[region]
    
    # Gerar coordenadas
    origin_coords = generate_coordinates_in_region(region)
    dest_coords = generate_coordinates_in_region(region)
    
    # Selecionar endereços
    addresses = REGIONS[region]["addresses"]
    origin_address = random.choice(addresses)
    dest_address = random.choice(addresses)
    
    # Para lastMile, usar endereços residenciais
    if route_type == "lastMile":
        marketplace = random.choice(MARKETPLACES)
        origin_address = f"Hub {marketplace} - {region.title()}"
        dest_address = random.choice(addresses)  # Endereço residencial
    
    # Definir modal baseado no tipo
    if route_type == "lineHaul":
        modal_choices = ["rodoviario", "aereo", "aquaviario"]
        modal_weights = [0.8, 0.15, 0.05]
    else:
        modal_choices = ["rodoviario"]
        modal_weights = [1.0]
    
    modal = random.choices(modal_choices, weights=modal_weights)[0]
    
    # Definir prioridade
    priority = random.choices(
        ["normal", "express", "urgent"], 
        weights=[0.7, 0.2, 0.1]
    )[0]
    
    # Definir status
    status = random.choices(
        ["pending", "inProgress", "completed", "delayed", "cancelled"],
        weights=[0.1, 0.4, 0.35, 0.1, 0.05]
    )[0]
    
    # Definir valores baseados no tipo
    if route_type == "lastMile":
        total_value = round(random.uniform(25.0, 150.0), 2)
        total_weight = round(random.uniform(0.5, 15.0), 1)
        estimated_cost = round(total_value * 0.4, 2)
    elif route_type == "lineHaul":
        total_value = round(random.uniform(1500.0, 5000.0), 2)
        total_weight = round(random.uniform(5000.0, 15000.0), 1)
        estimated_cost = round(total_value * 0.35, 2)
    else:  # firstMile
        total_value = round(random.uniform(300.0, 2000.0), 2)
        total_weight = round(random.uniform(500.0, 5000.0), 1)
        estimated_cost = round(total_value * 0.45, 2)
    
    # Datas
    base_date = datetime.now() - timedelta(days=random.randint(0, 30))
    scheduled_departure = base_date
    
    # Definir datas baseadas no status
    actual_departure = None
    estimated_arrival = scheduled_departure + timedelta(hours=random.randint(2, 12))
    actual_arrival = None
    current_location = None
    actual_cost = None
    
    if status in ["inProgress", "completed", "delayed"]:
        actual_departure = scheduled_departure + timedelta(minutes=random.randint(-30, 60))
        if status == "completed":
            actual_arrival = estimated_arrival + timedelta(minutes=random.randint(-60, 120))
            current_location = dest_coords
            actual_cost = round(estimated_cost * random.uniform(0.8, 1.3), 2)
        elif status == "inProgress":
            # Posição entre origem e destino
            progress = random.uniform(0.2, 0.8)
            current_location = {
                "lat": round(origin_coords["lat"] + (dest_coords["lat"] - origin_coords["lat"]) * progress, 6),
                "lng": round(origin_coords["lng"] + (dest_coords["lng"] - origin_coords["lng"]) * progress, 6)
            }
    
    # Produto tipo
    product_type = random.choice(PRODUCT_TYPES)
    
    # Placa do veículo
    vehicle_plate = random.choice(REAL_PLATES)
    
    return {
        "id": f"rt_{route_id:03d}",
        "routeNumber": f"RT-2024-{route_id:06d}",
        "type": route_type,
        "modal": modal,
        "priority": priority,
        "driverId": f"drv_{route_id:03d}",
        "vehicleId": f"veh_{route_id:03d}",
        "companyId": "comp_001",
        "customerId": f"cust_{route_id:03d}",
        "origin": {
            "address": origin_address,
            "coordinates": origin_coords,
            "contact": generate_random_name(),
            "phone": generate_phone(area_code)
        },
        "destination": {
            "address": dest_address,
            "coordinates": dest_coords,
            "contact": generate_random_name(),
            "phone": generate_phone(area_code)
        },
        "scheduledDeparture": scheduled_departure.isoformat() + "Z",
        "actualDeparture": actual_departure.isoformat() + "Z" if actual_departure else None,
        "estimatedArrival": estimated_arrival.isoformat() + "Z",
        "actualArrival": actual_arrival.isoformat() + "Z" if actual_arrival else None,
        "status": status,
        "currentLocation": current_location,
        "contractId": f"cont_{route_id:03d}",
        "tablePricesId": f"tbl_{route_id:03d}",
        "totalValue": total_value,
        "totalWeight": total_weight,
        "estimatedCost": estimated_cost,
        "actualCost": actual_cost,
        "productType": product_type,
        "createdAt": (base_date - timedelta(hours=random.randint(1, 48))).isoformat() + "Z",
        "updatedAt": (base_date + timedelta(minutes=random.randint(0, 300))).isoformat() + "Z",
        "createdBy": f"user_{random.randint(1, 10):03d}",
        "vehiclePlate": vehicle_plate
    }

def generate_all_routes():
    """Gera todas as 500 rotas"""
    routes = []
    route_id = 1
    
    # Distribuição por tipo (conforme especificação)
    type_distribution = [
        ("firstMile", 300),
        ("lineHaul", 125), 
        ("lastMile", 75)
    ]
    
    # Distribuição por região
    region_distribution = [
        ("saoPaulo", 175),
        ("rioDeJaneiro", 150),
        ("minasGerais", 125),
        ("vitoria", 50)
    ]
    
    # Calcular rotas por tipo e região
    total_routes_per_region = {region: count for region, count in region_distribution}
    
    for route_type, type_count in type_distribution:
        # Distribuir este tipo pelas regiões proporcionalmente
        for region, region_total in region_distribution:
            region_proportion = region_total / 500
            routes_for_this_type_region = int(type_count * region_proportion)
            
            for _ in range(routes_for_this_type_region):
                if route_id <= 500:
                    route = generate_route_data(route_id, route_type, region)
                    routes.append(route)
                    route_id += 1
    
    # Completar até 500 se necessário
    while len(routes) < 500:
        remaining_type = random.choice(["firstMile", "lineHaul", "lastMile"])
        remaining_region = random.choice(["saoPaulo", "rioDeJaneiro", "minasGerais", "vitoria"])
        route = generate_route_data(route_id, remaining_type, remaining_region)
        routes.append(route)
        route_id += 1
    
    return routes[:500]  # Garantir exatamente 500

def main():
    """Função principal"""
    print("Gerando 500 rotas mockadas...")
    
    routes = generate_all_routes()
    
    # Calcular estatísticas reais
    type_stats = {}
    status_stats = {}
    region_stats = {}
    
    for route in routes:
        # Tipo
        route_type = route["type"]
        type_stats[route_type] = type_stats.get(route_type, 0) + 1
        
        # Status
        status = route["status"]
        status_stats[status] = status_stats.get(status, 0) + 1
        
        # Região (baseado no telefone)
        phone = route["origin"]["phone"]
        if "11" in phone:
            region = "saoPaulo"
        elif "21" in phone:
            region = "rioDeJaneiro"
        elif "31" in phone:
            region = "minasGerais"
        else:
            region = "vitoria"
        region_stats[region] = region_stats.get(region, 0) + 1
    
    # Estrutura final
    data = {
        "routes": routes,
        "metadata": {
            "totalRoutes": len(routes),
            "generatedAt": datetime.now().isoformat() + "Z",
            "version": "1.0",
            "description": "Dados mockados para o módulo de Rotas do ERP SAAS PraFrota",
            "actualDistributions": {
                "byType": type_stats,
                "byStatus": status_stats,
                "byRegion": region_stats
            },
            "specifications": {
                "byType": {
                    "firstMile": "60% (300 rotas) - Coleta em centros de distribuição",
                    "lineHaul": "25% (125 rotas) - Transporte entre cidades", 
                    "lastMile": "15% (75 rotas) - Entrega final (Mercado Livre, Shopee, Amazon)"
                },
                "byModal": {
                    "rodoviario": "95% (475 rotas)",
                    "aereo": "3% (15 rotas)",
                    "aquaviario": "2% (10 rotas)"
                },
                "regions": {
                    "rioDeJaneiro": "30% (150 rotas)",
                    "saoPaulo": "35% (175 rotas)", 
                    "minasGerais": "25% (125 rotas)",
                    "vitoria": "10% (50 rotas)"
                }
            },
            "realVehiclePlates": REAL_PLATES,
            "productTypes": PRODUCT_TYPES,
            "lastMileMarketplaces": MARKETPLACES,
            "coordinates": REGIONS
        }
    }
    
    # Salvar arquivo
    output_file = "ROUTES_MOCK_DATA_COMPLETE.json"
    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=2)
    
    print(f"✅ Arquivo {output_file} gerado com sucesso!")
    print(f"📊 Estatísticas:")
    print(f"   Total de rotas: {len(routes)}")
    print(f"   Por tipo: {type_stats}")
    print(f"   Por status: {status_stats}")
    print(f"   Por região: {region_stats}")

if __name__ == "__main__":
    main() 