"""Plans domain exceptions with error codes."""

from identity_plan_kit.shared.exceptions import (
    AuthorizationError,
    NotFoundError,
    RateLimitError,
)


class PlanError(AuthorizationError):
    """Base exception for plan errors."""

    code = "PLAN_ERROR"
    message = "Plan error"


class PlanNotFoundError(NotFoundError):
    """Plan not found."""

    code = "PLAN_NOT_FOUND"
    message = "Plan not found"

    def __init__(self, plan_code: str | None = None) -> None:
        self.plan_code = plan_code
        msg = f"Plan not found: {plan_code}" if plan_code else "Plan not found"
        super().__init__(message=msg, details={"plan_code": plan_code} if plan_code else None)


class UserPlanNotFoundError(PlanError):
    """User has no active plan."""

    code = "USER_PLAN_NOT_FOUND"
    message = "No active plan"
    status_code = 402  # Payment Required


class PlanExpiredError(PlanError):
    """User's plan has expired."""

    code = "PLAN_EXPIRED"
    message = "Plan has expired"
    status_code = 402  # Payment Required


class FeatureNotFoundError(NotFoundError):
    """Feature does not exist."""

    code = "FEATURE_NOT_FOUND"
    message = "Feature not found"

    def __init__(self, feature_code: str | None = None) -> None:
        self.feature_code = feature_code
        msg = f"Feature not found: {feature_code}" if feature_code else "Feature not found"
        super().__init__(
            message=msg, details={"feature_code": feature_code} if feature_code else None
        )


class FeatureNotAvailableError(PlanError):
    """Feature not available in user's plan."""

    code = "FEATURE_NOT_AVAILABLE"
    message = "Feature not available"

    def __init__(
        self,
        feature_code: str | None = None,
        plan_code: str | None = None,
    ) -> None:
        self.feature_code = feature_code
        self.plan_code = plan_code
        msg = f"Feature '{feature_code}' not available"
        if plan_code:
            msg += f" in plan '{plan_code}'"
        super().__init__(
            message=msg,
            details={"feature_code": feature_code, "plan_code": plan_code},
        )


class QuotaExceededError(RateLimitError):
    """Usage quota exceeded."""

    code = "QUOTA_EXCEEDED"
    message = "Usage quota exceeded"

    def __init__(
        self,
        feature_code: str,
        limit: int,
        used: int,
        period: str | None = None,
    ) -> None:
        self.feature_code = feature_code
        self.limit = limit
        self.used = used
        self.period = period

        msg = f"Quota exceeded for '{feature_code}': {used}/{limit}"
        if period:
            msg += f" ({period})"
        super().__init__(
            message=msg,
            details={
                "feature_code": feature_code,
                "limit": limit,
                "used": used,
                "period": period,
                "remaining": limit - used,
            },
        )

    @property
    def remaining(self) -> int:
        """Get remaining quota (can be negative if over limit)."""
        return self.limit - self.used
