"""
Seed test orders for a team in Odoo.

Creates:
- Test carriers (shipping companies)
- Orders with lines (products)
- Stages (route segments)
- Trips (carrier assignments with dates)
- Tracking events
"""
import sys
import uuid
from datetime import datetime, timedelta
from pathlib import Path

# Add hub folder to path for OdooClient
sys.path.insert(0, str(Path(__file__).parent.parent / "hub"))

from client import OdooClient


TEAM_UUID = "ee0d350a-1ba8-412e-82eb-faecf542fc09"
USER_ID = "test-user-001"

# Test carriers to create
CARRIERS = [
    {
        "team_name": "MSC Mediterranean",
        "contact_person": "John Smith",
        "contact_email": "ops@msc.com",
    },
    {
        "team_name": "Maersk Line",
        "contact_person": "Hans Jensen",
        "contact_email": "ops@maersk.com",
    },
    {
        "team_name": "PIL Shipping",
        "contact_person": "Chen Wei",
        "contact_email": "ops@pil.com",
    },
]

# Test orders data - using real nodes from Odoo
ORDERS = [
    {
        "source": "Lagos",
        "destination": "Berlin",
        "notes": "Test order: Lagos to Berlin - Cocoa",
        "lines": [
            {"product_name": "Cocoa Beans", "quantity": 100, "unit": "tons", "price": 2500, "notes": "Premium grade cocoa beans from West Africa"},
        ],
        "stages": [
            {
                "name": "Lagos → Durban (Sea)",
                "stage_type": "transport",
                "transport_type": "sea",
                "source": "Lagos",
                "destination": "Durban",
                "carrier_idx": 0,  # MSC
                "notes": "Container shipping via Atlantic route",
            },
            {
                "name": "Durban → Berlin (Sea+Rail)",
                "stage_type": "transport",
                "transport_type": "sea",
                "source": "Durban",
                "destination": "Berlin",
                "carrier_idx": 1,  # Maersk
                "notes": "Combined sea and rail transport",
            },
        ]
    },
    {
        "source": "Berlin",
        "destination": "Cape Town",
        "notes": "Test order: Berlin to Cape Town - Electronics",
        "lines": [
            {"product_name": "Electronics", "quantity": 50, "unit": "tons", "price": 15000, "notes": "Consumer electronics, fragile handling required"},
        ],
        "stages": [
            {
                "name": "Berlin → Cape Town (Direct)",
                "stage_type": "transport",
                "transport_type": "sea",
                "source": "Berlin",
                "destination": "Cape Town",
                "carrier_idx": 1,  # Maersk
                "notes": "Direct container shipping",
            },
        ]
    },
    {
        "source": "Cape Town",
        "destination": "Lagos",
        "notes": "Test order: Cape Town to Lagos - Mixed cargo",
        "lines": [
            {"product_name": "Gold Concentrate", "quantity": 10, "unit": "tons", "price": 50000, "notes": "High security transport required"},
            {"product_name": "Copper Ore", "quantity": 200, "unit": "tons", "price": 800, "notes": "Bulk cargo, standard handling"},
        ],
        "stages": [
            {
                "name": "Cape Town → Lagos (Direct Sea)",
                "stage_type": "transport",
                "transport_type": "sea",
                "source": "Cape Town",
                "destination": "Lagos",
                "carrier_idx": 2,  # PIL
                "notes": "Coastal shipping route",
            },
        ]
    },
]


def find_node_by_name(client: OdooClient, name: str) -> int | None:
    """Find logistics node by name (partial match)."""
    results = client.search_read(
        "logistics.node",
        [["name", "ilike", name]],
        fields=["id", "name"],
        limit=1
    )
    if results:
        return results[0]["id"]
    return None


def find_product_by_name(client: OdooClient, name: str) -> int | None:
    """Find product by name (partial match)."""
    results = client.search_read(
        "products.product",
        [["name", "ilike", name]],
        fields=["id", "name"],
        limit=1
    )
    if results:
        return results[0]["id"]
    return None


def unwrap_id(result):
    """Extract ID from create result (handles list or int)."""
    if isinstance(result, list):
        return result[0]
    return result


def create_carriers(client: OdooClient) -> list[int]:
    """Create test carriers and return their IDs."""
    print("\n=== Creating test carriers ===")
    carrier_ids = []

    for carrier_data in CARRIERS:
        # Check if carrier already exists
        existing = client.search_read(
            "carrier",
            [["team_name", "=", carrier_data["team_name"]]],
            fields=["id"],
            limit=1
        )

        if existing:
            carrier_id = existing[0]["id"]
            print(f"  Carrier exists: {carrier_data['team_name']} (id={carrier_id})")
        else:
            carrier_id = unwrap_id(client.create("carrier", {
                "team_uuid": str(uuid.uuid4()),
                "team_name": carrier_data["team_name"],
                "contact_person": carrier_data["contact_person"],
                "contact_email": carrier_data["contact_email"],
                "state": "active",
            }))
            print(f"  Created carrier: {carrier_data['team_name']} (id={carrier_id})")

        carrier_ids.append(carrier_id)

    return carrier_ids


def create_order(client: OdooClient, order_data: dict, carrier_ids: list[int]) -> int | None:
    """Create a single order with lines, stages, trips and tracking."""
    print(f"\n--- Order: {order_data['source']} -> {order_data['destination']} ---")

    # Find source and destination nodes
    source_id = find_node_by_name(client, order_data["source"])
    dest_id = find_node_by_name(client, order_data["destination"])

    if not source_id or not dest_id:
        print(f"  ERROR: Could not find nodes")
        return None

    print(f"  Source: {order_data['source']} (id={source_id})")
    print(f"  Destination: {order_data['destination']} (id={dest_id})")

    # Create order
    order_id = unwrap_id(client.create("marketplace.order", {
        "team_uuid": TEAM_UUID,
        "user_id": USER_ID,
        "source_location_id": source_id,
        "destination_location_id": dest_id,
        "notes": order_data.get("notes", ""),
    }))
    print(f"  Created order id={order_id}")

    # Create order lines
    for line in order_data["lines"]:
        product_id = find_product_by_name(client, line["product_name"])
        if not product_id:
            print(f"  WARNING: Product '{line['product_name']}' not found")
            continue

        unwrap_id(client.create("marketplace.order.line", {
            "order_id": order_id,
            "product_id": product_id,
            "quantity": line["quantity"],
            "unit": line["unit"],
            "price_unit": line["price"],
            "notes": line.get("notes", ""),
        }))
        print(f"  + Line: {line['quantity']} {line['unit']} of {line['product_name']}")

    # Create tracking event: order created
    unwrap_id(client.create("marketplace.order.tracking", {
        "order_id": order_id,
        "status": "created",
        "description": "Order created",
        "created_by": USER_ID,
    }))

    # Create stages
    base_date = datetime.now()
    for seq, stage_data in enumerate(order_data.get("stages", []), start=1):
        stage_source_id = find_node_by_name(client, stage_data["source"])
        stage_dest_id = find_node_by_name(client, stage_data["destination"])

        if not stage_source_id or not stage_dest_id:
            print(f"  WARNING: Stage nodes not found: {stage_data['source']} -> {stage_data['destination']}")
            continue

        stage_id = unwrap_id(client.create("marketplace.order.stage", {
            "order_id": order_id,
            "name": stage_data["name"],
            "stage_type": stage_data["stage_type"],
            "transport_type": stage_data.get("transport_type"),
            "source_location_id": stage_source_id,
            "destination_location_id": stage_dest_id,
            "sequence": seq * 10,
            "notes": stage_data.get("notes", ""),
        }))
        print(f"  + Stage {seq}: {stage_data['name']} (id={stage_id})")

        # Create trip for this stage
        carrier_id = carrier_ids[stage_data.get("carrier_idx", 0)]
        loading_date = base_date + timedelta(days=seq * 7)
        unloading_date = loading_date + timedelta(days=5)

        trip_id = unwrap_id(client.create("marketplace.order.trip", {
            "stage_id": stage_id,
            "carrier_id": carrier_id,
            "name": f"Trip {seq} - {stage_data['name']}",
            "sequence": 10,
            "planned_loading_date": loading_date.strftime("%Y-%m-%d %H:%M:%S"),
            "planned_unloading_date": unloading_date.strftime("%Y-%m-%d %H:%M:%S"),
            "planned_weight": sum(l["quantity"] for l in order_data["lines"]),
        }))
        print(f"    + Trip: id={trip_id}, carrier_id={carrier_id}")

        # Create tracking event for stage
        unwrap_id(client.create("marketplace.order.tracking", {
            "order_id": order_id,
            "stage_id": stage_id,
            "trip_id": trip_id,
            "status": "stage_started",
            "description": f"Stage started: {stage_data['name']}",
            "created_by": USER_ID,
            "location_id": stage_source_id,
        }))

    return order_id


def seed_orders(client: OdooClient):
    """Create all test data."""
    print(f"Seeding orders for team: {TEAM_UUID}")

    # Create carriers first
    carrier_ids = create_carriers(client)

    # Create orders
    print("\n=== Creating orders ===")
    created = 0
    for order_data in ORDERS:
        order_id = create_order(client, order_data, carrier_ids)
        if order_id:
            created += 1

    print(f"\n=== Created {created}/{len(ORDERS)} orders ===")
    return created


def list_orders(client: OdooClient):
    """List existing orders for the team."""
    orders = client.search_read(
        "marketplace.order",
        [["team_uuid", "=", TEAM_UUID]],
        fields=["id", "name", "uuid", "total_amount", "notes"],
    )

    print(f"\nOrders for team {TEAM_UUID}:")
    for order in orders:
        print(f"  {order['name']} (uuid={order['uuid']}) - {order['total_amount']} - {order.get('notes', '')}")

        # List stages
        stages = client.search_read(
            "marketplace.order.stage",
            [["order_id", "=", order["id"]]],
            fields=["id", "name", "stage_type", "transport_type"],
        )
        for stage in stages:
            print(f"    Stage: {stage['name']} ({stage['transport_type']})")

            # List trips
            trips = client.search_read(
                "marketplace.order.trip",
                [["stage_id", "=", stage["id"]]],
                fields=["id", "name", "planned_loading_date", "planned_unloading_date"],
            )
            for trip in trips:
                print(f"      Trip: {trip['name']}")

    return orders


def delete_orders(client: OdooClient):
    """Delete all orders for the team (cascades to stages, trips, tracking)."""
    order_ids = client.search("marketplace.order", [["team_uuid", "=", TEAM_UUID]])

    if order_ids:
        client.unlink("marketplace.order", order_ids)
        print(f"Deleted {len(order_ids)} orders")
    else:
        print("No orders to delete")

    return len(order_ids)


def delete_carriers(client: OdooClient):
    """Delete test carriers."""
    carrier_names = [c["team_name"] for c in CARRIERS]
    carrier_ids = client.search("carrier", [["team_name", "in", carrier_names]])

    if carrier_ids:
        client.unlink("carrier", carrier_ids)
        print(f"Deleted {len(carrier_ids)} carriers")
    else:
        print("No carriers to delete")

    return len(carrier_ids)
