"""Tests pour l'integration Stripe simulée."""

import hmac
import hashlib
import sqlite3
import time

import pytest

from web_sentinel.payment import StripeClient, WebhookHandler, api_routes
from web_sentinel.payment.database import LicenseDatabase
from web_sentinel.payment.email_service import EmailService


def test_stripe_client_initialization():
    client = StripeClient(test_mode=True, api_key="sk_test_123")
    assert client.is_configured()


def test_create_checkout_session():
    client = StripeClient(test_mode=True, api_key="sk_test_123")
    session = client.create_checkout_session("pro", "monthly")
    assert session["url"].startswith("https://checkout.stripe.com/")
    assert session["price_id"] == "price_pro_monthly"


def test_webhook_signature_validation():
    handler = WebhookHandler(tolerance=600)
    payload = '{"id":"evt_test"}'
    secret = "whsec_test"
    timestamp = int(time.time())
    signature = hmac.new(
        secret.encode("utf-8"),
        f"{timestamp}.{payload}".encode("utf-8"),
        hashlib.sha256,
    ).hexdigest()
    header = f"t={timestamp},v1={signature}"

    assert handler.validate_signature(payload, header, secret)
    assert not handler.validate_signature(payload, header.replace(signature, "bad"), secret)


def test_handle_checkout_completed_creates_license(tmp_path, monkeypatch):
    temp_db = LicenseDatabase(tmp_path / "licenses.db")
    monkeypatch.setattr(api_routes, "license_store", temp_db)

    captured_email = {}

    class DummyEmailService:
        def send_license_email(self, to_email, api_key, tier, customer_name=None):
            captured_email.update(
                {
                    "to_email": to_email,
                    "api_key": api_key,
                    "tier": tier,
                    "customer_name": customer_name,
                }
            )
            return True

    monkeypatch.setattr(api_routes, "email_service", DummyEmailService())

    session = {
        "id": "cs_test_123",
        "customer": "cus_123",
        "subscription": "sub_123",
        "customer_details": {"email": "client@example.com", "name": "Client Test"},
        "metadata": {"tier": "PRO"},
    }

    api_routes.handle_checkout_completed(session)

    with sqlite3.connect(temp_db.db_path) as conn:
        row = conn.execute(
            "SELECT email, tier, stripe_subscription_id, status, api_key FROM licenses"
        ).fetchone()

    assert row is not None
    email, tier, subscription_id, status, api_key = row
    assert email == "client@example.com"
    assert tier == "PRO"
    assert subscription_id == "sub_123"
    assert status == "active"

    assert captured_email["to_email"] == "client@example.com"
    assert captured_email["tier"] == "PRO"
    assert captured_email["customer_name"] == "Client Test"
    assert captured_email["api_key"] == api_key


def test_send_license_email_builds_payload(monkeypatch):
    service = EmailService()

    captured = {}

    monkeypatch.setattr(
        service,
        "_send_email",
        lambda to_email, subject, html_body, text_body: captured.update(
            {
                "to": to_email,
                "subject": subject,
                "html": html_body,
                "text": text_body,
            }
        )
        or True,
    )

    result = service.send_license_email(
        to_email="client@example.com",
        api_key="ws_live_ABC123",
        tier="pro",
        customer_name="Client",
    )

    assert result is True
    assert captured["to"] == "client@example.com"
    assert "ws_live_ABC123" in captured["html"]
    assert "ws_live_ABC123" in captured["text"]
    assert "Pro" in captured["subject"].title()


def _insert_test_license(db: LicenseDatabase, subscription_id: str) -> str:
    record = db.create_license(
        email="user@example.com",
        tier="PRO",
        stripe_customer_id="cus_test",
        stripe_subscription_id=subscription_id,
    )
    return record["api_key"]


def _get_status(db: LicenseDatabase, api_key: str) -> str:
    with sqlite3.connect(db.db_path) as conn:
        return conn.execute(
            "SELECT status FROM licenses WHERE api_key = ?", (api_key,)
        ).fetchone()[0]


def test_handle_subscription_updated_changes_status(tmp_path, monkeypatch):
    temp_db = LicenseDatabase(tmp_path / "licenses.db")
    monkeypatch.setattr(api_routes, "license_store", temp_db)
    api_key = _insert_test_license(temp_db, "sub_update")

    api_routes.handle_subscription_updated({"id": "sub_update", "status": "past_due"})

    assert _get_status(temp_db, api_key) == "suspended"


def test_handle_subscription_deleted_sends_email(tmp_path, monkeypatch):
    temp_db = LicenseDatabase(tmp_path / "licenses.db")
    monkeypatch.setattr(api_routes, "license_store", temp_db)
    api_key = _insert_test_license(temp_db, "sub_delete")

    captured = {}

    class DummyEmailService(EmailService):
        def send_subscription_cancelled_email(self, to_email, tier, customer_name=None):
            captured.update(
                {"to_email": to_email, "tier": tier, "customer_name": customer_name}
            )
            return True

    monkeypatch.setattr(api_routes, "email_service", DummyEmailService())

    api_routes.handle_subscription_deleted({"id": "sub_delete"})

    assert _get_status(temp_db, api_key) == "cancelled"
    assert captured["to_email"] == "user@example.com"
    assert captured["tier"] == "PRO"


def test_handle_payment_failure_and_recovery(tmp_path, monkeypatch):
    temp_db = LicenseDatabase(tmp_path / "licenses.db")
    monkeypatch.setattr(api_routes, "license_store", temp_db)
    api_key = _insert_test_license(temp_db, "sub_pay")

    api_routes.handle_payment_failed({"id": "in_1", "subscription": "sub_pay"})
    assert _get_status(temp_db, api_key) == "suspended"

    api_routes.handle_payment_succeeded({"id": "in_2", "subscription": "sub_pay"})
    assert _get_status(temp_db, api_key) == "active"
