# app/modules/cms/routes/api/admin_store_themes.py
"""
Store theme management endpoints for admin.

These endpoints allow admins to:
- View store themes
- Apply theme presets
- Customize theme settings
- Reset themes to default

All operations use the service layer for business logic.
All exceptions are handled by the global exception handler.
"""

import logging

from fastapi import APIRouter, Depends, Path
from sqlalchemy.orm import Session

from app.api.deps import get_current_admin_api, get_db
from app.modules.cms.schemas.store_theme import (
    StoreThemeResponse,
    StoreThemeUpdate,
    ThemeDeleteResponse,
    ThemePresetListResponse,
    ThemePresetResponse,
)
from app.modules.cms.services.store_theme_service import store_theme_service
from app.modules.tenancy.schemas.auth import UserContext

admin_store_themes_router = APIRouter(prefix="/store-themes")
logger = logging.getLogger(__name__)


# ============================================================================
# PRESET ENDPOINTS
# ============================================================================


@admin_store_themes_router.get("/presets", response_model=ThemePresetListResponse)
async def get_theme_presets(current_admin: UserContext = Depends(get_current_admin_api)):
    """
    Get all available theme presets with preview information.

    Returns list of presets that can be applied to store themes.
    Each preset includes color palette, fonts, and layout configuration.

    **Permissions:** Admin only

    **Returns:**
    - List of available theme presets with preview data
    """
    logger.info("Getting theme presets")

    presets = store_theme_service.get_available_presets()
    return ThemePresetListResponse(presets=presets)


# ============================================================================
# THEME RETRIEVAL
# ============================================================================


@admin_store_themes_router.get("/{store_code}", response_model=StoreThemeResponse)
async def get_store_theme(
    store_code: str = Path(..., description="Store code"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get theme configuration for a store.

    Returns the store's custom theme if exists, otherwise returns default theme.

    **Path Parameters:**
    - `store_code`: Store code (e.g., STORE001)

    **Permissions:** Admin only

    **Returns:**
    - Complete theme configuration including colors, fonts, layout, and branding

    **Errors:**
    - `404`: Store not found (StoreNotFoundException)
    """
    logger.info(f"Getting theme for store: {store_code}")

    # Service raises StoreNotFoundException if store not found
    # Global exception handler converts it to HTTP 404
    theme = store_theme_service.get_theme(db, store_code)
    return theme


# ============================================================================
# THEME UPDATE
# ============================================================================


@admin_store_themes_router.put("/{store_code}", response_model=StoreThemeResponse)
async def update_store_theme(
    store_code: str = Path(..., description="Store code"),
    theme_data: StoreThemeUpdate = None,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Update or create theme for a store.

    Accepts partial updates - only provided fields are updated.
    If store has no theme, a new one is created.

    **Path Parameters:**
    - `store_code`: Store code (e.g., STORE001)

    **Request Body:**
    - `theme_name`: Optional theme name
    - `colors`: Optional color palette (primary, secondary, accent, etc.)
    - `fonts`: Optional font settings (heading, body)
    - `layout`: Optional layout settings (style, header, product_card)
    - `branding`: Optional branding assets (logo, favicon, etc.)
    - `custom_css`: Optional custom CSS rules
    - `social_links`: Optional social media links

    **Permissions:** Admin only

    **Returns:**
    - Updated theme configuration

    **Errors:**
    - `404`: Store not found (StoreNotFoundException)
    - `422`: Validation error (ThemeValidationException, InvalidColorFormatException, etc.)
    - `500`: Operation failed (ThemeOperationException)
    """
    logger.info(f"Updating theme for store: {store_code}")

    # Service handles all validation and raises appropriate exceptions
    # Global exception handler converts them to proper HTTP responses
    theme = store_theme_service.update_theme(db, store_code, theme_data)
    db.commit()
    return StoreThemeResponse(**theme.to_dict())


# ============================================================================
# PRESET APPLICATION
# ============================================================================


@admin_store_themes_router.post("/{store_code}/preset/{preset_name}", response_model=ThemePresetResponse)
async def apply_theme_preset(
    store_code: str = Path(..., description="Store code"),
    preset_name: str = Path(..., description="Preset name"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Apply a theme preset to a store.

    Replaces the store's current theme with the selected preset.
    Available presets can be retrieved from the `/presets` endpoint.

    **Path Parameters:**
    - `store_code`: Store code (e.g., STORE001)
    - `preset_name`: Name of preset to apply (e.g., 'modern', 'classic')

    **Available Presets:**
    - `default`: Clean and professional
    - `modern`: Contemporary tech-inspired
    - `classic`: Traditional and trustworthy
    - `minimal`: Ultra-clean black and white
    - `vibrant`: Bold and energetic
    - `elegant`: Sophisticated gray tones
    - `nature`: Fresh and eco-friendly

    **Permissions:** Admin only

    **Returns:**
    - Success message and applied theme configuration

    **Errors:**
    - `404`: Store not found (StoreNotFoundException) or preset not found (ThemePresetNotFoundException)
    - `500`: Operation failed (ThemeOperationException)
    """
    logger.info(f"Applying preset '{preset_name}' to store {store_code}")

    # Service validates preset name and applies it
    # Raises ThemePresetNotFoundException if preset doesn't exist
    # Global exception handler converts to HTTP 404
    theme = store_theme_service.apply_theme_preset(db, store_code, preset_name)
    db.commit()

    return ThemePresetResponse(
        message=f"Applied {preset_name} preset successfully",
        theme=StoreThemeResponse(**theme.to_dict()),
    )


# ============================================================================
# THEME DELETION
# ============================================================================


@admin_store_themes_router.delete("/{store_code}", response_model=ThemeDeleteResponse)
async def delete_store_theme(
    store_code: str = Path(..., description="Store code"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Delete custom theme for a store.

    Removes the store's custom theme. After deletion, the store
    will revert to using the default platform theme.

    **Path Parameters:**
    - `store_code`: Store code (e.g., STORE001)

    **Permissions:** Admin only

    **Returns:**
    - Success message

    **Errors:**
    - `404`: Store not found (StoreNotFoundException) or no custom theme (StoreThemeNotFoundException)
    - `500`: Operation failed (ThemeOperationException)
    """
    logger.info(f"Deleting theme for store: {store_code}")

    # Service handles deletion and raises exceptions if needed
    # Global exception handler converts them to proper HTTP responses
    result = store_theme_service.delete_theme(db, store_code)
    db.commit()
    return ThemeDeleteResponse(
        message=result.get("message", "Theme deleted successfully")
    )
