"""
Consistent API response helpers.
Provides standardized response formats for all API endpoints.
"""

from typing import Any, Dict, List, Optional

from flask import Response, jsonify
from marshmallow import ValidationError


def success_response(
    data: Any = None, message: Optional[str] = None, status_code: int = 200, meta: Optional[Dict[str, Any]] = None
) -> Response:
    """
    Create a successful API response.

    Args:
        data: Response data
        message: Optional success message
        status_code: HTTP status code
        meta: Optional metadata

    Returns:
        Flask JSON response
    """
    response = {
        "success": True,
    }

    if message:
        response["message"] = message

    if data is not None:
        response["data"] = data

    if meta:
        response["meta"] = meta

    return jsonify(response), status_code


def error_response(
    message: str,
    error_code: Optional[str] = None,
    status_code: int = 400,
    errors: Optional[Dict[str, List[str]]] = None,
    details: Optional[Dict[str, Any]] = None,
) -> Response:
    """
    Create an error API response.

    Args:
        message: Error message
        error_code: Optional error code
        status_code: HTTP status code
        errors: Optional field-specific errors
        details: Optional additional error details

    Returns:
        Flask JSON response
    """
    # error = user-facing message (backward compat); error_code = machine-readable
    response = {
        "success": False,
        "error": message,
        "message": message,
        "error_code": error_code or "error",
    }

    if errors:
        response["errors"] = errors

    if details:
        response["details"] = details

    return jsonify(response), status_code


def validation_error_response(errors: Dict[str, List[str]], message: str = "Validation failed") -> Response:
    """
    Create a validation error response.

    Args:
        errors: Field-specific validation errors
        message: Error message

    Returns:
        Flask JSON response
    """
    return error_response(message=message, error_code="validation_error", status_code=400, errors=errors)


def not_found_response(resource: str = "Resource", resource_id: Optional[Any] = None) -> Response:
    """
    Create a not found error response.

    Args:
        resource: Resource type name
        resource_id: Optional resource ID

    Returns:
        Flask JSON response
    """
    message = f"{resource} not found"
    if resource_id is not None:
        message = f"{resource} with ID {resource_id} not found"

    return error_response(message=message, error_code="not_found", status_code=404)


def unauthorized_response(message: str = "Authentication required") -> Response:
    """
    Create an unauthorized error response.

    Args:
        message: Error message

    Returns:
        Flask JSON response
    """
    return error_response(message=message, error_code="unauthorized", status_code=401)


def forbidden_response(message: str = "Insufficient permissions") -> Response:
    """
    Create a forbidden error response.

    Args:
        message: Error message

    Returns:
        Flask JSON response
    """
    return error_response(message=message, error_code="forbidden", status_code=403)


def paginated_response(
    items: List[Any], page: int, per_page: int, total: int, message: Optional[str] = None
) -> Response:
    """
    Create a paginated response.

    Args:
        items: List of items for current page
        page: Current page number
        per_page: Items per page
        total: Total number of items
        message: Optional message

    Returns:
        Flask JSON response
    """
    pages = (total + per_page - 1) // per_page if total > 0 else 0

    pagination = {
        "page": page,
        "per_page": per_page,
        "total": total,
        "pages": pages,
        "has_next": page < pages,
        "has_prev": page > 1,
        "next_page": page + 1 if page < pages else None,
        "prev_page": page - 1 if page > 1 else None,
    }

    return success_response(data=items, message=message, meta={"pagination": pagination})


def handle_validation_error(error: ValidationError) -> Response:
    """
    Handle Marshmallow validation errors.

    Args:
        error: ValidationError instance

    Returns:
        Flask JSON response
    """
    errors = {}
    if isinstance(error.messages, dict):
        errors = error.messages
    elif isinstance(error.messages, list):
        errors = {"_general": error.messages}

    return validation_error_response(errors=errors)


def created_response(data: Any, message: Optional[str] = None, location: Optional[str] = None) -> Response:
    """
    Create a 201 Created response.

    Args:
        data: Created resource data
        message: Optional success message
        location: Optional resource location URL

    Returns:
        Flask JSON response
    """
    response_data = {"success": True, "data": data}
    if message:
        response_data["message"] = message

    response = jsonify(response_data)
    response.status_code = 201

    if location:
        response.headers["Location"] = location

    return response


def no_content_response() -> Response:
    """
    Create a 204 No Content response.

    Returns:
        Flask response
    """
    return "", 204
