# app/modules/marketplace/routes/api/admin_letzshop.py
"""
Admin API endpoints for Letzshop marketplace integration.

Provides admin-level management of:
- Per-store Letzshop credentials
- Connection testing
- Sync triggers and status
- Order overview

All routes require module access control for the 'marketplace' module.
"""

import logging

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

from app.api.deps import get_current_admin_api, require_module_access
from app.core.database import get_db
from app.exceptions import ResourceNotFoundException, ValidationException
from app.modules.enums import FrontendType
from app.modules.marketplace.schemas import (
    FulfillmentOperationResponse,
    LetzshopCachedStoreDetail,
    LetzshopCachedStoreDetailResponse,
    LetzshopCachedStoreItem,
    LetzshopCachedStoreListResponse,
    LetzshopConnectionTestRequest,
    LetzshopConnectionTestResponse,
    LetzshopCreateStoreFromCacheResponse,
    LetzshopCredentialsCreate,
    LetzshopCredentialsResponse,
    LetzshopCredentialsUpdate,
    LetzshopExportRequest,
    LetzshopExportResponse,
    LetzshopHistoricalImportJobResponse,
    LetzshopHistoricalImportStartResponse,
    LetzshopJobItem,
    LetzshopJobsListResponse,
    LetzshopOrderDetailResponse,
    LetzshopOrderItemResponse,
    LetzshopOrderListResponse,
    LetzshopOrderResponse,
    LetzshopOrderStats,
    LetzshopStoreDirectoryStats,
    LetzshopStoreDirectoryStatsResponse,
    LetzshopStoreListResponse,
    LetzshopStoreOverview,
    LetzshopSuccessResponse,
    LetzshopSyncTriggerRequest,
    LetzshopSyncTriggerResponse,
)
from app.modules.marketplace.services.letzshop import (
    CredentialsNotFoundError,
    LetzshopClientError,
    LetzshopCredentialsService,
    LetzshopOrderService,
    LetzshopStoreSyncService,
    OrderNotFoundError,
    StoreNotFoundError,
)
from app.modules.orders.exceptions import OrderHasUnresolvedExceptionsException
from app.modules.orders.services.order_item_exception_service import (
    order_item_exception_service,
)
from app.modules.tenancy.schemas.auth import UserContext

admin_letzshop_router = APIRouter(
    prefix="/letzshop",
    dependencies=[Depends(require_module_access("marketplace", FrontendType.ADMIN))],
)
logger = logging.getLogger(__name__)


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


def get_order_service(db: Session) -> LetzshopOrderService:
    """Get order service instance."""
    return LetzshopOrderService(db)


def get_credentials_service(db: Session) -> LetzshopCredentialsService:
    """Get credentials service instance."""
    return LetzshopCredentialsService(db)


# ============================================================================
# Store Overview
# ============================================================================


@admin_letzshop_router.get("/stores", response_model=LetzshopStoreListResponse)
def list_stores_letzshop_status(
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    configured_only: bool = Query(
        False, description="Only show stores with Letzshop configured"
    ),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    List all stores with their Letzshop integration status.

    Shows which stores have Letzshop configured, sync status, and pending orders.
    """
    order_service = get_order_service(db)
    store_overviews, total = order_service.list_stores_with_letzshop_status(
        skip=skip,
        limit=limit,
        configured_only=configured_only,
    )

    return LetzshopStoreListResponse(
        stores=[LetzshopStoreOverview(**v) for v in store_overviews],
        total=total,
        skip=skip,
        limit=limit,
    )


# ============================================================================
# Credentials Management
# ============================================================================


@admin_letzshop_router.get(
    "/stores/{store_id}/credentials",
    response_model=LetzshopCredentialsResponse,
)
def get_store_credentials(
    store_id: int = Path(..., description="Store ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Get Letzshop credentials for a store (API key is masked)."""
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        store = order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    try:
        credentials = creds_service.get_credentials_or_raise(store_id)
    except CredentialsNotFoundError:
        raise ResourceNotFoundException(
            "LetzshopCredentials",
            str(store_id),
            message=f"Letzshop credentials not configured for store {store.name}",
        )

    return LetzshopCredentialsResponse(
        id=credentials.id,
        store_id=credentials.store_id,
        api_key_masked=creds_service.get_masked_api_key(store_id),
        api_endpoint=credentials.api_endpoint,
        auto_sync_enabled=credentials.auto_sync_enabled,
        sync_interval_minutes=credentials.sync_interval_minutes,
        last_sync_at=credentials.last_sync_at,
        last_sync_status=credentials.last_sync_status,
        last_sync_error=credentials.last_sync_error,
        created_at=credentials.created_at,
        updated_at=credentials.updated_at,
    )


@admin_letzshop_router.post(
    "/stores/{store_id}/credentials",
    response_model=LetzshopCredentialsResponse,
)
def create_or_update_store_credentials(
    store_id: int = Path(..., description="Store ID"),
    credentials_data: LetzshopCredentialsCreate = ...,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Create or update Letzshop credentials for a store."""
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        store = order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    credentials = creds_service.upsert_credentials(
        store_id=store_id,
        api_key=credentials_data.api_key,
        api_endpoint=credentials_data.api_endpoint,
        auto_sync_enabled=credentials_data.auto_sync_enabled,
        sync_interval_minutes=credentials_data.sync_interval_minutes,
    )
    db.commit()

    logger.info(
        f"Admin {current_admin.email} updated Letzshop credentials for store {store.name}"
    )

    return LetzshopCredentialsResponse(
        id=credentials.id,
        store_id=credentials.store_id,
        api_key_masked=creds_service.get_masked_api_key(store_id),
        api_endpoint=credentials.api_endpoint,
        auto_sync_enabled=credentials.auto_sync_enabled,
        sync_interval_minutes=credentials.sync_interval_minutes,
        last_sync_at=credentials.last_sync_at,
        last_sync_status=credentials.last_sync_status,
        last_sync_error=credentials.last_sync_error,
        created_at=credentials.created_at,
        updated_at=credentials.updated_at,
    )


@admin_letzshop_router.patch(
    "/stores/{store_id}/credentials",
    response_model=LetzshopCredentialsResponse,
)
def update_store_credentials(
    store_id: int = Path(..., description="Store ID"),
    credentials_data: LetzshopCredentialsUpdate = ...,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Partially update Letzshop credentials for a store."""
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        store = order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    try:
        credentials = creds_service.update_credentials(
            store_id=store_id,
            api_key=credentials_data.api_key,
            api_endpoint=credentials_data.api_endpoint,
            auto_sync_enabled=credentials_data.auto_sync_enabled,
            sync_interval_minutes=credentials_data.sync_interval_minutes,
        )
        db.commit()
    except CredentialsNotFoundError:
        raise ResourceNotFoundException(
            "LetzshopCredentials",
            str(store_id),
            message=f"Letzshop credentials not configured for store {store.name}",
        )

    return LetzshopCredentialsResponse(
        id=credentials.id,
        store_id=credentials.store_id,
        api_key_masked=creds_service.get_masked_api_key(store_id),
        api_endpoint=credentials.api_endpoint,
        auto_sync_enabled=credentials.auto_sync_enabled,
        sync_interval_minutes=credentials.sync_interval_minutes,
        last_sync_at=credentials.last_sync_at,
        last_sync_status=credentials.last_sync_status,
        last_sync_error=credentials.last_sync_error,
        created_at=credentials.created_at,
        updated_at=credentials.updated_at,
    )


@admin_letzshop_router.delete(
    "/stores/{store_id}/credentials",
    response_model=LetzshopSuccessResponse,
)
def delete_store_credentials(
    store_id: int = Path(..., description="Store ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Delete Letzshop credentials for a store."""
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        store = order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    deleted = creds_service.delete_credentials(store_id)
    if not deleted:
        raise ResourceNotFoundException(
            "LetzshopCredentials",
            str(store_id),
            message=f"Letzshop credentials not configured for store {store.name}",
        )
    db.commit()

    logger.info(
        f"Admin {current_admin.email} deleted Letzshop credentials for store {store.name}"
    )

    return LetzshopSuccessResponse(success=True, message="Letzshop credentials deleted")


# ============================================================================
# Connection Testing
# ============================================================================


@admin_letzshop_router.post(
    "/stores/{store_id}/test",
    response_model=LetzshopConnectionTestResponse,
)
def test_store_connection(
    store_id: int = Path(..., description="Store ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Test the Letzshop connection for a store using stored credentials."""
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    success, response_time_ms, error = creds_service.test_connection(store_id)

    return LetzshopConnectionTestResponse(
        success=success,
        message="Connection successful" if success else "Connection failed",
        response_time_ms=response_time_ms,
        error_details=error,
    )


@admin_letzshop_router.post("/test", response_model=LetzshopConnectionTestResponse)
def test_api_key(
    test_request: LetzshopConnectionTestRequest,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Test a Letzshop API key without saving it."""
    creds_service = get_credentials_service(db)

    success, response_time_ms, error = creds_service.test_api_key(
        api_key=test_request.api_key,
        api_endpoint=test_request.api_endpoint,
    )

    return LetzshopConnectionTestResponse(
        success=success,
        message="Connection successful" if success else "Connection failed",
        response_time_ms=response_time_ms,
        error_details=error,
    )


# ============================================================================
# Order Management
# ============================================================================


@admin_letzshop_router.get(
    "/orders",
    response_model=LetzshopOrderListResponse,
)
def list_all_letzshop_orders(
    store_id: int | None = Query(None, description="Filter by store"),
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=200),
    status: str | None = Query(None, description="Filter by order status"),
    has_declined_items: bool | None = Query(
        None, description="Filter orders with declined/unavailable items"
    ),
    search: str | None = Query(
        None, description="Search by order number, customer name, or email"
    ),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    List Letzshop orders across all stores (or for a specific store).

    When store_id is not provided, returns orders from all stores.
    """
    order_service = get_order_service(db)

    orders, total = order_service.list_orders(
        store_id=store_id,
        skip=skip,
        limit=limit,
        status=status,
        has_declined_items=has_declined_items,
        search=search,
    )

    # Get order stats (cross-store or store-specific)
    stats = order_service.get_order_stats(store_id)

    return LetzshopOrderListResponse(
        orders=[
            LetzshopOrderResponse(
                id=order.id,
                store_id=order.store_id,
                store_name=order.store.name if order.store else None,
                order_number=order.order_number,
                external_order_id=order.external_order_id,
                external_shipment_id=order.external_shipment_id,
                external_order_number=order.external_order_number,
                status=order.status,
                customer_email=order.customer_email,
                customer_name=order.customer_full_name,
                customer_locale=order.customer_locale,
                ship_country_iso=order.ship_country_iso,
                bill_country_iso=order.bill_country_iso,
                total_amount=order.total_amount,
                currency=order.currency,
                tracking_number=order.tracking_number,
                tracking_provider=order.tracking_provider,
                order_date=order.order_date,
                confirmed_at=order.confirmed_at,
                shipped_at=order.shipped_at,
                cancelled_at=order.cancelled_at,
                created_at=order.created_at,
                updated_at=order.updated_at,
                items=[
                    LetzshopOrderItemResponse(
                        id=item.id,
                        product_id=item.product_id,
                        product_name=item.product_name,
                        product_sku=item.product_sku,
                        gtin=item.gtin,
                        gtin_type=item.gtin_type,
                        quantity=item.quantity,
                        unit_price=item.unit_price,
                        total_price=item.total_price,
                        external_item_id=item.external_item_id,
                        external_variant_id=item.external_variant_id,
                        item_state=item.item_state,
                    )
                    for item in order.items
                ],
            )
            for order in orders
        ],
        total=total,
        skip=skip,
        limit=limit,
        stats=LetzshopOrderStats(**stats),
    )


@admin_letzshop_router.get(
    "/stores/{store_id}/orders",
    response_model=LetzshopOrderListResponse,
)
def list_store_letzshop_orders(
    store_id: int = Path(..., description="Store ID"),
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=200),
    status: str | None = Query(None, description="Filter by order status"),
    has_declined_items: bool | None = Query(
        None, description="Filter orders with declined/unavailable items"
    ),
    search: str | None = Query(
        None, description="Search by order number, customer name, or email"
    ),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """List Letzshop orders for a store."""
    order_service = get_order_service(db)

    try:
        order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    orders, total = order_service.list_orders(
        store_id=store_id,
        skip=skip,
        limit=limit,
        status=status,
        has_declined_items=has_declined_items,
        search=search,
    )

    # Get order stats for all statuses
    stats = order_service.get_order_stats(store_id)

    return LetzshopOrderListResponse(
        orders=[
            LetzshopOrderResponse(
                id=order.id,
                store_id=order.store_id,
                order_number=order.order_number,
                external_order_id=order.external_order_id,
                external_shipment_id=order.external_shipment_id,
                external_order_number=order.external_order_number,
                status=order.status,
                customer_email=order.customer_email,
                customer_name=order.customer_full_name,
                customer_locale=order.customer_locale,
                ship_country_iso=order.ship_country_iso,
                bill_country_iso=order.bill_country_iso,
                total_amount=order.total_amount,
                currency=order.currency,
                tracking_number=order.tracking_number,
                tracking_provider=order.tracking_provider,
                order_date=order.order_date,
                confirmed_at=order.confirmed_at,
                shipped_at=order.shipped_at,
                cancelled_at=order.cancelled_at,
                created_at=order.created_at,
                updated_at=order.updated_at,
                items=[
                    LetzshopOrderItemResponse(
                        id=item.id,
                        product_id=item.product_id,
                        product_name=item.product_name,
                        product_sku=item.product_sku,
                        gtin=item.gtin,
                        gtin_type=item.gtin_type,
                        quantity=item.quantity,
                        unit_price=item.unit_price,
                        total_price=item.total_price,
                        external_item_id=item.external_item_id,
                        external_variant_id=item.external_variant_id,
                        item_state=item.item_state,
                    )
                    for item in order.items
                ],
            )
            for order in orders
        ],
        total=total,
        skip=skip,
        limit=limit,
        stats=LetzshopOrderStats(**stats),
    )


@admin_letzshop_router.get(
    "/orders/{order_id}",
    response_model=LetzshopOrderDetailResponse,
)
def get_letzshop_order_detail(
    order_id: int = Path(..., description="Letzshop order ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Get detailed information for a single Letzshop order."""
    order_service = get_order_service(db)

    order = order_service.get_order_by_id(order_id)
    if not order:
        raise ResourceNotFoundException("Order", str(order_id))

    return LetzshopOrderDetailResponse(
        id=order.id,
        store_id=order.store_id,
        order_number=order.order_number,
        external_order_id=order.external_order_id,
        external_shipment_id=order.external_shipment_id,
        external_order_number=order.external_order_number,
        status=order.status,
        customer_email=order.customer_email,
        customer_name=order.customer_full_name,
        customer_locale=order.customer_locale,
        customer_first_name=order.customer_first_name,
        customer_last_name=order.customer_last_name,
        customer_phone=order.customer_phone,
        ship_country_iso=order.ship_country_iso,
        ship_first_name=order.ship_first_name,
        ship_last_name=order.ship_last_name,
        ship_company=order.ship_company,
        ship_address_line_1=order.ship_address_line_1,
        ship_address_line_2=order.ship_address_line_2,
        ship_city=order.ship_city,
        ship_postal_code=order.ship_postal_code,
        bill_country_iso=order.bill_country_iso,
        bill_first_name=order.bill_first_name,
        bill_last_name=order.bill_last_name,
        bill_company=order.bill_company,
        bill_address_line_1=order.bill_address_line_1,
        bill_address_line_2=order.bill_address_line_2,
        bill_city=order.bill_city,
        bill_postal_code=order.bill_postal_code,
        total_amount=order.total_amount,
        currency=order.currency,
        tracking_number=order.tracking_number,
        tracking_provider=order.tracking_provider,
        order_date=order.order_date,
        confirmed_at=order.confirmed_at,
        shipped_at=order.shipped_at,
        cancelled_at=order.cancelled_at,
        created_at=order.created_at,
        updated_at=order.updated_at,
        external_data=order.external_data,
        customer_notes=order.customer_notes,
        internal_notes=order.internal_notes,
        items=[
            LetzshopOrderItemResponse(
                id=item.id,
                product_id=item.product_id,
                product_name=item.product_name,
                product_sku=item.product_sku,
                gtin=item.gtin,
                gtin_type=item.gtin_type,
                quantity=item.quantity,
                unit_price=item.unit_price,
                total_price=item.total_price,
                external_item_id=item.external_item_id,
                external_variant_id=item.external_variant_id,
                item_state=item.item_state,
            )
            for item in order.items
        ],
    )


@admin_letzshop_router.post(
    "/stores/{store_id}/sync",
    response_model=LetzshopSyncTriggerResponse,
)
def trigger_store_sync(
    store_id: int = Path(..., description="Store ID"),
    sync_request: LetzshopSyncTriggerRequest = LetzshopSyncTriggerRequest(),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Trigger a sync operation for a store.

    This imports new orders from Letzshop.
    """
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        store = order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    # Verify credentials exist
    try:
        creds_service.get_credentials_or_raise(store_id)
    except CredentialsNotFoundError:
        raise ValidationException(
            f"Letzshop credentials not configured for store {store.name}"
        )

    # Import orders using the client
    try:
        with creds_service.create_client(store_id) as client:
            shipments = client.get_unconfirmed_shipments()
            logger.info(
                f"Letzshop sync for store {store_id}: "
                f"fetched {len(shipments)} unconfirmed shipments from API"
            )

            orders_imported = 0
            orders_updated = 0
            errors = []

            for shipment in shipments:
                try:
                    # Check if order already exists
                    existing = order_service.get_order_by_shipment_id(
                        store_id, shipment["id"]
                    )

                    if existing:
                        # Update existing order
                        order_service.update_order_from_shipment(existing, shipment)
                        orders_updated += 1
                    else:
                        # Create new order
                        order_service.create_order(store_id, shipment)
                        orders_imported += 1

                except Exception as e:
                    errors.append(
                        f"Error processing shipment {shipment.get('id')}: {e}"
                    )

            db.commit()

            # Update sync status
            creds_service.update_sync_status(
                store_id,
                "success" if not errors else "partial",
                "; ".join(errors) if errors else None,
            )

            return LetzshopSyncTriggerResponse(
                success=True,
                message=f"Sync completed: {orders_imported} imported, {orders_updated} updated",
                orders_imported=orders_imported,
                orders_updated=orders_updated,
                errors=errors,
            )

    except LetzshopClientError as e:
        creds_service.update_sync_status(store_id, "failed", str(e))
        return LetzshopSyncTriggerResponse(
            success=False,
            message=f"Sync failed: {e}",
            errors=[str(e)],
        )


# ============================================================================
# Jobs (Unified view of imports, exports, and syncs)
# ============================================================================


@admin_letzshop_router.get(
    "/jobs",
    response_model=LetzshopJobsListResponse,
)
def list_all_letzshop_jobs(
    job_type: str | None = Query(None, description="Filter: import, export, order_sync, historical_import"),
    status: str | None = Query(None, description="Filter by status"),
    skip: int = Query(0, ge=0),
    limit: int = Query(20, ge=1, le=100),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get unified list of all Letzshop-related jobs across all stores.
    Combines product imports, exports, and order syncs.
    """
    order_service = get_order_service(db)

    jobs_data, total = order_service.list_letzshop_jobs(
        store_id=None,
        job_type=job_type,
        status=status,
        skip=skip,
        limit=limit,
    )

    jobs = [LetzshopJobItem(**job) for job in jobs_data]

    return LetzshopJobsListResponse(jobs=jobs, total=total)


@admin_letzshop_router.get(
    "/stores/{store_id}/jobs",
    response_model=LetzshopJobsListResponse,
)
def list_store_letzshop_jobs(
    store_id: int = Path(..., description="Store ID"),
    job_type: str | None = Query(None, description="Filter: import, export, order_sync"),
    status: str | None = Query(None, description="Filter by status"),
    skip: int = Query(0, ge=0),
    limit: int = Query(20, ge=1, le=100),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get unified list of Letzshop-related jobs for a store.
    Combines product imports, exports, and order syncs.
    """
    order_service = get_order_service(db)

    try:
        order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    # Use service layer for database queries
    jobs_data, total = order_service.list_letzshop_jobs(
        store_id=store_id,
        job_type=job_type,
        status=status,
        skip=skip,
        limit=limit,
    )

    # Convert dict data to Pydantic models
    jobs = [LetzshopJobItem(**job) for job in jobs_data]

    return LetzshopJobsListResponse(jobs=jobs, total=total)


# ============================================================================
# Historical Import
# ============================================================================


@admin_letzshop_router.post(
    "/stores/{store_id}/import-history",
    response_model=LetzshopHistoricalImportStartResponse,
)
def start_historical_import(
    store_id: int = Path(..., description="Store ID"),
    background_tasks: BackgroundTasks = None,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Start historical order import from Letzshop as a background job.

    Creates a job that imports both confirmed and declined orders with
    real-time progress tracking. Poll the status endpoint to track progress.

    Returns a job_id for polling the status endpoint.
    """
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        store = order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    # Verify credentials exist
    try:
        creds_service.get_credentials_or_raise(store_id)
    except CredentialsNotFoundError:
        raise ValidationException(
            f"Letzshop credentials not configured for store {store.name}"
        )

    # Check if there's already a running import for this store
    existing_job = order_service.get_running_historical_import_job(store_id)
    if existing_job:
        raise ValidationException(
            f"Historical import already in progress (job_id={existing_job.id})"
        )

    # Create job record
    job = order_service.create_historical_import_job(store_id, current_admin.id)

    logger.info(f"Created historical import job {job.id} for store {store_id}")

    # Dispatch via task dispatcher (supports Celery or BackgroundTasks)
    from app.tasks.dispatcher import task_dispatcher

    celery_task_id = task_dispatcher.dispatch_historical_import(
        background_tasks=background_tasks,
        job_id=job.id,
        store_id=store_id,
    )

    # Store Celery task ID if using Celery
    if celery_task_id:
        job.celery_task_id = celery_task_id
        db.commit()

    return LetzshopHistoricalImportStartResponse(
        job_id=job.id,
        status="pending",
        message="Historical import job started",
    )


@admin_letzshop_router.get(
    "/stores/{store_id}/import-history/{job_id}/status",
    response_model=LetzshopHistoricalImportJobResponse,
)
def get_historical_import_status(
    store_id: int = Path(..., description="Store ID"),
    job_id: int = Path(..., description="Import job ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get status of a historical import job.

    Poll this endpoint to track import progress. Returns current phase,
    page being fetched, and counts of processed/imported/updated orders.
    """
    order_service = get_order_service(db)
    job = order_service.get_historical_import_job_by_id(store_id, job_id)

    if not job:
        raise ResourceNotFoundException("HistoricalImportJob", str(job_id))

    return LetzshopHistoricalImportJobResponse.model_validate(job)


@admin_letzshop_router.get(
    "/stores/{store_id}/import-summary",
)
def get_import_summary(
    store_id: int = Path(..., description="Store ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Get summary statistics for imported Letzshop orders.

    Returns total orders, unique customers, and breakdowns by state/locale/country.
    """
    order_service = get_order_service(db)

    try:
        order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    summary = order_service.get_historical_import_summary(store_id)

    return {
        "success": True,
        "summary": summary,
    }


# ============================================================================
# Fulfillment Operations (Admin)
# ============================================================================


@admin_letzshop_router.post(
    "/stores/{store_id}/orders/{order_id}/confirm",
    response_model=FulfillmentOperationResponse,
)
def confirm_order(
    store_id: int = Path(..., description="Store ID"),
    order_id: int = Path(..., description="Order ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Confirm all inventory units for a Letzshop order.

    Sends confirmInventoryUnits mutation with isAvailable=true for all items.

    Raises:
        OrderHasUnresolvedExceptionsException: If order has unresolved product exceptions
    """
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        order = order_service.get_order_or_raise(store_id, order_id)
    except OrderNotFoundError:
        raise ResourceNotFoundException("Order", str(order_id))

    # Check for unresolved exceptions (blocks confirmation)
    unresolved_count = order_item_exception_service.get_unresolved_exception_count(
        db, order_id
    )
    if unresolved_count > 0:
        raise OrderHasUnresolvedExceptionsException(order_id, unresolved_count)

    # Get inventory unit IDs from order items
    items = order_service.get_order_items(order)
    if not items:
        return FulfillmentOperationResponse(
            success=False,
            message="No items found in order",
        )

    inventory_unit_ids = [
        item.external_item_id for item in items if item.external_item_id
    ]

    if not inventory_unit_ids:
        return FulfillmentOperationResponse(
            success=False,
            message="No inventory unit IDs found in order items",
        )

    try:
        with creds_service.create_client(store_id) as client:
            result = client.confirm_inventory_units(inventory_unit_ids)

            if not result.get("inventoryUnits"):
                error_messages = [
                    e.get("message", "Unknown error")
                    for e in result.get("errors", [])
                ]
                return FulfillmentOperationResponse(
                    success=False,
                    message="Some inventory units could not be confirmed",
                    errors=error_messages,
                )

            # Update order status and item states
            for item in items:
                if item.external_item_id:
                    order_service.update_inventory_unit_state(
                        order, item.external_item_id, "confirmed_available"
                    )
            order_service.mark_order_confirmed(order)
            db.commit()

            return FulfillmentOperationResponse(
                success=True,
                message=f"Confirmed {len(inventory_unit_ids)} inventory units",
                confirmed_units=[u.get("id") for u in result.get("inventoryUnits", [])],
            )

    except LetzshopClientError as e:
        return FulfillmentOperationResponse(success=False, message=str(e))


@admin_letzshop_router.post(
    "/stores/{store_id}/orders/{order_id}/reject",
    response_model=FulfillmentOperationResponse,
)
def reject_order(
    store_id: int = Path(..., description="Store ID"),
    order_id: int = Path(..., description="Order ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Decline all inventory units for a Letzshop order.

    Sends confirmInventoryUnits mutation with isAvailable=false for all items.
    """
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        order = order_service.get_order_or_raise(store_id, order_id)
    except OrderNotFoundError:
        raise ResourceNotFoundException("Order", str(order_id))

    # Get inventory unit IDs from order items
    items = order_service.get_order_items(order)
    if not items:
        return FulfillmentOperationResponse(
            success=False,
            message="No items found in order",
        )

    inventory_unit_ids = [
        item.external_item_id for item in items if item.external_item_id
    ]

    if not inventory_unit_ids:
        return FulfillmentOperationResponse(
            success=False,
            message="No inventory unit IDs found in order items",
        )

    try:
        with creds_service.create_client(store_id) as client:
            result = client.reject_inventory_units(inventory_unit_ids)

            if not result.get("inventoryUnits"):
                error_messages = [
                    e.get("message", "Unknown error")
                    for e in result.get("errors", [])
                ]
                return FulfillmentOperationResponse(
                    success=False,
                    message="Some inventory units could not be declined",
                    errors=error_messages,
                )

            # Update item states and order status
            for item in items:
                if item.external_item_id:
                    order_service.update_inventory_unit_state(
                        order, item.external_item_id, "confirmed_unavailable"
                    )
            order_service.mark_order_rejected(order)
            db.commit()

            return FulfillmentOperationResponse(
                success=True,
                message=f"Declined {len(inventory_unit_ids)} inventory units",
            )

    except LetzshopClientError as e:
        return FulfillmentOperationResponse(success=False, message=str(e))


@admin_letzshop_router.post(
    "/stores/{store_id}/orders/{order_id}/items/{item_id}/confirm",
    response_model=FulfillmentOperationResponse,
)
def confirm_single_item(
    store_id: int = Path(..., description="Store ID"),
    order_id: int = Path(..., description="Order ID"),
    item_id: str = Path(..., description="External Item ID (Letzshop inventory unit ID)"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Confirm a single inventory unit in an order.

    Sends confirmInventoryUnits mutation with isAvailable=true for one item.

    Raises:
        OrderHasUnresolvedExceptionsException: If the specific item has an unresolved exception
    """
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        order = order_service.get_order_or_raise(store_id, order_id)
    except OrderNotFoundError:
        raise ResourceNotFoundException("Order", str(order_id))

    # Check if this specific item has an unresolved exception
    # Find the order item by external_item_id
    item = next(
        (i for i in order.items if i.external_item_id == item_id),
        None
    )
    if item and item.needs_product_match:
        raise OrderHasUnresolvedExceptionsException(order_id, 1)

    try:
        with creds_service.create_client(store_id) as client:
            result = client.confirm_inventory_units([item_id])

            if not result.get("inventoryUnits"):
                error_messages = [
                    e.get("message", "Unknown error")
                    for e in result.get("errors", [])
                ]
                return FulfillmentOperationResponse(
                    success=False,
                    message="Failed to confirm item",
                    errors=error_messages,
                )

            # Update local order item state
            order_service.update_inventory_unit_state(order, item_id, "confirmed_available")
            db.commit()

            return FulfillmentOperationResponse(
                success=True,
                message="Item confirmed",
                confirmed_units=[item_id],
            )

    except LetzshopClientError as e:
        return FulfillmentOperationResponse(success=False, message=str(e))


@admin_letzshop_router.post(
    "/stores/{store_id}/orders/{order_id}/items/{item_id}/decline",
    response_model=FulfillmentOperationResponse,
)
def decline_single_item(
    store_id: int = Path(..., description="Store ID"),
    order_id: int = Path(..., description="Order ID"),
    item_id: str = Path(..., description="External Item ID (Letzshop inventory unit ID)"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Decline a single inventory unit in an order.

    Sends confirmInventoryUnits mutation with isAvailable=false for one item.
    """
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        order = order_service.get_order_or_raise(store_id, order_id)
    except OrderNotFoundError:
        raise ResourceNotFoundException("Order", str(order_id))

    try:
        with creds_service.create_client(store_id) as client:
            result = client.reject_inventory_units([item_id])

            if not result.get("inventoryUnits"):
                error_messages = [
                    e.get("message", "Unknown error")
                    for e in result.get("errors", [])
                ]
                return FulfillmentOperationResponse(
                    success=False,
                    message="Failed to decline item",
                    errors=error_messages,
                )

            # Update local order item state
            order_service.update_inventory_unit_state(order, item_id, "confirmed_unavailable")
            db.commit()

            return FulfillmentOperationResponse(
                success=True,
                message="Item declined",
            )

    except LetzshopClientError as e:
        return FulfillmentOperationResponse(success=False, message=str(e))


# ============================================================================
# Tracking Sync
# ============================================================================


@admin_letzshop_router.post(
    "/stores/{store_id}/sync-tracking",
    response_model=LetzshopSyncTriggerResponse,
)
def sync_tracking_for_store(
    store_id: int = Path(..., description="Store ID"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Sync tracking information from Letzshop for confirmed orders.

    Fetches tracking data from Letzshop API for orders that:
    - Are in "processing" status (confirmed)
    - Don't have tracking info yet
    - Have an external shipment ID

    This is useful when tracking is added by Letzshop after order confirmation.
    """
    order_service = get_order_service(db)
    creds_service = get_credentials_service(db)

    try:
        order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    # Verify credentials exist
    try:
        creds_service.get_credentials_or_raise(store_id)
    except CredentialsNotFoundError:
        raise ValidationException(
            f"Letzshop credentials not configured for store {store_id}"
        )

    # Get orders that need tracking
    orders_without_tracking = order_service.get_orders_without_tracking(store_id)
    if not orders_without_tracking:
        return LetzshopSyncTriggerResponse(
            success=True,
            message="No orders need tracking updates",
            orders_imported=0,
            orders_updated=0,
        )

    logger.info(
        f"Syncing tracking for {len(orders_without_tracking)} orders (store {store_id})"
    )

    orders_updated = 0
    errors = []

    try:
        with creds_service.create_client(store_id) as client:
            for order in orders_without_tracking:
                try:
                    # Fetch shipment by ID
                    shipment_data = client.get_shipment_by_id(order.external_shipment_id)
                    if shipment_data:
                        updated = order_service.update_tracking_from_shipment_data(
                            order, shipment_data
                        )
                        if updated:
                            orders_updated += 1
                except Exception as e:
                    errors.append(
                        f"Error syncing tracking for order {order.order_number}: {e}"
                    )

            db.commit()

            message = f"Tracking sync completed: {orders_updated} orders updated"
            if errors:
                message += f" ({len(errors)} errors)"

            return LetzshopSyncTriggerResponse(
                success=True,
                message=message,
                orders_imported=0,
                orders_updated=orders_updated,
                errors=errors,
            )

    except LetzshopClientError as e:
        return LetzshopSyncTriggerResponse(
            success=False,
            message=f"Tracking sync failed: {e}",
            errors=[str(e)],
        )


# ============================================================================
# Store Directory (Letzshop Marketplace Stores)
# ============================================================================


def get_store_sync_service(db: Session) -> LetzshopStoreSyncService:
    """Get store sync service instance."""
    return LetzshopStoreSyncService(db)


@admin_letzshop_router.post("/store-directory/sync")
def trigger_store_directory_sync(
    background_tasks: BackgroundTasks,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Trigger a sync of the Letzshop store directory.

    Fetches all stores from Letzshop's public GraphQL API and updates
    the local cache. This is typically run daily via Celery beat, but
    can be triggered manually here.
    """
    from app.modules.marketplace.tasks import sync_store_directory

    # Try to dispatch via Celery first
    try:
        task = sync_store_directory.delay()
        logger.info(
            f"Admin {current_admin.email} triggered store directory sync (task={task.id})"
        )
        return {
            "success": True,
            "message": "Store directory sync started",
            "task_id": task.id,
            "mode": "celery",
        }
    except Exception as e:
        # Fall back to background tasks
        logger.warning(f"Celery dispatch failed, using background tasks: {e}")

        def run_sync():
            from app.core.database import SessionLocal

            sync_db = SessionLocal()
            try:
                sync_service = LetzshopStoreSyncService(sync_db)
                sync_service.sync_all_stores()
            finally:
                sync_db.close()

        background_tasks.add_task(run_sync)
        logger.info(
            f"Admin {current_admin.email} triggered store directory sync (background task)"
        )
        return {
            "success": True,
            "message": "Store directory sync started",
            "mode": "background_task",
        }


@admin_letzshop_router.get(
    "/store-directory/stats",
    response_model=LetzshopStoreDirectoryStatsResponse,
)
def get_store_directory_stats(
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
) -> LetzshopStoreDirectoryStatsResponse:
    """
    Get statistics about the Letzshop store directory cache.

    Returns total, active, claimed, and unclaimed store counts.
    """
    sync_service = get_store_sync_service(db)
    stats_data = sync_service.get_sync_stats()
    return LetzshopStoreDirectoryStatsResponse(
        stats=LetzshopStoreDirectoryStats(**stats_data)
    )


@admin_letzshop_router.get(
    "/store-directory/stores",
    response_model=LetzshopCachedStoreListResponse,
)
def list_cached_stores(
    search: str | None = Query(None, description="Search by name"),
    city: str | None = Query(None, description="Filter by city"),
    category: str | None = Query(None, description="Filter by category"),
    only_unclaimed: bool = Query(False, description="Only show unclaimed stores"),
    page: int = Query(1, ge=1),
    limit: int = Query(20, ge=1, le=100),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
) -> LetzshopCachedStoreListResponse:
    """
    List cached Letzshop stores with search and filtering.

    This returns stores from the local cache, not directly from Letzshop.
    """
    sync_service = get_store_sync_service(db)
    stores, total = sync_service.search_cached_stores(
        search=search,
        city=city,
        category=category,
        only_unclaimed=only_unclaimed,
        page=page,
        limit=limit,
    )

    return LetzshopCachedStoreListResponse(
        stores=[
            LetzshopCachedStoreItem(
                id=v.id,
                letzshop_id=v.letzshop_id,
                slug=v.slug,
                name=v.name,
                merchant_name=v.merchant_name,
                email=v.email,
                phone=v.phone,
                website=v.website,
                city=v.city,
                categories=v.categories or [],
                is_active=v.is_active,
                is_claimed=v.is_claimed,
                claimed_by_store_id=v.claimed_by_store_id,
                last_synced_at=v.last_synced_at,
                letzshop_url=v.letzshop_url,
            )
            for v in stores
        ],
        total=total,
        page=page,
        limit=limit,
        has_more=(page * limit) < total,
    )


@admin_letzshop_router.get(
    "/store-directory/stores/{slug}",
    response_model=LetzshopCachedStoreDetailResponse,
)
def get_cached_store_detail(
    slug: str = Path(..., description="Letzshop store slug"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
) -> LetzshopCachedStoreDetailResponse:
    """
    Get detailed information about a cached Letzshop store.
    """
    sync_service = get_store_sync_service(db)
    store = sync_service.get_cached_store(slug)

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

    return LetzshopCachedStoreDetailResponse(
        store=LetzshopCachedStoreDetail(
            id=store.id,
            letzshop_id=store.letzshop_id,
            slug=store.slug,
            name=store.name,
            merchant_name=store.merchant_name,
            description_en=store.description_en,
            description_fr=store.description_fr,
            description_de=store.description_de,
            email=store.email,
            phone=store.phone,
            fax=store.fax,
            website=store.website,
            street=store.street,
            street_number=store.street_number,
            city=store.city,
            zipcode=store.zipcode,
            country_iso=store.country_iso,
            latitude=store.latitude,
            longitude=store.longitude,
            categories=store.categories or [],
            background_image_url=store.background_image_url,
            social_media_links=store.social_media_links or [],
            opening_hours_en=store.opening_hours_en,
            opening_hours_fr=store.opening_hours_fr,
            opening_hours_de=store.opening_hours_de,
            representative_name=store.representative_name,
            representative_title=store.representative_title,
            is_active=store.is_active,
            is_claimed=store.is_claimed,
            claimed_by_store_id=store.claimed_by_store_id,
            claimed_at=store.claimed_at,
            last_synced_at=store.last_synced_at,
            letzshop_url=store.letzshop_url,
        )
    )


@admin_letzshop_router.post(
    "/store-directory/stores/{slug}/create-store",
    response_model=LetzshopCreateStoreFromCacheResponse,
)
def create_store_from_letzshop(
    slug: str = Path(..., description="Letzshop store slug"),
    merchant_id: int = Query(..., description="Merchant ID to create store under"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
) -> LetzshopCreateStoreFromCacheResponse:
    """
    Create a platform store from a cached Letzshop store.

    This creates a new store on the platform using information from the
    Letzshop store cache. The store will be linked to the specified merchant.

    Args:
        slug: The Letzshop store slug
        merchant_id: The merchant ID to create the store under
    """
    sync_service = get_store_sync_service(db)

    try:
        store_info = sync_service.create_store_from_cache(slug, merchant_id)

        logger.info(
            f"Admin {current_admin.email} created store {store_info['store_code']} "
            f"from Letzshop store {slug}"
        )

        return LetzshopCreateStoreFromCacheResponse(
            message=f"Store '{store_info['name']}' created successfully",
            store=store_info,
            letzshop_store_slug=slug,
        )

    except ValueError as e:
        raise ValidationException(str(e))


# ============================================================================
# Product Export
# ============================================================================


@admin_letzshop_router.get("/stores/{store_id}/export")
def export_store_products_letzshop(
    store_id: int = Path(..., description="Store ID"),
    language: str = Query(
        "en", description="Language for title/description (en, fr, de)"
    ),
    include_inactive: bool = Query(False, description="Include inactive products"),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Export store products in Letzshop CSV format (Admin only).

    Generates a Google Shopping compatible CSV file for Letzshop marketplace.
    The file uses tab-separated values and includes all required Letzshop fields.

    **Supported languages:** en, fr, de

    **CSV Format:**
    - Delimiter: Tab (\\t)
    - Encoding: UTF-8
    - Fields: id, title, description, price, availability, image_link, etc.

    Returns:
        CSV file as attachment (store_code_letzshop_export.csv)
    """
    from fastapi.responses import Response

    from app.modules.marketplace.services.letzshop_export_service import (
        letzshop_export_service,
    )

    order_service = get_order_service(db)

    try:
        store = order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    csv_content = letzshop_export_service.export_store_products(
        db=db,
        store_id=store.id,
        language=language,
        include_inactive=include_inactive,
    )

    filename = f"{store.store_code.lower()}_letzshop_export.csv"

    return Response(
        content=csv_content,
        media_type="text/csv; charset=utf-8",
        headers={
            "Content-Disposition": f'attachment; filename="{filename}"',
        },
    )


@admin_letzshop_router.post(
    "/stores/{store_id}/export",
    response_model=LetzshopExportResponse,
)
def export_store_products_letzshop_to_folder(
    store_id: int = Path(..., description="Store ID"),
    request: LetzshopExportRequest = None,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """
    Export store products to Letzshop pickup folder (Admin only).

    Generates CSV files for all languages (FR, DE, EN) and places them in a folder
    that Letzshop scheduler can fetch from. This is the preferred method for
    automated product sync.

    **Behavior:**
    - When Celery is enabled: Queues export as background task, returns immediately
    - When Celery is disabled: Runs synchronously and returns file paths
    - Creates CSV files for each language (fr, de, en)
    - Places files in: exports/letzshop/{store_code}/
    - Filename format: {store_code}_products_{language}.csv

    Returns:
        JSON with export status and file paths (or task_id if async)
    """
    import os
    from datetime import UTC, datetime
    from pathlib import Path as FilePath

    from app.core.config import settings
    from app.modules.marketplace.services.letzshop_export_service import (
        letzshop_export_service,
    )

    order_service = get_order_service(db)

    try:
        store = order_service.get_store_or_raise(store_id)
    except StoreNotFoundError:
        raise ResourceNotFoundException("Store", str(store_id))

    include_inactive = request.include_inactive if request else False

    # If Celery is enabled, dispatch as async task
    if settings.use_celery:
        from app.tasks.dispatcher import task_dispatcher

        celery_task_id = task_dispatcher.dispatch_product_export(
            store_id=store.id,
            triggered_by=f"admin:{current_admin.id}",
            include_inactive=include_inactive,
        )

        return {
            "success": True,
            "message": f"Export task queued for store {store.store_code}. Check Flower for status.",
            "store_code": store.store_code,
            "export_directory": f"exports/letzshop/{store.store_code.lower()}",
            "files": [],
            "celery_task_id": celery_task_id,
            "is_async": True,
        }

    # Synchronous export (when Celery is disabled)
    started_at = datetime.now(UTC)

    # Create export directory
    export_dir = FilePath(f"exports/letzshop/{store.store_code.lower()}")
    export_dir.mkdir(parents=True, exist_ok=True)

    exported_files = []
    languages = ["fr", "de", "en"]
    total_records = 0
    failed_count = 0

    for lang in languages:
        try:
            csv_content = letzshop_export_service.export_store_products(
                db=db,
                store_id=store.id,
                language=lang,
                include_inactive=include_inactive,
            )

            filename = f"{store.store_code.lower()}_products_{lang}.csv"
            filepath = export_dir / filename

            with open(filepath, "w", encoding="utf-8") as f:
                f.write(csv_content)

            # Count lines (minus header)
            line_count = csv_content.count("\n")
            if line_count > 0:
                total_records = max(total_records, line_count - 1)

            exported_files.append({
                "language": lang,
                "filename": filename,
                "path": str(filepath),
                "size_bytes": os.path.getsize(filepath),
            })
        except Exception as e:
            failed_count += 1
            exported_files.append({
                "language": lang,
                "error": str(e),
            })

    # Log the export operation via service
    completed_at = datetime.now(UTC)
    letzshop_export_service.log_export(
        db=db,
        store_id=store.id,
        started_at=started_at,
        completed_at=completed_at,
        files_processed=len(languages),
        files_succeeded=len(languages) - failed_count,
        files_failed=failed_count,
        products_exported=total_records,
        triggered_by=f"admin:{current_admin.id}",
        error_details={"files": exported_files} if failed_count > 0 else None,
    )
    db.commit()

    return {
        "success": True,
        "message": f"Exported {len([f for f in exported_files if 'error' not in f])} language(s) to {export_dir}",
        "store_code": store.store_code,
        "export_directory": str(export_dir),
        "files": exported_files,
        "is_async": False,
    }
