"""Invoices API endpoint mixin."""

from typing import TYPE_CHECKING

from growflow_billing.models.invoice import Invoice

if TYPE_CHECKING:
    from growflow_billing.client import GrowFlowBillingClient


class InvoicesMixin:
    """Mixin for invoice-related API calls."""

    async def get_invoices(
        self: "GrowFlowBillingClient",
        external_id: str,
        limit: int = 20,
    ) -> list[Invoice]:
        """Get invoices for a subscriber.

        Args:
            external_id: Subscriber's external ID
            limit: Max number of invoices (default: 20, max: 100)

        Returns:
            List of Invoice objects

        Example:
            invoices = await client.get_invoices("store_123", limit=10)
            for inv in invoices:
                print(f"{inv.number}: {inv.amount_paid_decimal} {inv.currency}")
                if inv.invoice_pdf:
                    print(f"  PDF: {inv.invoice_pdf}")
        """
        response = await self._request(
            "GET",
            "/invoices",
            params={
                "subscriber_external_id": external_id,
                "limit": min(limit, 100),
            },
        )

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

    async def get_invoice(
        self: "GrowFlowBillingClient",
        invoice_id: str,
    ) -> Invoice:
        """Get a specific invoice by ID.

        Args:
            invoice_id: Invoice ID (Stripe invoice ID)

        Returns:
            Invoice object

        Raises:
            NotFoundError: If invoice not found
        """
        response = await self._request("GET", f"/invoices/{invoice_id}")
        return Invoice(**response)

    async def get_upcoming_invoice(
        self: "GrowFlowBillingClient",
        external_id: str,
    ) -> Invoice | None:
        """Get upcoming invoice for a subscriber.

        This shows what the next invoice will look like.

        Args:
            external_id: Subscriber's external ID

        Returns:
            Invoice object or None if no upcoming invoice
        """
        try:
            response = await self._request(
                "GET",
                "/invoices/upcoming",
                params={"subscriber_external_id": external_id},
            )
            return Invoice(**response)
        except Exception:
            return None

    async def get_invoice_pdf_url(
        self: "GrowFlowBillingClient",
        invoice_id: str,
    ) -> str:
        """Get PDF download URL for an invoice.

        Args:
            invoice_id: Invoice ID

        Returns:
            URL string to download the invoice PDF

        Raises:
            NotFoundError: If invoice not found
        """
        response = await self._request("GET", f"/invoices/{invoice_id}/pdf")
        return response.get("pdf_url") or response.get("url", "")

    async def send_invoice(
        self: "GrowFlowBillingClient",
        invoice_id: str,
    ) -> bool:
        """Send invoice to customer via email.

        Args:
            invoice_id: Invoice ID

        Returns:
            True if invoice was sent successfully

        Raises:
            NotFoundError: If invoice not found
        """
        response = await self._request("POST", f"/invoices/{invoice_id}/send")
        return response.get("success") or response.get("sent") or True
