# app/routes/shop_pages.py
"""
Shop/Customer HTML page routes using Jinja2 templates.

These routes serve the public-facing shop interface for customers.
Authentication required only for account pages.

AUTHENTICATION:
- Public pages (catalog, products): No auth required
- Account pages (dashboard, orders): Requires customer authentication
- Customer authentication accepts:
  * customer_token cookie (path=/shop) - for page navigation
  * Authorization header - for API calls
- Customers CANNOT access admin or vendor routes

Routes (all mounted at /shop/* or /vendors/{code}/shop/* prefix):
- GET /                           → Shop homepage / product catalog
- GET /products                   → Product catalog
- GET /products/{id}              → Product detail page
- GET /categories/{slug}          → Category products
- GET /cart                       → Shopping cart
- GET /checkout                   → Checkout process
- GET /account/register           → Customer registration
- GET /account/login              → Customer login
- GET /account/dashboard          → Customer dashboard (auth required)
- GET /account/orders             → Order history (auth required)
- GET /account/orders/{id}        → Order detail (auth required)
- GET /account/profile            → Customer profile (auth required)
- GET /account/addresses          → Address management (auth required)
- GET /{slug}                     → Dynamic content pages (CMS): /about, /faq, /contact, etc.
"""

import logging

from fastapi import APIRouter, Depends, Path, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session

from app.api.deps import get_current_customer_from_cookie_or_header, get_db
from app.services.content_page_service import content_page_service
from models.database.customer import Customer

router = APIRouter()
templates = Jinja2Templates(directory="app/templates")

logger = logging.getLogger(__name__)


# ============================================================================
# HELPER: Build Shop Template Context
# ============================================================================


def get_shop_context(request: Request, db: Session = None, **extra_context) -> dict:
    """
    Build template context for shop pages.

    Automatically includes vendor and theme from middleware request.state.
    Additional context can be passed as keyword arguments.

    Args:
        request: FastAPI request object with vendor/theme in state
        db: Optional database session for loading navigation pages
        **extra_context: Additional variables for template (user, product_id, etc.)

    Returns:
        Dictionary with request, vendor, theme, navigation pages, and extra context

    Example:
        # Simple usage
        get_shop_context(request)

        # With database session for navigation
        get_shop_context(request, db=db)

        # With extra data
        get_shop_context(request, db=db, user=current_user, product_id=123)
    """
    # Extract from middleware state
    vendor = getattr(request.state, "vendor", None)
    theme = getattr(request.state, "theme", None)
    clean_path = getattr(request.state, "clean_path", request.url.path)
    vendor_context = getattr(request.state, "vendor_context", None)

    # Get detection method from vendor_context
    access_method = (
        vendor_context.get("detection_method", "unknown")
        if vendor_context
        else "unknown"
    )

    if vendor is None:
        logger.warning(
            "[SHOP_CONTEXT] Vendor not found in request.state",
            extra={
                "path": request.url.path,
                "host": request.headers.get("host", ""),
                "has_vendor": False,
            },
        )

    # Calculate base URL for links
    # - Domain/subdomain access: base_url = "/"
    # - Path-based access: base_url = "/vendor/{vendor_code}/" or "/vendors/{vendor_code}/"
    base_url = "/"
    if access_method == "path" and vendor:
        # Use the full_prefix from vendor_context to determine which pattern was used
        full_prefix = (
            vendor_context.get("full_prefix", "/vendor/")
            if vendor_context
            else "/vendor/"
        )
        base_url = f"{full_prefix}{vendor.subdomain}/"

    # Load footer navigation pages from CMS if db session provided
    footer_pages = []
    header_pages = []
    if db and vendor:
        try:
            vendor_id = vendor.id
            # Get pages configured to show in footer
            footer_pages = content_page_service.list_pages_for_vendor(
                db, vendor_id=vendor_id, footer_only=True, include_unpublished=False
            )
            # Get pages configured to show in header
            header_pages = content_page_service.list_pages_for_vendor(
                db, vendor_id=vendor_id, header_only=True, include_unpublished=False
            )
        except Exception as e:
            logger.error(
                "[SHOP_CONTEXT] Failed to load navigation pages",
                extra={"error": str(e), "vendor_id": vendor.id if vendor else None},
            )

    context = {
        "request": request,
        "vendor": vendor,
        "theme": theme,
        "clean_path": clean_path,
        "access_method": access_method,
        "base_url": base_url,
        "footer_pages": footer_pages,
        "header_pages": header_pages,
    }

    # Add any extra context (user, product_id, category_slug, etc.)
    if extra_context:
        context.update(extra_context)

    logger.debug(
        "[SHOP_CONTEXT] Context built",
        extra={
            "vendor_id": vendor.id if vendor else None,
            "vendor_name": vendor.name if vendor else None,
            "vendor_subdomain": vendor.subdomain if vendor else None,
            "has_theme": theme is not None,
            "access_method": access_method,
            "base_url": base_url,
            "footer_pages_count": len(footer_pages),
            "header_pages_count": len(header_pages),
            "extra_keys": list(extra_context.keys()) if extra_context else [],
        },
    )

    return context


# ============================================================================
# PUBLIC SHOP ROUTES (No Authentication Required)
# ============================================================================


@router.get("/", response_class=HTMLResponse, include_in_schema=False)
@router.get("/products", response_class=HTMLResponse, include_in_schema=False)
async def shop_products_page(request: Request, db: Session = Depends(get_db)):
    """
    Render shop homepage / product catalog.
    Shows featured products and categories.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/products.html", get_shop_context(request, db=db)
    )


@router.get(
    "/products/{product_id}", response_class=HTMLResponse, include_in_schema=False
)
async def shop_product_detail_page(
    request: Request, product_id: int = Path(..., description="Product ID")
):
    """
    Render product detail page.
    Shows product information, images, reviews, and buy options.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/product.html", get_shop_context(request, product_id=product_id)
    )


@router.get(
    "/categories/{category_slug}", response_class=HTMLResponse, include_in_schema=False
)
async def shop_category_page(
    request: Request, category_slug: str = Path(..., description="Category slug")
):
    """
    Render category products page.
    Shows all products in a specific category.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/category.html", get_shop_context(request, category_slug=category_slug)
    )


@router.get("/cart", response_class=HTMLResponse, include_in_schema=False)
async def shop_cart_page(request: Request):
    """
    Render shopping cart page.
    Shows cart items and allows quantity updates.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse("shop/cart.html", get_shop_context(request))


@router.get("/checkout", response_class=HTMLResponse, include_in_schema=False)
async def shop_checkout_page(request: Request):
    """
    Render checkout page.
    Handles shipping, payment, and order confirmation.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse("shop/checkout.html", get_shop_context(request))


@router.get("/search", response_class=HTMLResponse, include_in_schema=False)
async def shop_search_page(request: Request):
    """
    Render search results page.
    Shows products matching search query.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse("shop/search.html", get_shop_context(request))


# ============================================================================
# CUSTOMER ACCOUNT - PUBLIC ROUTES (No Authentication)
# ============================================================================


@router.get("/account/register", response_class=HTMLResponse, include_in_schema=False)
async def shop_register_page(request: Request):
    """
    Render customer registration page.
    No authentication required.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/register.html", get_shop_context(request)
    )


@router.get("/account/login", response_class=HTMLResponse, include_in_schema=False)
async def shop_login_page(request: Request):
    """
    Render customer login page.
    No authentication required.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/login.html", get_shop_context(request)
    )


@router.get(
    "/account/forgot-password", response_class=HTMLResponse, include_in_schema=False
)
async def shop_forgot_password_page(request: Request):
    """
    Render forgot password page.
    Allows customers to reset their password.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/forgot-password.html", get_shop_context(request)
    )


# ============================================================================
# CUSTOMER ACCOUNT - AUTHENTICATED ROUTES
# ============================================================================


@router.get("/account", response_class=RedirectResponse, include_in_schema=False)
@router.get("/account/", response_class=RedirectResponse, include_in_schema=False)
async def shop_account_root(request: Request):
    """
    Redirect /shop/account or /shop/account/ to dashboard.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    # Get base_url from context for proper redirect
    vendor = getattr(request.state, "vendor", None)
    vendor_context = getattr(request.state, "vendor_context", None)
    access_method = (
        vendor_context.get("detection_method", "unknown")
        if vendor_context
        else "unknown"
    )

    base_url = "/"
    if access_method == "path" and vendor:
        full_prefix = (
            vendor_context.get("full_prefix", "/vendor/")
            if vendor_context
            else "/vendor/"
        )
        base_url = f"{full_prefix}{vendor.subdomain}/"

    return RedirectResponse(url=f"{base_url}shop/account/dashboard", status_code=302)


@router.get("/account/dashboard", response_class=HTMLResponse, include_in_schema=False)
async def shop_account_dashboard_page(
    request: Request,
    current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
    db: Session = Depends(get_db),
):
    """
    Render customer account dashboard.
    Shows account overview, recent orders, and quick links.
    Requires customer authentication.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/dashboard.html", get_shop_context(request, user=current_customer)
    )


@router.get("/account/orders", response_class=HTMLResponse, include_in_schema=False)
async def shop_orders_page(
    request: Request,
    current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
    db: Session = Depends(get_db),
):
    """
    Render customer orders history page.
    Shows all past and current orders.
    Requires customer authentication.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/orders.html", get_shop_context(request, user=current_customer)
    )


@router.get(
    "/account/orders/{order_id}", response_class=HTMLResponse, include_in_schema=False
)
async def shop_order_detail_page(
    request: Request,
    order_id: int = Path(..., description="Order ID"),
    current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
    db: Session = Depends(get_db),
):
    """
    Render customer order detail page.
    Shows detailed order information and tracking.
    Requires customer authentication.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/order-detail.html",
        get_shop_context(request, user=current_customer, order_id=order_id),
    )


@router.get("/account/profile", response_class=HTMLResponse, include_in_schema=False)
async def shop_profile_page(
    request: Request,
    current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
    db: Session = Depends(get_db),
):
    """
    Render customer profile page.
    Edit personal information and preferences.
    Requires customer authentication.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/profile.html", get_shop_context(request, user=current_customer)
    )


@router.get("/account/addresses", response_class=HTMLResponse, include_in_schema=False)
async def shop_addresses_page(
    request: Request,
    current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
    db: Session = Depends(get_db),
):
    """
    Render customer addresses management page.
    Manage shipping and billing addresses.
    Requires customer authentication.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/addresses.html", get_shop_context(request, user=current_customer)
    )


@router.get("/account/wishlist", response_class=HTMLResponse, include_in_schema=False)
async def shop_wishlist_page(
    request: Request,
    current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
    db: Session = Depends(get_db),
):
    """
    Render customer wishlist page.
    View and manage saved products.
    Requires customer authentication.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/wishlist.html", get_shop_context(request, user=current_customer)
    )


@router.get("/account/settings", response_class=HTMLResponse, include_in_schema=False)
async def shop_settings_page(
    request: Request,
    current_customer: Customer = Depends(get_current_customer_from_cookie_or_header),
    db: Session = Depends(get_db),
):
    """
    Render customer account settings page.
    Configure notifications, privacy, and preferences.
    Requires customer authentication.
    """
    logger.debug(
        "[SHOP_HANDLER] shop_products_page REACHED",
        extra={
            "path": request.url.path,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    return templates.TemplateResponse(
        "shop/account/settings.html", get_shop_context(request, user=current_customer)
    )


# ============================================================================
# DYNAMIC CONTENT PAGES (CMS)
# ============================================================================


@router.get("/{slug}", response_class=HTMLResponse, include_in_schema=False)
async def generic_content_page(
    request: Request,
    slug: str = Path(..., description="Content page slug"),
    db: Session = Depends(get_db),
):
    """
    Generic content page handler (CMS).

    Handles dynamic content pages like:
    - /about, /faq, /contact, /shipping, /returns, /privacy, /terms, etc.

    Features:
    - Two-tier system: Vendor overrides take priority, fallback to platform defaults
    - Only shows published pages
    - Returns 404 if page not found

    This route MUST be defined last in the router to avoid conflicts with
    specific routes (like /products, /cart, /account, etc.)
    """
    from fastapi import HTTPException

    logger.debug(
        "[SHOP_HANDLER] generic_content_page REACHED",
        extra={
            "path": request.url.path,
            "slug": slug,
            "vendor": getattr(request.state, "vendor", "NOT SET"),
            "context": getattr(request.state, "context_type", "NOT SET"),
        },
    )

    vendor = getattr(request.state, "vendor", None)
    vendor_id = vendor.id if vendor else None

    # Load content page from database (vendor override → platform default)
    page = content_page_service.get_page_for_vendor(
        db, slug=slug, vendor_id=vendor_id, include_unpublished=False
    )

    if not page:
        logger.warning(
            "[SHOP_HANDLER] Content page not found",
            extra={
                "slug": slug,
                "vendor_id": vendor_id,
                "vendor_name": vendor.name if vendor else None,
            },
        )
        raise HTTPException(status_code=404, detail=f"Page not found: {slug}")

    logger.info(
        "[SHOP_HANDLER] Content page found",
        extra={
            "slug": slug,
            "page_id": page.id,
            "page_title": page.title,
            "is_vendor_override": page.vendor_id is not None,
            "vendor_id": vendor_id,
        },
    )

    return templates.TemplateResponse(
        "shop/content-page.html", get_shop_context(request, page=page)
    )


# ============================================================================
# DEBUG ENDPOINTS - For troubleshooting context issues
# ============================================================================


@router.get("/debug/context", response_class=HTMLResponse, include_in_schema=False)
async def debug_context(request: Request):
    """
    DEBUG ENDPOINT: Display request context.

    Shows what's available in request.state.
    Useful for troubleshooting template variable issues.

    URL: /shop/debug/context
    """
    vendor = getattr(request.state, "vendor", None)
    theme = getattr(request.state, "theme", None)

    debug_info = {
        "path": request.url.path,
        "host": request.headers.get("host", ""),
        "vendor": {
            "found": vendor is not None,
            "id": vendor.id if vendor else None,
            "name": vendor.name if vendor else None,
            "subdomain": vendor.subdomain if vendor else None,
            "is_active": vendor.is_active if vendor else None,
        },
        "theme": {
            "found": theme is not None,
            "name": theme.get("theme_name") if theme else None,
        },
        "clean_path": getattr(request.state, "clean_path", "NOT SET"),
        "context_type": str(getattr(request.state, "context_type", "NOT SET")),
    }

    # Return as JSON-like HTML for easy reading
    import json

    html_content = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Debug Context</title>
        <style>
            body {{ font-family: monospace; margin: 20px; }}
            pre {{ background: #f0f0f0; padding: 20px; border-radius: 5px; }}
            .good {{ color: green; }}
            .bad {{ color: red; }}
        </style>
    </head>
    <body>
        <h1>Request Context Debug</h1>
        <pre>{json.dumps(debug_info, indent=2)}</pre>

        <h2>Status</h2>
        <p class="{"good" if vendor else "bad"}">
            Vendor: {"✓ Found" if vendor else "✗ Not Found"}
        </p>
        <p class="{"good" if theme else "bad"}">
            Theme: {"✓ Found" if theme else "✗ Not Found"}
        </p>
        <p class="{"good" if str(getattr(request.state, "context_type", "NOT SET")) == "shop" else "bad"}">
            Context Type: {str(getattr(request.state, "context_type", "NOT SET"))}
        </p>
    </body>
    </html>
    """
    return HTMLResponse(content=html_content)
