# services/tenant/app/api/tenant_settings.py
"""
Tenant Settings API Endpoints
REST API for managing tenant-specific operational settings
"""

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from uuid import UUID
from typing import Dict, Any

from app.core.database import get_db
from shared.routing.route_builder import RouteBuilder
from ..services.tenant_settings_service import TenantSettingsService
from ..schemas.tenant_settings import (
    TenantSettingsResponse,
    TenantSettingsUpdate,
    CategoryUpdateRequest,
    CategoryResetResponse
)

router = APIRouter()
route_builder = RouteBuilder("tenants")


@router.get(
    "/{tenant_id}/settings",
    response_model=TenantSettingsResponse,
    summary="Get all tenant settings",
    description="Retrieve all operational settings for a tenant. Creates default settings if none exist."
)
async def get_tenant_settings(
    tenant_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    Get all settings for a tenant

    - **tenant_id**: UUID of the tenant

    Returns all setting categories with their current values.
    If settings don't exist, default values are created and returned.
    """
    service = TenantSettingsService(db)
    settings = await service.get_settings(tenant_id)
    return settings


@router.put(
    "/{tenant_id}/settings",
    response_model=TenantSettingsResponse,
    summary="Update tenant settings",
    description="Update one or more setting categories for a tenant. Only provided categories are updated."
)
async def update_tenant_settings(
    tenant_id: UUID,
    updates: TenantSettingsUpdate,
    db: AsyncSession = Depends(get_db)
):
    """
    Update tenant settings

    - **tenant_id**: UUID of the tenant
    - **updates**: Object containing setting categories to update

    Only provided categories will be updated. Omitted categories remain unchanged.
    All values are validated against min/max constraints.
    """
    service = TenantSettingsService(db)
    settings = await service.update_settings(tenant_id, updates)
    return settings


@router.get(
    "/{tenant_id}/settings/{category}",
    response_model=Dict[str, Any],
    summary="Get settings for a specific category",
    description="Retrieve settings for a single category (procurement, inventory, production, supplier, pos, or order)"
)
async def get_category_settings(
    tenant_id: UUID,
    category: str,
    db: AsyncSession = Depends(get_db)
):
    """
    Get settings for a specific category

    - **tenant_id**: UUID of the tenant
    - **category**: Category name (procurement, inventory, production, supplier, pos, order)

    Returns settings for the specified category only.

    Valid categories:
    - procurement: Auto-approval and procurement planning settings
    - inventory: Stock thresholds and temperature monitoring
    - production: Capacity, quality, and scheduling settings
    - supplier: Payment terms and performance thresholds
    - pos: POS integration sync settings
    - order: Discount and delivery settings
    """
    service = TenantSettingsService(db)
    category_settings = await service.get_category(tenant_id, category)
    return {
        "tenant_id": str(tenant_id),
        "category": category,
        "settings": category_settings
    }


@router.put(
    "/{tenant_id}/settings/{category}",
    response_model=TenantSettingsResponse,
    summary="Update settings for a specific category",
    description="Update all or some fields within a single category"
)
async def update_category_settings(
    tenant_id: UUID,
    category: str,
    request: CategoryUpdateRequest,
    db: AsyncSession = Depends(get_db)
):
    """
    Update settings for a specific category

    - **tenant_id**: UUID of the tenant
    - **category**: Category name
    - **request**: Object containing the settings to update

    Updates only the specified category. All values are validated.
    """
    service = TenantSettingsService(db)
    settings = await service.update_category(tenant_id, category, request.settings)
    return settings


@router.post(
    "/{tenant_id}/settings/{category}/reset",
    response_model=CategoryResetResponse,
    summary="Reset category to default values",
    description="Reset a specific category to its default values"
)
async def reset_category_settings(
    tenant_id: UUID,
    category: str,
    db: AsyncSession = Depends(get_db)
):
    """
    Reset a category to default values

    - **tenant_id**: UUID of the tenant
    - **category**: Category name

    Resets all settings in the specified category to their default values.
    This operation cannot be undone.
    """
    service = TenantSettingsService(db)
    reset_settings = await service.reset_category(tenant_id, category)

    return CategoryResetResponse(
        category=category,
        settings=reset_settings,
        message=f"Category '{category}' has been reset to default values"
    )


@router.delete(
    "/{tenant_id}/settings",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete tenant settings",
    description="Delete all settings for a tenant (used when tenant is deleted)"
)
async def delete_tenant_settings(
    tenant_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    Delete tenant settings

    - **tenant_id**: UUID of the tenant

    This endpoint is typically called automatically when a tenant is deleted.
    It removes all setting data for the tenant.
    """
    service = TenantSettingsService(db)
    await service.delete_settings(tenant_id)
    return None
