# app/modules/marketplace/routes/api/platform.py
"""
Platform Letzshop store lookup API endpoints.

Allows potential stores to find themselves in the Letzshop marketplace
and claim their shop during signup.

All endpoints are unauthenticated (no authentication required).
"""

import logging
import re
from typing import Annotated

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

from app.core.database import get_db
from app.exceptions import ResourceNotFoundException
from app.modules.marketplace.models import LetzshopStoreCache
from app.modules.marketplace.services.letzshop import LetzshopStoreSyncService

router = APIRouter(prefix="/letzshop-stores")
logger = logging.getLogger(__name__)


# =============================================================================
# Response Schemas
# =============================================================================


class LetzshopStoreInfo(BaseModel):
    """Letzshop store information for display."""

    letzshop_id: str | None = None
    slug: str
    name: str
    merchant_name: str | None = None
    description: str | None = None
    email: str | None = None
    phone: str | None = None
    website: str | None = None
    address: str | None = None
    city: str | None = None
    categories: list[str] = []
    background_image_url: str | None = None
    social_media_links: list[str] = []
    letzshop_url: str
    is_claimed: bool = False

    @classmethod
    def from_cache(cls, cache: LetzshopStoreCache, lang: str = "en") -> "LetzshopStoreInfo":
        """Create from cache entry."""
        return cls(
            letzshop_id=cache.letzshop_id,
            slug=cache.slug,
            name=cache.name,
            merchant_name=cache.merchant_name,
            description=cache.get_description(lang),
            email=cache.email,
            phone=cache.phone,
            website=cache.website,
            address=cache.get_full_address(),
            city=cache.city,
            categories=cache.categories or [],
            background_image_url=cache.background_image_url,
            social_media_links=cache.social_media_links or [],
            letzshop_url=cache.letzshop_url,
            is_claimed=cache.is_claimed,
        )


class LetzshopStoreListResponse(BaseModel):
    """Paginated list of Letzshop stores."""

    stores: list[LetzshopStoreInfo]
    total: int
    page: int
    limit: int
    has_more: bool


class LetzshopLookupRequest(BaseModel):
    """Request to lookup a Letzshop store by URL."""

    url: str  # e.g., https://letzshop.lu/vendors/my-shop or just "my-shop"


class LetzshopLookupResponse(BaseModel):
    """Response from Letzshop store lookup."""

    found: bool
    store: LetzshopStoreInfo | None = None
    error: str | None = None


# =============================================================================
# Helper Functions
# =============================================================================


def extract_slug_from_url(url_or_slug: str) -> str:
    """
    Extract store slug from Letzshop URL or return as-is if already a slug.

    Handles:
    - https://letzshop.lu/vendors/my-shop
    - https://letzshop.lu/en/stores/my-shop
    - letzshop.lu/vendors/my-shop
    - my-shop
    """
    # Clean up the input
    url_or_slug = url_or_slug.strip()

    # If it looks like a URL, extract the slug
    if "letzshop" in url_or_slug.lower() or "/" in url_or_slug:
        # Remove protocol if present
        url_or_slug = re.sub(r"^https?://", "", url_or_slug)

        # Match pattern like letzshop.lu/[lang/]stores/SLUG[/...]
        match = re.search(r"letzshop\.lu/(?:[a-z]{2}/)?stores?/([^/?#]+)", url_or_slug, re.IGNORECASE)
        if match:
            return match.group(1).lower()

        # If just a path like stores/my-shop
        match = re.search(r"stores?/([^/?#]+)", url_or_slug)
        if match:
            return match.group(1).lower()

    # Return as-is (assume it's already a slug)
    return url_or_slug.lower()


# =============================================================================
# Endpoints
# =============================================================================


@router.get("", response_model=LetzshopStoreListResponse)  # public
async def list_letzshop_stores(
    search: Annotated[str | None, Query(description="Search by name")] = None,
    category: Annotated[str | None, Query(description="Filter by category")] = None,
    city: Annotated[str | None, Query(description="Filter by city")] = None,
    only_unclaimed: Annotated[bool, Query(description="Only show unclaimed stores")] = False,
    lang: Annotated[str, Query(description="Language for descriptions")] = "en",
    page: Annotated[int, Query(ge=1)] = 1,
    limit: Annotated[int, Query(ge=1, le=50)] = 20,
    db: Session = Depends(get_db),
) -> LetzshopStoreListResponse:
    """
    List Letzshop stores from cached directory.

    The cache is periodically synced from Letzshop's public GraphQL API.
    Run the sync task manually or wait for scheduled sync if cache is empty.
    """
    sync_service = LetzshopStoreSyncService(db)

    stores, total = sync_service.search_cached_stores(
        search=search,
        city=city,
        category=category,
        only_unclaimed=only_unclaimed,
        page=page,
        limit=limit,
    )

    return LetzshopStoreListResponse(
        stores=[LetzshopStoreInfo.from_cache(v, lang) for v in stores],
        total=total,
        page=page,
        limit=limit,
        has_more=(page * limit) < total,
    )


@router.post("/lookup", response_model=LetzshopLookupResponse)  # public
async def lookup_letzshop_store(
    request: LetzshopLookupRequest,
    lang: Annotated[str, Query(description="Language for descriptions")] = "en",
    db: Session = Depends(get_db),
) -> LetzshopLookupResponse:
    """
    Lookup a Letzshop store by URL or slug.

    This endpoint:
    1. Extracts the slug from the provided URL
    2. Looks up store in local cache (or fetches from Letzshop if not cached)
    3. Checks if the store is already claimed on our platform
    4. Returns store info for signup pre-fill
    """
    try:
        slug = extract_slug_from_url(request.url)

        if not slug:
            return LetzshopLookupResponse(
                found=False,
                error="Could not extract store slug from URL",
            )

        sync_service = LetzshopStoreSyncService(db)

        # First try cache
        cache_entry = sync_service.get_cached_store(slug)

        # If not in cache, try to fetch from Letzshop
        if not cache_entry:
            logger.info(f"Store {slug} not in cache, fetching from Letzshop...")
            cache_entry = sync_service.sync_single_store(slug)

        if not cache_entry:
            return LetzshopLookupResponse(
                found=False,
                error="Store not found on Letzshop",
            )

        return LetzshopLookupResponse(
            found=True,
            store=LetzshopStoreInfo.from_cache(cache_entry, lang),
        )

    except Exception as e:
        logger.error(f"Error looking up Letzshop store: {e}")
        return LetzshopLookupResponse(
            found=False,
            error="Failed to lookup store",
        )


@router.get("/stats")  # public
async def get_letzshop_store_stats(
    db: Session = Depends(get_db),
) -> dict:
    """
    Get statistics about the Letzshop store cache.

    Returns total, active, claimed, and unclaimed store counts.
    """
    sync_service = LetzshopStoreSyncService(db)
    return sync_service.get_sync_stats()


@router.get("/{slug}", response_model=LetzshopStoreInfo)  # public
async def get_letzshop_store(
    slug: str,
    lang: Annotated[str, Query(description="Language for descriptions")] = "en",
    db: Session = Depends(get_db),
) -> LetzshopStoreInfo:
    """
    Get a specific Letzshop store by slug.

    Returns 404 if store not found in cache or on Letzshop.
    """
    slug = slug.lower()

    sync_service = LetzshopStoreSyncService(db)

    # First try cache
    cache_entry = sync_service.get_cached_store(slug)

    # If not in cache, try to fetch from Letzshop
    if not cache_entry:
        logger.info(f"Store {slug} not in cache, fetching from Letzshop...")
        cache_entry = sync_service.sync_single_store(slug)

    if not cache_entry:
        raise ResourceNotFoundException("LetzshopStore", slug)

    return LetzshopStoreInfo.from_cache(cache_entry, lang)
