# app/modules/core/routes/api/merchant_menu.py
"""
Merchant menu rendering endpoint.

Provides the dynamic sidebar menu for the merchant portal:
- GET /menu/render/merchant - Get rendered merchant menu for current user

Menu sections are grouped by platform:
- Core items (dashboard, billing, account) appear at root level
- Platform-specific items are grouped under their platform name
- No AdminMenuConfig visibility filtering — menu is purely driven by
  module definitions + module enablement + subscription status
"""

import logging
from typing import Any

from fastapi import APIRouter, Depends, Request
from pydantic import BaseModel
from sqlalchemy.orm import Session

from app.api.deps import get_current_merchant_from_cookie_or_header, get_db
from app.modules.core.services.menu_service import menu_service
from app.modules.enums import FrontendType
from app.modules.tenancy.schemas.auth import UserContext
from app.utils.i18n import translate

logger = logging.getLogger(__name__)

merchant_menu_router = APIRouter(prefix="/menu")


# =============================================================================
# Schemas
# =============================================================================


class MenuSectionResponse(BaseModel):
    """Menu section for rendering."""

    id: str
    label: str | None = None
    icon: str | None = None
    platform_code: str | None = None
    is_collapsible: bool = False
    items: list[dict[str, Any]]


class RenderedMenuResponse(BaseModel):
    """Rendered menu for frontend."""

    frontend_type: str
    sections: list[MenuSectionResponse]


# =============================================================================
# Helpers
# =============================================================================


def _translate_label(label_key: str | None, language: str) -> str | None:
    """Translate a label key, falling back to a readable version of the key."""
    if not label_key:
        return None

    translated = translate(label_key, language=language)

    # If translation returned the key itself, create a readable fallback
    if translated == label_key:
        parts = label_key.split(".")
        last_part = parts[-1]
        return last_part.replace("_", " ").title()

    return translated


# =============================================================================
# Endpoint
# =============================================================================


@merchant_menu_router.get("/render/merchant", response_model=RenderedMenuResponse)
async def get_rendered_merchant_menu(
    request: Request,
    db: Session = Depends(get_db),
    current_user: UserContext = Depends(get_current_merchant_from_cookie_or_header),
):
    """
    Get the rendered merchant menu for the current user.

    Returns a platform-grouped menu structure:
    - Core sections (dashboard, billing, account) at root level
    - Platform-specific sections grouped under platform name

    Menu visibility is driven by module definitions + module enablement
    + subscription status. No AdminMenuConfig filtering.
    """
    # Resolve the merchant for this user (via service layer)
    merchant = menu_service.get_merchant_for_menu(db, current_user.id)

    if not merchant:
        # No merchant found — return empty menu
        return RenderedMenuResponse(
            frontend_type=FrontendType.MERCHANT.value,
            sections=[],
        )

    # Get platform-grouped menu
    core_sections, platform_sections = menu_service.get_merchant_menu_by_platform(
        db, merchant.id
    )

    # Resolve language
    language = current_user.preferred_language or getattr(
        request.state, "language", "en"
    )

    # Build response sections
    all_sections = []

    # Core sections first (translated labels)
    for section in core_sections:
        translated_items = []
        for item in section.items:
            if not item.is_module_enabled:
                continue
            translated_items.append(
                {
                    "id": item.id,
                    "label": _translate_label(item.label_key, language),
                    "icon": item.icon,
                    "url": item.route,
                }
            )

        if translated_items:
            all_sections.append(
                MenuSectionResponse(
                    id=section.id,
                    label=_translate_label(section.label_key, language),
                    icon=section.icon,
                    is_collapsible=section.is_collapsible,
                    items=translated_items,
                )
            )

    # Platform sections (platform name as label, collapsible)
    for section in platform_sections:
        translated_items = []
        for item in section.items:
            if not item.is_module_enabled:
                continue
            translated_items.append(
                {
                    "id": item.id,
                    "label": _translate_label(item.label_key, language),
                    "icon": item.icon,
                    "url": item.route,
                }
            )

        if translated_items:
            # Extract platform_code from section id (format: "platform-{code}")
            platform_code = section.id.removeprefix("platform-")
            all_sections.append(
                MenuSectionResponse(
                    id=section.id,
                    label=section.label_key,  # Already platform name, not a translation key
                    icon=section.icon,
                    platform_code=platform_code,
                    is_collapsible=True,
                    items=translated_items,
                )
            )

    # Sort order: 1) Dashboard (main), 2) Platform sections, 3) Billing, 4) Account
    # Core sections use their definition order; platform sections slot in between
    # main=0, platform=25, billing=50, account=900
    def _section_sort_key(s):
        if s.platform_code:
            return 25, s.id
        # Map known core section IDs to their display order
        core_order = {"main": 0, "billing": 50, "account": 900}
        return core_order.get(s.id, 500), s.id

    all_sections.sort(key=_section_sort_key)

    return RenderedMenuResponse(
        frontend_type=FrontendType.MERCHANT.value,
        sections=all_sections,
    )
