"""Partner account management — registration, API keys, and configuration."""

from __future__ import annotations

import hashlib
import secrets
import uuid

import structlog

from hive_compute.coordinator.database import get_db_ctx
from hive_compute.url_safety import validate_outbound_http_url

logger = structlog.get_logger()
ACTIVE_PARTNER_STATUS = "active"
INACTIVE_PARTNER_STATUS = "inactive"
VALID_PARTNER_STATUSES = {ACTIVE_PARTNER_STATUS, INACTIVE_PARTNER_STATUS}


def create_partner(
    name: str,
    rate_per_minute: float = 0.006,
    callback_url: str | None = None,
    monthly_budget_cents: int | None = None,
    credits_usd: float | None = None,
) -> dict:
    """Create a new partner account. Returns partner info with raw API key."""
    if callback_url:
        validate_outbound_http_url(callback_url, purpose="partner callback_url")

    partner_id = f"partner_{uuid.uuid4().hex[:12]}"
    api_key = f"hive_{secrets.token_urlsafe(32)}"
    api_key_hash = hashlib.sha256(api_key.encode()).hexdigest()
    callback_secret = secrets.token_urlsafe(32) if callback_url else None

    with get_db_ctx() as db:
        db.execute(
            """
            INSERT INTO partners (
                partner_id, name, api_key_hash, callback_url, callback_secret,
                rate_per_minute, credits_usd, monthly_budget_cents
            )
            VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            """,
            (
                partner_id,
                name,
                api_key_hash,
                callback_url,
                callback_secret,
                rate_per_minute,
                credits_usd,
                monthly_budget_cents,
            ),
        )

        # Also add to api_keys table for auth compatibility
        db.execute(
            "INSERT INTO api_keys (key_hash, name) VALUES (?, ?)",
            (api_key_hash, f"partner:{partner_id}"),
        )

    logger.info("Partner created", partner_id=partner_id, name=name)

    return {
        "partner_id": partner_id,
        "name": name,
        "api_key": api_key,  # Only returned at creation time
        "callback_url": callback_url,
        "callback_secret": callback_secret,
        "rate_per_minute": rate_per_minute,
        "credits_usd": credits_usd,
        "monthly_budget_cents": monthly_budget_cents,
    }


def get_partner_by_key_hash(key_hash: str) -> dict | None:
    """Look up a partner by their API key hash."""
    with get_db_ctx() as db:
        row = db.execute(
            "SELECT * FROM partners WHERE api_key_hash = ? AND status = ?",
            (key_hash, ACTIVE_PARTNER_STATUS),
        ).fetchone()

    if not row:
        return None

    return {
        "partner_id": row["partner_id"],
        "name": row["name"],
        "callback_url": row["callback_url"],
        "callback_secret": row["callback_secret"],
        "rate_per_minute": row["rate_per_minute"],
        "credits_usd": row["credits_usd"],
        "monthly_budget_cents": row["monthly_budget_cents"],
        "status": row["status"],
    }


def list_partners() -> list[dict]:
    """List all partner accounts."""
    with get_db_ctx() as db:
        rows = db.execute(
            """
            SELECT partner_id, name, rate_per_minute, credits_usd, monthly_budget_cents,
                   status, callback_url, created_at
            FROM partners
            ORDER BY created_at DESC
            """
        ).fetchall()

    return [
        {
            "partner_id": row["partner_id"],
            "name": row["name"],
            "rate_per_minute": row["rate_per_minute"],
            "credits_usd": row["credits_usd"],
            "monthly_budget_cents": row["monthly_budget_cents"],
            "status": row["status"],
            "callback_url": row["callback_url"],
            "created_at": row["created_at"],
        }
        for row in rows
    ]


def update_partner_status(partner_id: str, status: str) -> dict | None:
    """Update a partner account status and return the current record."""
    if status not in VALID_PARTNER_STATUSES:
        raise ValueError(f"Invalid partner status: {status}")

    with get_db_ctx() as db:
        row = db.execute(
            """
            UPDATE partners
            SET status = ?
            WHERE partner_id = ?
            RETURNING partner_id, name, rate_per_minute, credits_usd, monthly_budget_cents,
                      status, callback_url, created_at
            """,
            (status, partner_id),
        ).fetchone()

    if not row:
        return None

    return {
        "partner_id": row["partner_id"],
        "name": row["name"],
        "rate_per_minute": row["rate_per_minute"],
        "credits_usd": row["credits_usd"],
        "monthly_budget_cents": row["monthly_budget_cents"],
        "status": row["status"],
        "callback_url": row["callback_url"],
        "created_at": row["created_at"],
    }


def update_partner_budget(partner_id: str, monthly_budget_cents: int | None) -> dict | None:
    """Update a partner's monthly budget cap and return the current record."""
    with get_db_ctx() as db:
        row = db.execute(
            """
            UPDATE partners
            SET monthly_budget_cents = ?
            WHERE partner_id = ?
            RETURNING partner_id, name, rate_per_minute, credits_usd, monthly_budget_cents,
                      status, callback_url, created_at
            """,
            (monthly_budget_cents, partner_id),
        ).fetchone()

    if not row:
        return None

    return {
        "partner_id": row["partner_id"],
        "name": row["name"],
        "rate_per_minute": row["rate_per_minute"],
        "credits_usd": row["credits_usd"],
        "monthly_budget_cents": row["monthly_budget_cents"],
        "status": row["status"],
        "callback_url": row["callback_url"],
        "created_at": row["created_at"],
    }
