"""TikTok-specific exception handling and error code mapping.

This module provides error handling for the TikTok API, including HTTP status
code mapping, TikTok-specific error codes, and user-friendly messages.
"""

from typing import Any

from src.marqetive.platforms.exceptions import (
    MediaUploadError,
    PlatformAuthError,
    PlatformError,
    PostNotFoundError,
    RateLimitError,
    ValidationError,
)


# TikTok API error codes (hypothetical, based on common API patterns)
# Source: TikTok Developer documentation (assumed)
class TikTokErrorCode:
    """TikTok API error codes."""

    # Authentication & Authorization
    INVALID_ACCESS_TOKEN = 10001
    ACCESS_TOKEN_EXPIRED = 10002
    SCOPE_NOT_AUTHORIZED = 10003
    AUTHENTICATION_FAILED = 10004
    ACCOUNT_NOT_AUTHORIZED = 10005

    # Rate Limiting
    RATE_LIMIT_EXCEEDED = 20001
    TOO_MANY_REQUESTS = 20002

    # Resource Not Found
    VIDEO_NOT_FOUND = 30001
    USER_NOT_FOUND = 30002
    COMMENT_NOT_FOUND = 30003

    # Validation Errors
    INVALID_PARAMETER = 40001
    VIDEO_TOO_LARGE = 40002
    VIDEO_DURATION_INVALID = 40003
    DESCRIPTION_TOO_LONG = 40004
    DUPLICATE_VIDEO = 40005
    INVALID_VIDEO_FORMAT = 40006

    # Media Upload & Processing
    UPLOAD_FAILED = 50001
    INIT_UPLOAD_FAILED = 50002
    APPEND_CHUNK_FAILED = 50003
    FINALIZE_UPLOAD_FAILED = 50004
    MEDIA_PROCESSING_FAILED = 50005


# Mapping of error codes to user-friendly messages
ERROR_MESSAGES: dict[int, str] = {
    # Authentication
    10001: "Invalid access token. Please re-authenticate.",
    10002: "Access token has expired. Please refresh the token.",
    10003: "The application is not authorized for the requested scope.",
    10004: "Authentication failed. Please check your credentials.",
    10005: "The user has not authorized this action for their account.",
    # Rate Limiting
    20001: "Rate limit exceeded. Please wait before making more requests.",
    20002: "Too many requests. You have hit a rate limit.",
    # Resource Not Found
    30001: "The requested video could not be found.",
    30002: "The specified user does not exist.",
    30003: "The specified comment could not be found.",
    # Validation
    40001: "Invalid parameter in request.",
    40002: "Video file size is too large.",
    40003: "Video duration is outside the allowed range.",
    40004: "Video description is too long.",
    40005: "This video appears to be a duplicate of a previous post.",
    40006: "Invalid video format. Please use a supported format like MP4 or MOV.",
    # Media
    50001: "Media upload failed.",
    50005: "Media processing failed after upload.",
}


def map_tiktok_error(
    status_code: int | None,
    error_code: int | None = None,
    error_message: str | None = None,
    response_data: dict[str, Any] | None = None,
) -> PlatformError:
    """Map TikTok API error to the appropriate exception class.

    Args:
        status_code: HTTP status code.
        error_code: TikTok-specific error code from the response body.
        error_message: Error message from the API.
        response_data: Full response data from the API.

    Returns:
        An appropriate subclass of PlatformError.
    """
    if response_data and "error" in response_data:
        error_data = response_data["error"]
        if not error_code:
            error_code = error_data.get("code")
        if not error_message:
            error_message = error_data.get("message")

    friendly_message = ERROR_MESSAGES.get(
        error_code or 0, error_message or "An unknown TikTok API error occurred"
    )

    # Map to exception types based on error code categories or status code
    if error_code in (10001, 10002, 10003, 10004, 10005) or status_code in (401, 403):
        return PlatformAuthError(
            friendly_message,
            platform="tiktok",
            status_code=status_code,
        )

    if error_code in (20001, 20002) or status_code == 429:
        retry_after = None
        if response_data and response_data.get("extra"):
            retry_after = response_data["extra"].get("log_id")  # Placeholder
        return RateLimitError(
            friendly_message,
            platform="tiktok",
            status_code=status_code or 429,
            retry_after=retry_after,
        )

    if error_code in (30001,):
        return PostNotFoundError(
            post_id="",  # TikTok might use a different identifier
            platform="tiktok",
            status_code=status_code,
            message=friendly_message,
        )

    if error_code in (40001, 40002, 40003, 40004, 40005, 40006):
        return ValidationError(
            friendly_message,
            platform="tiktok",
        )

    if error_code in (50001, 50002, 50003, 50004, 50005):
        return MediaUploadError(
            friendly_message,
            platform="tiktok",
            status_code=status_code,
        )

    # Generic platform error for everything else
    return PlatformError(
        friendly_message,
        platform="tiktok",
        status_code=status_code,
    )


class TikTokAPIError(PlatformError):
    """TikTok API specific error with detailed information."""

    def __init__(
        self,
        message: str,
        *,
        status_code: int | None = None,
        error_code: int | None = None,
        response_data: dict[str, Any] | None = None,
    ) -> None:
        super().__init__(message, platform="tiktok", status_code=status_code)
        self.error_code = error_code
        self.response_data = response_data

    def __repr__(self) -> str:
        return (
            f"TikTokAPIError(message={self.message!r}, "
            f"status_code={self.status_code}, "
            f"error_code={self.error_code})"
        )
