#!/usr/bin/env python3
"""
Import logistics nodes into Odoo from CSV files.
"""
import csv
import os
from pathlib import Path

from client import OdooClient


# UN/LOCODE function code mapping
# 1=Port, 2=Rail, 3=Road, 4=Airport, 5=Postal, 6=Multimodal, 7=Fixed transport, B=Border crossing
FUNCTION_MAP = {
    "1": ("sea", "container", "Port Terminal"),
    "2": ("rail", "container", "Railway Terminal"),
    "3": ("auto", "bulk", "Road Terminal"),
    "4": ("air", "container", "Airport"),
    "5": ("auto", "bulk", "Postal Exchange"),
    "6": ("auto", "container", "Multimodal"),
    "7": ("rail", "container", "Fixed Transport"),
    "B": ("auto", "bulk", "Border Crossing"),
}


TRANSPORT_CATEGORIES = [
    {"name": "Automotive", "code": "auto", "sequence": 10},
    {"name": "Railway", "code": "rail", "sequence": 20},
    {"name": "Maritime", "code": "sea", "sequence": 30},
    {"name": "River", "code": "river", "sequence": 40},
    {"name": "Air", "code": "air", "sequence": 50},
]

LOADING_TYPES = [
    {"name": "Container", "code": "container", "sequence": 10},
    {"name": "Bulk", "code": "bulk", "sequence": 20},
    {"name": "Break Bulk", "code": "breakbulk", "sequence": 30},
    {"name": "RoRo", "code": "roro", "sequence": 40},
]


def ensure_reference_data(client: OdooClient):
    """Create transport categories and loading types if they don't exist."""
    print("Ensuring reference data exists...")

    for cat in TRANSPORT_CATEGORIES:
        existing = client.search("logistics.transport.category", [["code", "=", cat["code"]]], limit=1)
        if not existing:
            client.create("logistics.transport.category", cat)
            print(f"  Created transport category: {cat['name']}")

    for lt in LOADING_TYPES:
        existing = client.search("logistics.loading.type", [["code", "=", lt["code"]]], limit=1)
        if not existing:
            client.create("logistics.loading.type", lt)
            print(f"  Created loading type: {lt['name']}")


def get_transport_refs(client: OdooClient) -> dict:
    """Get transport category and loading type references."""
    ensure_reference_data(client)

    refs = {}

    # Transport categories
    for code in ["rail", "auto", "sea", "air", "river"]:
        result = client.search_read(
            "logistics.transport.category", [["code", "=", code]], fields=["id"], limit=1
        )
        refs[f"cat_{code}"] = result[0]["id"] if result else None

    # Loading types
    for code in ["container", "bulk", "breakbulk", "roro"]:
        result = client.search_read(
            "logistics.loading.type", [["code", "=", code]], fields=["id"], limit=1
        )
        refs[f"load_{code}"] = result[0]["id"] if result else None

    return refs


def import_from_csv(client: OdooClient, refs: dict, csv_path: str) -> int:
    """Import nodes from a CSV file."""
    print(f"\n=== Importing from CSV: {csv_path} ===")

    if not os.path.exists(csv_path):
        print(f"  File not found: {csv_path}")
        return 0

    existing = client.search_read("logistics.node", [], fields=["id", "code"])
    existing_codes = {n["code"]: n["id"] for n in existing if n["code"]}

    created = 0
    skipped = 0
    errors = 0

    with open(csv_path, "r", encoding="utf-8") as f:
        reader = csv.DictReader(f)
        for row in reader:
            code = row.get("code", "")
            if code in existing_codes:
                skipped += 1
                continue

            country_code = row.get("country", "")
            country_id = client.get_country(country_code)
            if not country_id:
                errors += 1
                continue

            # Parse coordinates
            lat = row.get("latitude")
            lon = row.get("longitude")
            if lat and lon:
                try:
                    lat = float(lat)
                    lon = float(lon)
                except ValueError:
                    errors += 1
                    continue
            else:
                errors += 1
                continue

            # Parse all function codes and create connections for each
            func = row.get("function", "3")
            connections = []
            for char in func:
                if char in FUNCTION_MAP:
                    cat_code, load_code, conn_name = FUNCTION_MAP[char]
                    cat_id = refs.get(f"cat_{cat_code}")
                    load_id = refs.get(f"load_{load_code}")
                    if cat_id and load_id:
                        connections.append((0, 0, {
                            "name": conn_name,
                            "transport_category_id": cat_id,
                            "loading_type_id": load_id,
                        }))

            vals = {
                "code": code,
                "name": row.get("name", code),
                "latitude": lat,
                "longitude": lon,
                "country_id": country_id,
                "connection_ids": connections,
            }

            try:
                client.create("logistics.node", vals)
                created += 1
                if created % 100 == 0:
                    print(f"  Created {created} nodes...")
            except Exception as e:
                print(f"  Error creating {code}: {e}")
                errors += 1

    print(f"CSV import: {created} created, {skipped} skipped, {errors} errors")
    return created


def main():
    """Import nodes from all CSV files in datasets/."""
    client = OdooClient()
    client.connect()

    refs = get_transport_refs(client)
    print(f"Transport refs: {refs}")

    datasets_dir = Path(__file__).parent
    csv_files = list(datasets_dir.glob("*.csv"))

    if not csv_files:
        print(f"No CSV files found in {datasets_dir}")
        return

    for csv_path in csv_files:
        import_from_csv(client, refs, str(csv_path))


if __name__ == "__main__":
    main()
