"""Subscriptions API endpoint mixin."""

from typing import TYPE_CHECKING

from growflow_billing.models.subscription import Subscription, SubscriptionStatus

if TYPE_CHECKING:
    from growflow_billing.client import GrowFlowBillingClient


class SubscriptionsMixin:
    """Mixin for subscription-related API calls."""

    async def get_subscription(
        self: "GrowFlowBillingClient",
        external_id: str,
    ) -> Subscription | None:
        """Get active subscription for a subscriber.

        Returns the most recent active or trialing subscription.

        Args:
            external_id: Subscriber's external ID

        Returns:
            Subscription object or None if no active subscription

        Example:
            subscription = await client.get_subscription("store_123")
            if subscription:
                print(f"Plan: {subscription.plan_slug}")
                print(f"Status: {subscription.status}")
        """
        subscriptions = await self.list_subscriptions(external_id)

        # Return first active or trialing subscription
        for sub in subscriptions:
            if sub.status in (SubscriptionStatus.ACTIVE, SubscriptionStatus.TRIALING):
                return sub

        return None

    async def list_subscriptions(
        self: "GrowFlowBillingClient",
        external_id: str,
        status: SubscriptionStatus | str | None = None,
        limit: int = 20,
        offset: int = 0,
    ) -> list[Subscription]:
        """List subscriptions for a subscriber.

        Args:
            external_id: Subscriber's external ID
            status: Filter by status (optional)
            limit: Max results (default: 20)
            offset: Pagination offset (default: 0)

        Returns:
            List of Subscription objects
        """
        params: dict[str, str | int] = {
            "subscriber_external_id": external_id,
            "limit": limit,
            "offset": offset,
        }
        if status:
            params["status"] = status.value if isinstance(status, SubscriptionStatus) else status

        response = await self._request("GET", "/subscriptions", params=params)

        # Handle both list and paginated responses
        if isinstance(response, list):
            return [Subscription(**s) for s in response]
        return [Subscription(**s) for s in response.get("items", response.get("data", []))]

    async def get_subscription_by_id(
        self: "GrowFlowBillingClient",
        subscription_id: str,
    ) -> Subscription:
        """Get subscription by ID.

        Args:
            subscription_id: Subscription ID

        Returns:
            Subscription object

        Raises:
            NotFoundError: If subscription not found
        """
        response = await self._request("GET", f"/subscriptions/{subscription_id}")
        return Subscription(**response)

    async def cancel_subscription(
        self: "GrowFlowBillingClient",
        subscription_id: str,
        at_period_end: bool = True,
    ) -> Subscription:
        """Cancel a subscription.

        Args:
            subscription_id: Subscription ID to cancel
            at_period_end: If True, cancel at end of billing period;
                          if False, cancel immediately

        Returns:
            Updated Subscription object

        Example:
            # Cancel at end of billing period
            sub = await client.cancel_subscription("sub_xxx", at_period_end=True)

            # Cancel immediately
            sub = await client.cancel_subscription("sub_xxx", at_period_end=False)
        """
        response = await self._request(
            "POST",
            f"/subscriptions/{subscription_id}/cancel",
            json={"cancel_at_period_end": at_period_end},
        )
        return Subscription(**response)

    async def change_plan(
        self: "GrowFlowBillingClient",
        subscription_id: str,
        new_plan_slug: str,
        prorate: bool = True,
    ) -> Subscription:
        """Change subscription plan (upgrade/downgrade).

        Args:
            subscription_id: Subscription ID
            new_plan_slug: Slug of the new plan
            prorate: Whether to prorate the change (default: True)

        Returns:
            Updated Subscription object

        Example:
            # Upgrade to pro plan
            sub = await client.change_plan("sub_xxx", "pro")
        """
        response = await self._request(
            "POST",
            f"/subscriptions/{subscription_id}/change-plan",
            json={"new_plan_slug": new_plan_slug, "prorate": prorate},
        )
        return Subscription(**response)

    async def resume_subscription(
        self: "GrowFlowBillingClient",
        subscription_id: str,
    ) -> Subscription:
        """Resume a paused or canceled subscription.

        Args:
            subscription_id: Subscription ID to resume

        Returns:
            Updated Subscription object
        """
        response = await self._request(
            "POST",
            f"/subscriptions/{subscription_id}/resume",
        )
        return Subscription(**response)

    async def reactivate_subscription(
        self: "GrowFlowBillingClient",
        subscription_id: str,
    ) -> Subscription:
        """Reactivate a canceled subscription (if still within reactivation window).

        Args:
            subscription_id: Subscription ID to reactivate

        Returns:
            Updated Subscription object with active status

        Raises:
            NotFoundError: If subscription not found
        """
        response = await self._request(
            "POST",
            f"/subscriptions/{subscription_id}/reactivate",
        )
        return Subscription(**response)
