"""
Step 1: Register a Stripe webhook endpoint via ngrok and update .env.

Run BEFORE starting the dev server:
    1. Start ngrok:        ngrok http 5000
    2. Run this script:    uv run python scripts/stripe_e2e_setup.py
    3. Start dev server:   make dev
    4. Run E2E tests:      uv run python scripts/stripe_e2e_test.py

To tear down afterward:
    uv run python scripts/stripe_e2e_setup.py --teardown
"""

import json
import os
import re
import sys
import urllib.request

from dotenv import load_dotenv

load_dotenv()

import stripe

STRIPE_SECRET_KEY = os.getenv("STRIPE_SECRET_KEY", "") or os.getenv("STRIPE_API_PRIVATE_KEY", "")
if not STRIPE_SECRET_KEY:
    print("ERROR: Set STRIPE_SECRET_KEY or STRIPE_API_PRIVATE_KEY in .env")
    sys.exit(1)

stripe.api_key = STRIPE_SECRET_KEY
stripe.max_network_retries = 2

ENV_PATH = os.path.join(os.path.dirname(__file__), "..", ".env")
ENV_PATH = os.path.abspath(ENV_PATH)
WEBHOOK_PATH = "/billing/webhook/stripe"
NGROK_API = "http://localhost:4040/api/tunnels"


def _update_env(key, value):
    """Update a key in .env file."""
    text = open(ENV_PATH).read()
    pattern = rf"^{key}=.*$"
    replacement = f"{key}={value}"
    if re.search(pattern, text, re.MULTILINE):
        text = re.sub(pattern, replacement, text, flags=re.MULTILINE)
    else:
        text = text.rstrip("\n") + f"\n{replacement}\n"
    open(ENV_PATH, "w").write(text)


def setup():
    # Get ngrok tunnel URL
    try:
        resp = urllib.request.urlopen(NGROK_API, timeout=5)
        tunnels = json.loads(resp.read())
        tunnel_url = tunnels["tunnels"][0]["public_url"]
    except Exception as e:
        print(f"ERROR: ngrok not running: {e}")
        print("Start ngrok first:  ngrok http 5000")
        sys.exit(1)

    webhook_url = f"{tunnel_url}{WEBHOOK_PATH}"
    print(f"ngrok tunnel: {tunnel_url}")
    print(f"Webhook URL:  {webhook_url}")

    # Check for existing E2E webhook endpoint
    existing_id = os.getenv("STRIPE_WEBHOOK_ENDPOINT_ID", "")
    if existing_id:
        try:
            ep = stripe.WebhookEndpoint.retrieve(existing_id)
            if ep.url == webhook_url and ep.status == "enabled":
                print(f"\nEndpoint already exists and matches: {existing_id}")
                print("Ready to test. Run:  uv run python scripts/stripe_e2e_test.py")
                return
            # URL changed (new ngrok session), delete and recreate
            print(f"Existing endpoint URL mismatch, recreating...")
            stripe.WebhookEndpoint.delete(existing_id)
        except stripe.InvalidRequestError:
            pass  # Already deleted

    # Create webhook endpoint
    endpoint = stripe.WebhookEndpoint.create(
        url=webhook_url,
        enabled_events=[
            "checkout.session.completed",
            "customer.subscription.created",
            "customer.subscription.updated",
            "customer.subscription.deleted",
            "invoice.payment_failed",
        ],
    )

    print(f"\nCreated endpoint: {endpoint.id}")
    print(f"Webhook secret:  {endpoint.secret[:25]}...")

    # Update .env
    _update_env("STRIPE_WEBHOOK_SECRET", endpoint.secret)
    _update_env("STRIPE_WEBHOOK_ENDPOINT_ID", endpoint.id)
    print("\nUpdated .env with STRIPE_WEBHOOK_SECRET and STRIPE_WEBHOOK_ENDPOINT_ID")
    print("\nNext steps:")
    print("  1. Restart dev server:  make dev")
    print("  2. Run E2E tests:       uv run python scripts/stripe_e2e_test.py")


def teardown():
    endpoint_id = os.getenv("STRIPE_WEBHOOK_ENDPOINT_ID", "")
    if endpoint_id:
        try:
            stripe.WebhookEndpoint.delete(endpoint_id)
            print(f"Deleted webhook endpoint: {endpoint_id}")
        except stripe.InvalidRequestError:
            print(f"Endpoint {endpoint_id} already deleted")

    _update_env("STRIPE_WEBHOOK_SECRET", "")
    _update_env("STRIPE_WEBHOOK_ENDPOINT_ID", "")
    print("Cleared .env webhook config")


if __name__ == "__main__":
    if "--teardown" in sys.argv:
        teardown()
    else:
        setup()
