# services/suppliers/app/api/suppliers.py
"""
Supplier API endpoints
"""

from fastapi import APIRouter, Depends, HTTPException, Query, Path, Request
from typing import List, Optional
from uuid import UUID
import structlog

from sqlalchemy.ext.asyncio import AsyncSession
from app.core.database import get_db
from app.services.supplier_service import SupplierService
from app.schemas.suppliers import (
    SupplierCreate, SupplierUpdate, SupplierResponse, SupplierSummary,
    SupplierSearchParams, SupplierApproval, SupplierStatistics
)
from shared.auth.decorators import get_current_user_dep
from typing import Dict, Any

router = APIRouter(prefix="/tenants/{tenant_id}/suppliers", tags=["suppliers"])
logger = structlog.get_logger()

@router.post("", response_model=SupplierResponse)
@router.post("/", response_model=SupplierResponse)
async def create_supplier(
    supplier_data: SupplierCreate,
    tenant_id: str = Path(..., description="Tenant ID"),
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    
    try:
        service = SupplierService(db)
        supplier = await service.create_supplier(
            tenant_id=UUID(tenant_id),
            supplier_data=supplier_data,
            created_by=current_user.user_id
        )
        return SupplierResponse.from_orm(supplier)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error("Error creating supplier", error=str(e))
        raise HTTPException(status_code=500, detail="Failed to create supplier")


@router.get("", response_model=List[SupplierSummary])
@router.get("/", response_model=List[SupplierSummary])
async def list_suppliers(
    tenant_id: str = Path(..., description="Tenant ID"),
    search_term: Optional[str] = Query(None, description="Search term"),
    supplier_type: Optional[str] = Query(None, description="Supplier type filter"),
    status: Optional[str] = Query(None, description="Status filter"),
    limit: int = Query(50, ge=1, le=1000, description="Number of results to return"),
    offset: int = Query(0, ge=0, description="Number of results to skip"),
    db: AsyncSession = Depends(get_db)
):
    """List suppliers with optional filters"""
    # require_permissions(current_user, ["suppliers:read"])
    
    try:
        service = SupplierService(db)
        search_params = SupplierSearchParams(
            search_term=search_term,
            supplier_type=supplier_type,
            status=status,
            limit=limit,
            offset=offset
        )
        suppliers = await service.search_suppliers(
            tenant_id=UUID(tenant_id),
            search_params=search_params
        )
        return [SupplierSummary.from_orm(supplier) for supplier in suppliers]
    except Exception as e:
        logger.error("Error listing suppliers", error=str(e))
        raise HTTPException(status_code=500, detail="Failed to retrieve suppliers")


@router.get("/statistics", response_model=SupplierStatistics)
async def get_supplier_statistics(
    tenant_id: str = Path(..., description="Tenant ID"),
    db: AsyncSession = Depends(get_db)
):
    """Get supplier statistics for dashboard"""
    # require_permissions(current_user, ["suppliers:read"])
    
    try:
        service = SupplierService(db)
        stats = await service.get_supplier_statistics(UUID(tenant_id))
        return SupplierStatistics(**stats)
    except Exception as e:
        logger.error("Error getting supplier statistics", error=str(e))
        raise HTTPException(status_code=500, detail="Failed to retrieve statistics")


@router.get("/active", response_model=List[SupplierSummary])
async def get_active_suppliers(
    tenant_id: str = Path(..., description="Tenant ID"),
    db: AsyncSession = Depends(get_db)
):
    """Get all active suppliers"""
    # require_permissions(current_user, ["suppliers:read"])
    
    try:
        service = SupplierService(db)
        suppliers = await service.get_active_suppliers(UUID(tenant_id))
        return [SupplierSummary.from_orm(supplier) for supplier in suppliers]
    except Exception as e:
        logger.error("Error getting active suppliers", error=str(e))
        raise HTTPException(status_code=500, detail="Failed to retrieve active suppliers")


@router.get("/top", response_model=List[SupplierSummary])
async def get_top_suppliers(
    tenant_id: str = Path(..., description="Tenant ID"),
    limit: int = Query(10, ge=1, le=50, description="Number of top suppliers to return"),
    db: AsyncSession = Depends(get_db)
):
    """Get top performing suppliers"""
    # require_permissions(current_user, ["suppliers:read"])
    
    try:
        service = SupplierService(db)
        suppliers = await service.get_top_suppliers(UUID(tenant_id), limit)
        return [SupplierSummary.from_orm(supplier) for supplier in suppliers]
    except Exception as e:
        logger.error("Error getting top suppliers", error=str(e))
        raise HTTPException(status_code=500, detail="Failed to retrieve top suppliers")


@router.get("/pending-review", response_model=List[SupplierSummary])
async def get_suppliers_needing_review(
    tenant_id: str = Path(..., description="Tenant ID"),
    days_since_last_order: int = Query(30, ge=1, le=365, description="Days since last order"),
    db: AsyncSession = Depends(get_db)
):
    """Get suppliers that may need performance review"""
    # require_permissions(current_user, ["suppliers:read"])
    
    try:
        service = SupplierService(db)
        suppliers = await service.get_suppliers_needing_review(
            UUID(tenant_id), days_since_last_order
        )
        return [SupplierSummary.from_orm(supplier) for supplier in suppliers]
    except Exception as e:
        logger.error("Error getting suppliers needing review", error=str(e))
        raise HTTPException(status_code=500, detail="Failed to retrieve suppliers needing review")


@router.get("/{supplier_id}", response_model=SupplierResponse)
async def get_supplier(
    supplier_id: UUID = Path(..., description="Supplier ID"),
    tenant_id: str = Path(..., description="Tenant ID"),
    db: AsyncSession = Depends(get_db)
):
    """Get supplier by ID"""
    # require_permissions(current_user, ["suppliers:read"])
    
    try:
        service = SupplierService(db)
        supplier = await service.get_supplier(supplier_id)
        
        if not supplier:
            raise HTTPException(status_code=404, detail="Supplier not found")
        
        return SupplierResponse.from_orm(supplier)
    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error getting supplier", supplier_id=str(supplier_id), error=str(e))
        raise HTTPException(status_code=500, detail="Failed to retrieve supplier")


@router.put("/{supplier_id}", response_model=SupplierResponse)
async def update_supplier(
    supplier_data: SupplierUpdate,
    supplier_id: UUID = Path(..., description="Supplier ID"),
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Update supplier information"""
    # require_permissions(current_user, ["suppliers:update"])
    
    try:
        service = SupplierService(db)
        
        # Check supplier exists
        existing_supplier = await service.get_supplier(supplier_id)
        if not existing_supplier:
            raise HTTPException(status_code=404, detail="Supplier not found")
        
        supplier = await service.update_supplier(
            supplier_id=supplier_id,
            supplier_data=supplier_data,
            updated_by=current_user.user_id
        )
        
        if not supplier:
            raise HTTPException(status_code=404, detail="Supplier not found")
        
        return SupplierResponse.from_orm(supplier)
    except HTTPException:
        raise
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error("Error updating supplier", supplier_id=str(supplier_id), error=str(e))
        raise HTTPException(status_code=500, detail="Failed to update supplier")


@router.delete("/{supplier_id}")
async def delete_supplier(
    supplier_id: UUID = Path(..., description="Supplier ID"),
    db: AsyncSession = Depends(get_db)
):
    """Delete supplier (soft delete)"""
    # require_permissions(current_user, ["suppliers:delete"])
    
    try:
        service = SupplierService(db)
        
        # Check supplier exists
        existing_supplier = await service.get_supplier(supplier_id)
        if not existing_supplier:
            raise HTTPException(status_code=404, detail="Supplier not found")
        
        success = await service.delete_supplier(supplier_id)
        if not success:
            raise HTTPException(status_code=404, detail="Supplier not found")
        
        return {"message": "Supplier deleted successfully"}
    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error deleting supplier", supplier_id=str(supplier_id), error=str(e))
        raise HTTPException(status_code=500, detail="Failed to delete supplier")


@router.post("/{supplier_id}/approve", response_model=SupplierResponse)
async def approve_supplier(
    approval_data: SupplierApproval,
    supplier_id: UUID = Path(..., description="Supplier ID"),
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Approve or reject a pending supplier"""
    # require_permissions(current_user, ["suppliers:approve"])
    
    try:
        service = SupplierService(db)
        
        # Check supplier exists
        existing_supplier = await service.get_supplier(supplier_id)
        if not existing_supplier:
            raise HTTPException(status_code=404, detail="Supplier not found")
        
        if approval_data.action == "approve":
            supplier = await service.approve_supplier(
                supplier_id=supplier_id,
                approved_by=current_user.user_id,
                notes=approval_data.notes
            )
        elif approval_data.action == "reject":
            if not approval_data.notes:
                raise HTTPException(status_code=400, detail="Rejection reason is required")
            supplier = await service.reject_supplier(
                supplier_id=supplier_id,
                rejection_reason=approval_data.notes,
                rejected_by=current_user.user_id
            )
        else:
            raise HTTPException(status_code=400, detail="Invalid action")
        
        if not supplier:
            raise HTTPException(status_code=400, detail="Supplier is not in pending approval status")
        
        return SupplierResponse.from_orm(supplier)
    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error processing supplier approval", supplier_id=str(supplier_id), error=str(e))
        raise HTTPException(status_code=500, detail="Failed to process supplier approval")


@router.get("/types/{supplier_type}", response_model=List[SupplierSummary])
async def get_suppliers_by_type(
    supplier_type: str = Path(..., description="Supplier type"),
    tenant_id: str = Path(..., description="Tenant ID"),
    db: AsyncSession = Depends(get_db)
):
    """Get suppliers by type"""
    # require_permissions(current_user, ["suppliers:read"])
    
    try:
        from app.models.suppliers import SupplierType
        
        # Validate supplier type
        try:
            type_enum = SupplierType(supplier_type.upper())
        except ValueError:
            raise HTTPException(status_code=400, detail="Invalid supplier type")
        
        service = SupplierService(db)
        suppliers = await service.get_suppliers_by_type(UUID(tenant_id), type_enum)
        return [SupplierSummary.from_orm(supplier) for supplier in suppliers]
    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error getting suppliers by type", supplier_type=supplier_type, error=str(e))
        raise HTTPException(status_code=500, detail="Failed to retrieve suppliers by type")