"""Custom exceptions for integrations."""


class IntegrationError(Exception):
    """Base exception for all integration errors."""

    pass


# =============================================================================
# GitHub Exceptions
# =============================================================================


class GitHubError(IntegrationError):
    """Base exception for GitHub integration errors."""

    pass


class GitHubAPIError(GitHubError):
    """Error communicating with GitHub API."""

    def __init__(self, message: str, status_code: int | None = None) -> None:
        super().__init__(message)
        self.status_code = status_code


class GitHubAuthError(GitHubError):
    """GitHub authentication or authorization error."""

    pass


class GitHubRateLimitError(GitHubError):
    """GitHub rate limit exceeded."""

    def __init__(self, message: str, retry_after: int | None = None) -> None:
        super().__init__(message)
        self.retry_after = retry_after


# =============================================================================
# LinkedIn Exceptions
# =============================================================================


class LinkedInError(IntegrationError):
    """Base exception for LinkedIn integration errors."""

    pass


class LinkedInAPIError(LinkedInError):
    """Error communicating with LinkedIn API."""

    def __init__(
        self,
        message: str,
        status_code: int | None = None,
        error_code: str | None = None,
    ) -> None:
        super().__init__(message)
        self.status_code = status_code
        self.error_code = error_code


class LinkedInAuthError(LinkedInError):
    """LinkedIn authentication or authorization error.

    Raised when OAuth flow fails or when API returns 401/403.
    """

    def __init__(
        self,
        message: str,
        error_code: str | None = None,
        error_description: str | None = None,
    ) -> None:
        super().__init__(message)
        self.error_code = error_code
        self.error_description = error_description


class LinkedInRateLimitError(LinkedInError):
    """LinkedIn rate limit exceeded (429 response).

    Attributes:
        retry_after: Seconds to wait before retrying, if provided by API.
    """

    def __init__(self, message: str, retry_after: int | None = None) -> None:
        super().__init__(message)
        self.retry_after = retry_after


class LinkedInTokenExpiredError(LinkedInAuthError):
    """LinkedIn access token has expired.

    This is a specific auth error that indicates the token needs to be refreshed
    or the user needs to re-authenticate.
    """

    def __init__(self, message: str = "LinkedIn access token has expired") -> None:
        super().__init__(message, error_code="EXPIRED_TOKEN")


class LinkedInInvalidStateError(LinkedInAuthError):
    """Invalid or expired OAuth state parameter.

    Raised when the state parameter in OAuth callback doesn't match
    the expected value, which could indicate a CSRF attack or expired session.
    """

    def __init__(self, message: str = "Invalid or expired OAuth state") -> None:
        super().__init__(message, error_code="INVALID_STATE")


class LinkedInSyncError(LinkedInError):
    """Error during LinkedIn sync operation."""

    def __init__(
        self,
        message: str,
        page_id: str | None = None,
        recoverable: bool = True,
    ) -> None:
        super().__init__(message)
        self.page_id = page_id
        self.recoverable = recoverable
