import sys
from pathlib import Path

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient

BACKEND_DIR = Path(__file__).parent.parent
sys.path.insert(0, str(BACKEND_DIR))
sys.path.insert(0, str(BACKEND_DIR / "plugins"))

import payments_plugin  # noqa: E402
from plugins.payments_plugin import PRODUCTS, SUBSCRIPTIONS, _platform_fee  # noqa: E402


@pytest.mark.parametrize("product_id", [
    "angelzen-tier-100",
    "angelzen-tier-500",
    "angelzen-tier-1000",
    "yuliantarot-tier-100",
    "yuliantarot-tier-500",
    "yuliantarot-tier-1000",
    "angelzen-item-incense",
    "yuliantarot-item-crystal",
])
def test_one_time_products_exist(product_id):
    assert product_id in PRODUCTS
    assert PRODUCTS[product_id]["currency"] == "hkd"
    assert "platform_fee_rate" not in PRODUCTS[product_id] or PRODUCTS[product_id]["platform_fee_rate"] == 0.05


@pytest.mark.parametrize("sub_id", [
    "angelzen-subscription-10k",
    "yuliantarot-subscription-10k",
])
def test_subscriptions_exist(sub_id):
    assert sub_id in SUBSCRIPTIONS
    assert SUBSCRIPTIONS[sub_id]["currency"] == "hkd"
    assert SUBSCRIPTIONS[sub_id]["price_hkd"] == 10000
    assert SUBSCRIPTIONS[sub_id]["interval"] == "month"


def test_platform_fee_default():
    assert _platform_fee(100) == 5.0
    assert _platform_fee(500) == 25.0
    assert _platform_fee(1000) == 50.0
    assert _platform_fee(10000) == 500.0


def make_client(monkeypatch: pytest.MonkeyPatch, config: dict | None = None):
    store = {"orders": {}, "balances": {}, "credit_txs": [], "subscriptions": {}}
    monkeypatch.setattr(payments_plugin, "_load_store", lambda: store)
    monkeypatch.setattr(payments_plugin, "_save_store", lambda s: None)
    app = FastAPI()
    plugin = payments_plugin.PaymentsPlugin().bind({"payments_config": config or {}})
    plugin.register(app)
    return TestClient(app), store


def test_subscribe_unknown_id(monkeypatch: pytest.MonkeyPatch):
    client, _ = make_client(monkeypatch)
    response = client.post("/payments/subscribe", json={
        "subscription_id": "unknown-sub",
        "user_id": "user_123",
        "method": "stripe",
    })
    assert response.status_code == 400
    assert "Unknown subscription_id" in response.json()["detail"]


def test_subscribe_creates_record(monkeypatch: pytest.MonkeyPatch):
    client, store = make_client(monkeypatch)
    response = client.post("/payments/subscribe", json={
        "subscription_id": "angelzen-subscription-10k",
        "user_id": "user_123",
        "method": "stripe",
    })
    assert response.status_code == 200
    data = response.json()
    assert data["amount_hkd"] == 10000
    assert data["platform_fee_hkd"] == 500.0
    assert data["status"] == "pending"
    assert "subscription_id" in data
    assert len(store["subscriptions"]) == 1


def test_checkout_hkd_product(monkeypatch: pytest.MonkeyPatch):
    client, store = make_client(monkeypatch)
    response = client.post("/payments/checkout", json={
        "product_id": "angelzen-tier-500",
        "user_id": "user_123",
        "currency": "hkd",
        "method": "stripe",
    })
    assert response.status_code == 200
    data = response.json()
    assert data["amount_hkd"] == 500
    assert data["platform_fee_hkd"] == 25.0
    assert data["currency"] == "hkd"
    order = list(store["orders"].values())[0]
    assert order["amount_hkd"] == 500
    assert order["currency"] == "hkd"
    assert order["platform_fee_hkd"] == 25.0


def test_checkout_usd_product_still_works(monkeypatch: pytest.MonkeyPatch):
    client, store = make_client(monkeypatch)
    response = client.post("/payments/checkout", json={
        "product_id": "karma",
        "user_id": "user_123",
        "currency": "usd",
        "method": "stripe",
    })
    assert response.status_code == 200
    data = response.json()
    assert data["amount_usd"] == 33
    assert data["currency"] == "usd"
    order = list(store["orders"].values())[0]
    assert order["amount_usd"] == 33
    assert order["erc_amount"] == order["amount_usd"] * 10
