# app/modules/tenancy/routes/api/admin_stores.py
"""
Store management endpoints for admin.

Architecture Notes:
- All business logic is in store_service (no direct DB operations here)
- Uses domain exceptions from app/exceptions/store.py
- Exception handler middleware converts domain exceptions to HTTP responses
"""

import logging

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

from app.api.deps import get_current_admin_api
from app.core.database import get_db
from app.modules.tenancy.exceptions import ConfirmationRequiredException
from app.modules.tenancy.schemas.auth import UserContext
from app.modules.tenancy.schemas.store import (
    StoreCreate,
    StoreCreateResponse,
    StoreDetailResponse,
    StoreListResponse,
    StoreStatsResponse,
    StoreUpdate,
)
from app.modules.tenancy.services.admin_service import admin_service
from app.modules.tenancy.services.store_service import store_service

admin_stores_router = APIRouter(prefix="/stores")
logger = logging.getLogger(__name__)


@admin_stores_router.post("", response_model=StoreCreateResponse)
def create_store(
    store_data: StoreCreate,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Create a new store (storefront/brand) under an existing merchant (Admin only).

    This endpoint:
    1. Validates that the parent merchant exists
    2. Creates a new store record linked to the merchant
    3. Sets up default roles (Owner, Manager, Editor, Viewer)

    The store inherits owner and contact information from its parent merchant.
    """
    store = admin_service.create_store(db=db, store_data=store_data)
    db.commit()

    return StoreCreateResponse(
        # Store fields
        id=store.id,
        store_code=store.store_code,
        subdomain=store.subdomain,
        name=store.name,
        description=store.description,
        merchant_id=store.merchant_id,
        letzshop_csv_url_fr=store.letzshop_csv_url_fr,
        letzshop_csv_url_en=store.letzshop_csv_url_en,
        letzshop_csv_url_de=store.letzshop_csv_url_de,
        is_active=store.is_active,
        is_verified=store.is_verified,
        created_at=store.created_at,
        updated_at=store.updated_at,
        # Merchant info
        merchant_name=store.merchant.name,
        merchant_contact_email=store.merchant.contact_email,
        merchant_contact_phone=store.merchant.contact_phone,
        merchant_website=store.merchant.website,
        # Owner info (from merchant)
        owner_user_id=store.merchant.owner.id,
        owner_email=store.merchant.owner.email,
        owner_username=store.merchant.owner.username,
        login_url=f"http://localhost:8000/store/{store.subdomain}/login",
    )


@admin_stores_router.get("", response_model=StoreListResponse)
def get_all_stores_admin(
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    search: str | None = Query(None, description="Search by name or store code"),
    is_active: bool | None = Query(None),
    is_verified: bool | None = Query(None),
    merchant_id: int | None = Query(None, description="Filter by merchant ID"),
    include_deleted: bool = Query(False, description="Include soft-deleted stores"),
    only_deleted: bool = Query(False, description="Show only soft-deleted stores (trash view)"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Get all stores with filtering (Admin only)."""
    stores, total = admin_service.get_all_stores(
        db=db,
        skip=skip,
        limit=limit,
        search=search,
        is_active=is_active,
        is_verified=is_verified,
        merchant_id=merchant_id,
        include_deleted=include_deleted,
        only_deleted=only_deleted,
    )
    return StoreListResponse(stores=stores, total=total, skip=skip, limit=limit)


@admin_stores_router.get("/stats", response_model=StoreStatsResponse)
def get_store_statistics_endpoint(
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Get store statistics for admin dashboard (Admin only)."""
    stats = admin_service.get_store_statistics(db)

    return StoreStatsResponse(
        total=stats["total"],
        verified=stats["verified"],
        pending=stats["pending"],
        inactive=stats["inactive"],
    )


def _build_store_detail_response(store) -> StoreDetailResponse:
    """
    Helper to build StoreDetailResponse with resolved contact info.

    Contact fields are resolved using store override or merchant fallback.
    Inheritance flags indicate if value comes from merchant.
    """
    contact_info = store.get_contact_info_with_inheritance()

    return StoreDetailResponse(
        # Store fields
        id=store.id,
        store_code=store.store_code,
        subdomain=store.subdomain,
        name=store.name,
        description=store.description,
        merchant_id=store.merchant_id,
        letzshop_csv_url_fr=store.letzshop_csv_url_fr,
        letzshop_csv_url_en=store.letzshop_csv_url_en,
        letzshop_csv_url_de=store.letzshop_csv_url_de,
        is_active=store.is_active,
        is_verified=store.is_verified,
        created_at=store.created_at,
        updated_at=store.updated_at,
        # Merchant info
        merchant_name=store.merchant.name,
        # Owner details (from merchant)
        owner_user_id=store.merchant.owner_user_id,
        owner_email=store.merchant.owner.email,
        owner_username=store.merchant.owner.username,
        # Resolved contact info with inheritance flags
        **contact_info,
        # Original merchant values for UI reference
        merchant_contact_email=store.merchant.contact_email,
        merchant_contact_phone=store.merchant.contact_phone,
        merchant_website=store.merchant.website,
        merchant_business_address=store.merchant.business_address,
        merchant_tax_number=store.merchant.tax_number,
    )


@admin_stores_router.get("/{store_identifier}", response_model=StoreDetailResponse)
def get_store_details(
    store_identifier: str = Path(..., description="Store ID or store_code"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get detailed store information including merchant and owner details (Admin only).

    Accepts either store ID (integer) or store_code (string).

    Returns store info with merchant contact details, owner info, and
    resolved contact fields (store override or merchant default).

    Raises:
        StoreNotFoundException: If store not found (404)
    """
    store = store_service.get_store_by_identifier(db, store_identifier)
    return _build_store_detail_response(store)


@admin_stores_router.put("/{store_identifier}", response_model=StoreDetailResponse)
def update_store(
    store_identifier: str = Path(..., description="Store ID or store_code"),
    store_update: StoreUpdate = Body(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Update store information (Admin only).

    Accepts either store ID (integer) or store_code (string).

    **Can update:**
    - Basic info: name, description, subdomain
    - Marketplace URLs
    - Status: is_active, is_verified
    - Contact info: contact_email, contact_phone, website, business_address, tax_number
      (these override merchant defaults; set to empty to reset to inherit)

    **Cannot update:**
    - `store_code` (immutable)

    Raises:
        StoreNotFoundException: If store not found (404)
    """
    store = store_service.get_store_by_identifier(db, store_identifier)
    store = admin_service.update_store(db, store.id, store_update)
    db.commit()
    return _build_store_detail_response(store)


# NOTE: Ownership transfer is handled at the Merchant level.
# Use PUT /api/v1/admin/merchants/{id}/transfer-ownership instead.


@admin_stores_router.put("/{store_identifier}/verification", response_model=StoreDetailResponse)
def toggle_store_verification(
    store_identifier: str = Path(..., description="Store ID or store_code"),
    verification_data: dict = Body(..., example={"is_verified": True}),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Set store verification status (Admin only).

    Accepts either store ID (integer) or store_code (string).

    Request body: { "is_verified": true/false }

    Raises:
        StoreNotFoundException: If store not found (404)
    """
    store = store_service.get_store_by_identifier(db, store_identifier)

    if "is_verified" in verification_data:
        store, message = store_service.set_verification(
            db, store.id, verification_data["is_verified"]
        )
        db.commit()  # ✅ ARCH: Commit at API level for transaction control
        logger.info(f"Store verification updated: {message}")

    return _build_store_detail_response(store)


@admin_stores_router.put("/{store_identifier}/status", response_model=StoreDetailResponse)
def toggle_store_status(
    store_identifier: str = Path(..., description="Store ID or store_code"),
    status_data: dict = Body(..., example={"is_active": True}),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Set store active status (Admin only).

    Accepts either store ID (integer) or store_code (string).

    Request body: { "is_active": true/false }

    Raises:
        StoreNotFoundException: If store not found (404)
    """
    store = store_service.get_store_by_identifier(db, store_identifier)

    if "is_active" in status_data:
        store, message = store_service.set_status(
            db, store.id, status_data["is_active"]
        )
        db.commit()  # ✅ ARCH: Commit at API level for transaction control
        logger.info(f"Store status updated: {message}")

    return _build_store_detail_response(store)


@admin_stores_router.delete("/{store_identifier}")
def delete_store(
    store_identifier: str = Path(..., description="Store ID or store_code"),
    confirm: bool = Query(False, description="Must be true to confirm deletion"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Delete store and all associated data (Admin only).

    Accepts either store ID (integer) or store_code (string).

    ⚠️ **WARNING: This is destructive and will delete:**
    - Store account
    - All products
    - All orders
    - All customers
    - All team members

    Requires confirmation parameter: `confirm=true`

    Raises:
        ConfirmationRequiredException: If confirm=true not provided (400)
        StoreNotFoundException: If store not found (404)
    """
    if not confirm:
        raise ConfirmationRequiredException(
            operation="delete_store",
            message="Deletion requires confirmation parameter: confirm=true",
        )

    store = store_service.get_store_by_identifier(db, store_identifier)
    message = admin_service.delete_store(db, store.id)
    db.commit()
    return {"message": message}


@admin_stores_router.put("/{store_id}/restore")
def restore_store(
    store_id: int,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Restore a soft-deleted store (Admin only).

    This only restores the store record itself.
    Child records (products, customers, etc.) must be restored separately.
    """
    from app.core.soft_delete import restore
    from app.modules.tenancy.models import Store

    restored = restore(db, Store, store_id, restored_by_id=current_admin.id)
    db.commit()
    logger.info(f"Store {store_id} restored by admin {current_admin.username}")
    return {"message": f"Store '{restored.name}' restored successfully", "store_id": store_id}
