"""
Sync offer node to Optovia Maps graph.
- Upsert offer node
- Create edge offer -> location
"""
import os
from datetime import datetime

# Load secrets from Infisical first
import config  # noqa: F401

from arango import ArangoClient
from prefect import flow, task, get_run_logger

ARANGODB_URL = os.environ.get("ARANGODB_URL", "http://217.216.32.39:32844")
ARANGODB_DATABASE = os.environ.get("ARANGODB_DATABASE", "optovia_maps")
ARANGODB_PASSWORD = os.environ.get("ARANGODB_PASSWORD", "")


def get_db():
    client = ArangoClient(hosts=ARANGODB_URL)
    return client.db(ARANGODB_DATABASE, username="root", password=ARANGODB_PASSWORD)


@task
def upsert_offer_node(offer_data: dict) -> str:
    logger = get_run_logger()
    db = get_db()

    if not db.has_collection("nodes"):
        db.create_collection("nodes")

    nodes = db.collection("nodes")

    offer_uuid = offer_data["uuid"]
    doc = {
        "_key": offer_uuid,
        "name": offer_data.get("name") or f"Offer {offer_uuid}",
        "latitude": offer_data.get("location_latitude"),
        "longitude": offer_data.get("location_longitude"),
        "country": offer_data.get("location_country"),
        "country_code": offer_data.get("location_country_code"),
        "transport_types": [],
        "node_type": "offer",
        "team_uuid": offer_data.get("team_uuid"),
        "product_uuid": offer_data.get("product_uuid"),
        "price_per_unit": offer_data.get("price_per_unit"),
        "currency": offer_data.get("currency"),
        "quantity": offer_data.get("quantity"),
        "unit": offer_data.get("unit"),
        "synced_at": datetime.utcnow().isoformat(),
    }

    if nodes.has(offer_uuid):
        nodes.update(doc)
        logger.info("Updated offer node %s", offer_uuid)
    else:
        nodes.insert(doc)
        logger.info("Inserted offer node %s", offer_uuid)

    return offer_uuid


@task
def upsert_offer_edge(offer_uuid: str, location_uuid: str) -> bool:
    logger = get_run_logger()
    db = get_db()

    if not db.has_collection("edges"):
        db.create_collection("edges", edge=True)

    edges = db.collection("edges")

    edge_key = f"{offer_uuid}_{location_uuid}_offer"
    doc = {
        "_key": edge_key,
        "_from": f"nodes/{offer_uuid}",
        "_to": f"nodes/{location_uuid}",
        "type": "offer",
        "transport_type": "offer",
        "distance_km": 0,
        "travel_time_seconds": 0,
        "source": "offer",
        "priority": 1,
        "calculated_at": datetime.utcnow().isoformat(),
    }

    if edges.has(edge_key):
        edges.update(doc)
        logger.info("Updated offer edge %s -> %s", offer_uuid, location_uuid)
    else:
        edges.insert(doc)
        logger.info("Created offer edge %s -> %s", offer_uuid, location_uuid)

    return True


@flow(name="sync-offer", log_prints=True)
def sync_offer(offer_data: dict):
    """Sync offer to graph database."""
    logger = get_run_logger()

    offer_uuid = offer_data.get("uuid")
    location_uuid = offer_data.get("location_uuid")

    if not offer_uuid or not location_uuid:
        raise ValueError("offer_data must include uuid and location_uuid")

    logger.info("Syncing offer %s to graph", offer_uuid)

    upsert_offer_node(offer_data)
    upsert_offer_edge(offer_uuid, location_uuid)

    logger.info("Offer %s synced", offer_uuid)
    return {"offer_uuid": offer_uuid, "status": "ok"}
