"""
CheckoutScenario — Click checkout, fill Stripe test card, submit payment,
wait for redirect to success URL.

config keys:
    checkout_button_selector (str)  — CSS selector for checkout button on plan page
    stripe_card_number_selector (str)   — selector inside Stripe iframe for card number
    stripe_expiry_selector (str)        — selector for expiry field
    stripe_cvc_selector (str)           — selector for CVC field
    stripe_name_selector (str)          — selector for cardholder name (optional)
    stripe_submit_selector (str)        — selector for Stripe pay button
    success_url_fragment (str)          — URL fragment present after successful payment
    success_selector (str)              — selector visible on success page
    test_card_number (str)              — defaults to 4242424242424242
    test_card_expiry (str)              — defaults to 12/30
    test_card_cvc (str)                 — defaults to 123
    test_card_name (str)                — defaults to Test User

NOTE: Stripe Checkout embeds its own iframe. This scenario handles both:
  - Stripe Checkout (hosted, full-page redirect) — fill directly on stripe.com
  - Stripe Payment Element (embedded) — fill inside frame
"""

from .base import BaseScenario, ScenarioResult


# Default Stripe test card
DEFAULT_CARD = "4242424242424242"
DEFAULT_EXPIRY = "12/30"
DEFAULT_CVC = "123"
DEFAULT_NAME = "Test User"

# Stripe hosted checkout selectors
STRIPE_HOSTED_CARD_SEL = "input[name=cardnumber], input[data-elements-stable-field-name=cardNumber]"
STRIPE_HOSTED_EXPIRY_SEL = "input[name=exp-date], input[data-elements-stable-field-name=cardExpiry]"
STRIPE_HOSTED_CVC_SEL = "input[name=cvc], input[data-elements-stable-field-name=cardCvc]"
STRIPE_HOSTED_NAME_SEL = "input[name=billingName]"
STRIPE_HOSTED_SUBMIT_SEL = "button[type=submit]"


class CheckoutScenario(BaseScenario):
    name = "checkout"

    async def run(self, page, config: dict) -> None:
        # -- Step 1: Click checkout button (if on plan selection page)
        checkout_btn_sel = config.get("checkout_button_selector", "")
        if checkout_btn_sel:
            await self._click(checkout_btn_sel, step_name="click_checkout_button")

        # -- Step 2: Wait for Stripe page/frame to load
        step = self._new_step("wait_for_stripe")
        try:
            # Wait for Stripe's card number field — could be in iframe or hosted page
            card_sel = config.get(
                "stripe_card_number_selector",
                STRIPE_HOSTED_CARD_SEL,
            )
            # If hosted checkout, URL will move to checkout.stripe.com
            try:
                await page.wait_for_url("**/checkout.stripe.com/**", timeout=self._timeout)
                self._finish_step(step, "pass", "Stripe hosted checkout page loaded")
                stripe_context = page  # direct fill on stripe.com
            except Exception:
                # Try embedded payment element
                stripe_context = page
                await page.wait_for_selector(card_sel, timeout=self._timeout)
                self._finish_step(step, "pass", "Stripe payment element loaded (embedded)")
        except Exception as exc:
            step.screenshot_path = await self._screenshot("stripe_load")
            self._finish_step(step, "error", f"Stripe did not load: {exc}")
            return

        # -- Step 3: Fill card number
        card_number = config.get("test_card_number", DEFAULT_CARD)
        card_sel = config.get("stripe_card_number_selector", STRIPE_HOSTED_CARD_SEL)
        await self._fill(card_sel, card_number, step_name="fill_card_number")

        # -- Step 4: Fill expiry
        expiry = config.get("test_card_expiry", DEFAULT_EXPIRY)
        expiry_sel = config.get("stripe_expiry_selector", STRIPE_HOSTED_EXPIRY_SEL)
        await self._fill(expiry_sel, expiry, step_name="fill_card_expiry")

        # -- Step 5: Fill CVC
        cvc = config.get("test_card_cvc", DEFAULT_CVC)
        cvc_sel = config.get("stripe_cvc_selector", STRIPE_HOSTED_CVC_SEL)
        await self._fill(cvc_sel, cvc, step_name="fill_card_cvc")

        # -- Step 6: Fill cardholder name (optional — not all Stripe flows show it)
        name_sel = config.get("stripe_name_selector", STRIPE_HOSTED_NAME_SEL)
        name = config.get("test_card_name", DEFAULT_NAME)
        step_name_fill = self._new_step("fill_cardholder_name")
        try:
            name_el = await stripe_context.query_selector(name_sel)
            if name_el:
                await stripe_context.fill(name_sel, name)
                self._finish_step(step_name_fill, "pass", "Cardholder name filled")
            else:
                self._finish_step(step_name_fill, "pass", "Cardholder name field not present — skipped")
        except Exception as exc:
            self._finish_step(step_name_fill, "pass", f"Name field skipped: {exc}")

        # -- Step 7: Submit payment
        submit_sel = config.get("stripe_submit_selector", STRIPE_HOSTED_SUBMIT_SEL)
        await self._click(submit_sel, step_name="submit_payment")

        # -- Step 8: Wait for redirect back to success URL
        success_url_fragment = config.get("success_url_fragment", "success")
        await self._verify_url_contains(success_url_fragment, step_name="verify_success_redirect")

        # -- Step 9: Verify success element
        success_selector = config.get("success_selector", "")
        if success_selector:
            await self._verify_selector_visible(success_selector, step_name="verify_success_element")

        # -- Step 10: Screenshot of success state
        await self._capture_screenshot_step("payment_success")
