"""
Tests for the commodity analytics API endpoints.
"""
import hashlib
import secrets
from datetime import datetime

import pytest


async def _create_api_key_for_user(db, user_id, plan="starter"):
    """Helper: create an API key and subscription, return the raw key."""
    raw_key = f"sk_{secrets.token_urlsafe(32)}"
    key_hash = hashlib.sha256(raw_key.encode()).hexdigest()
    now = datetime.utcnow().isoformat()

    await db.execute(
        """INSERT INTO api_keys (user_id, name, key_hash, key_prefix, scopes, created_at)
           VALUES (?, ?, ?, ?, ?, ?)""",
        (user_id, "test-key", key_hash, raw_key[:12], "read,write", now),
    )

    # Create subscription for plan
    if plan != "free":
        await db.execute(
            """INSERT OR REPLACE INTO subscriptions
               (user_id, plan, status, created_at, updated_at)
               VALUES (?, ?, 'active', ?, ?)""",
            (user_id, plan, now, now),
        )
    await db.commit()

    return raw_key


@pytest.mark.asyncio
async def test_api_requires_auth(client):
    """API returns 401 without auth header."""
    response = await client.get("/api/v1/commodities")
    assert response.status_code == 401


@pytest.mark.asyncio
async def test_api_rejects_free_plan(client, db, test_user, mock_analytics):
    """API returns 403 for free plan users."""
    raw_key = await _create_api_key_for_user(db, test_user["id"], plan="free")
    response = await client.get(
        "/api/v1/commodities",
        headers={"Authorization": f"Bearer {raw_key}"},
    )
    assert response.status_code == 403


@pytest.mark.asyncio
async def test_list_commodities(client, db, test_user, mock_analytics):
    """GET /commodities returns commodity list."""
    raw_key = await _create_api_key_for_user(db, test_user["id"])
    response = await client.get(
        "/api/v1/commodities",
        headers={"Authorization": f"Bearer {raw_key}"},
    )
    assert response.status_code == 200
    data = await response.get_json()
    assert "commodities" in data
    assert len(data["commodities"]) == 2


@pytest.mark.asyncio
async def test_commodity_metrics(client, db, test_user, mock_analytics):
    """GET /commodities/<code>/metrics returns time series."""
    raw_key = await _create_api_key_for_user(db, test_user["id"])
    response = await client.get(
        "/api/v1/commodities/711100/metrics?metrics=production&metrics=exports",
        headers={"Authorization": f"Bearer {raw_key}"},
    )
    assert response.status_code == 200
    data = await response.get_json()
    assert data["commodity_code"] == 711100
    assert "production" in data["metrics"]


@pytest.mark.asyncio
async def test_commodity_metrics_invalid_metric(client, db, test_user, mock_analytics):
    """GET /commodities/<code>/metrics rejects invalid metrics."""
    raw_key = await _create_api_key_for_user(db, test_user["id"])
    response = await client.get(
        "/api/v1/commodities/711100/metrics?metrics=DROP_TABLE",
        headers={"Authorization": f"Bearer {raw_key}"},
    )
    assert response.status_code == 400


@pytest.mark.asyncio
async def test_commodity_countries(client, db, test_user, mock_analytics):
    """GET /commodities/<code>/countries returns ranking."""
    raw_key = await _create_api_key_for_user(db, test_user["id"])
    response = await client.get(
        "/api/v1/commodities/711100/countries?metric=production&limit=5",
        headers={"Authorization": f"Bearer {raw_key}"},
    )
    assert response.status_code == 200
    data = await response.get_json()
    assert data["metric"] == "production"


@pytest.mark.asyncio
async def test_commodity_csv_export(client, db, test_user, mock_analytics):
    """GET /commodities/<code>/metrics.csv returns CSV."""
    raw_key = await _create_api_key_for_user(db, test_user["id"])
    response = await client.get(
        "/api/v1/commodities/711100/metrics.csv",
        headers={"Authorization": f"Bearer {raw_key}"},
    )
    assert response.status_code == 200
    assert "text/csv" in response.content_type


@pytest.mark.asyncio
async def test_me_endpoint(client, db, test_user, mock_analytics):
    """GET /me returns user info."""
    raw_key = await _create_api_key_for_user(db, test_user["id"])
    response = await client.get(
        "/api/v1/me",
        headers={"Authorization": f"Bearer {raw_key}"},
    )
    assert response.status_code == 200
    data = await response.get_json()
    assert data["email"] == "test@example.com"
    assert data["plan"] == "starter"
