import json
import logging
from typing import List, Optional

from datetime import datetime, date

from fastapi import APIRouter, Body, Depends, HTTPException, Query
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession

from core.database import get_db
from services.support_seats import Support_seatsService

# Set up logging
logger = logging.getLogger(__name__)

router = APIRouter(prefix="/api/v1/entities/support_seats", tags=["support_seats"])


# ---------- Pydantic Schemas ----------
class Support_seatsData(BaseModel):
    """Entity data schema (for create/update)"""
    user_id: str = None
    display_name: str
    email: str
    role: str
    department_id: int = None
    status: str = None
    chat_limit: int = None
    working_hours: str = None
    permissions: str = None


class Support_seatsUpdateData(BaseModel):
    """Update entity data (partial updates allowed)"""
    user_id: Optional[str] = None
    display_name: Optional[str] = None
    email: Optional[str] = None
    role: Optional[str] = None
    department_id: Optional[int] = None
    status: Optional[str] = None
    chat_limit: Optional[int] = None
    working_hours: Optional[str] = None
    permissions: Optional[str] = None


class Support_seatsResponse(BaseModel):
    """Entity response schema"""
    id: int
    user_id: Optional[str] = None
    display_name: str
    email: str
    role: str
    department_id: Optional[int] = None
    status: Optional[str] = None
    chat_limit: Optional[int] = None
    working_hours: Optional[str] = None
    permissions: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


class Support_seatsListResponse(BaseModel):
    """List response schema"""
    items: List[Support_seatsResponse]
    total: int
    skip: int
    limit: int


class Support_seatsBatchCreateRequest(BaseModel):
    """Batch create request"""
    items: List[Support_seatsData]


class Support_seatsBatchUpdateItem(BaseModel):
    """Batch update item"""
    id: int
    updates: Support_seatsUpdateData


class Support_seatsBatchUpdateRequest(BaseModel):
    """Batch update request"""
    items: List[Support_seatsBatchUpdateItem]


class Support_seatsBatchDeleteRequest(BaseModel):
    """Batch delete request"""
    ids: List[int]


# ---------- Routes ----------
@router.get("", response_model=Support_seatsListResponse)
async def query_support_seatss(
    query: str = Query(None, description="Query conditions (JSON string)"),
    sort: str = Query(None, description="Sort field (prefix with '-' for descending)"),
    skip: int = Query(0, ge=0, description="Number of records to skip"),
    limit: int = Query(20, ge=1, le=2000, description="Max number of records to return"),
    fields: str = Query(None, description="Comma-separated list of fields to return"),
    db: AsyncSession = Depends(get_db),
):
    """Query support_seatss with filtering, sorting, and pagination"""
    logger.debug(f"Querying support_seatss: query={query}, sort={sort}, skip={skip}, limit={limit}, fields={fields}")
    
    service = Support_seatsService(db)
    try:
        # Parse query JSON if provided
        query_dict = None
        if query:
            try:
                query_dict = json.loads(query)
            except json.JSONDecodeError:
                raise HTTPException(status_code=400, detail="Invalid query JSON format")
        
        result = await service.get_list(
            skip=skip, 
            limit=limit,
            query_dict=query_dict,
            sort=sort,
        )
        logger.debug(f"Found {result['total']} support_seatss")
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error querying support_seatss: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.get("/all", response_model=Support_seatsListResponse)
async def query_support_seatss_all(
    query: str = Query(None, description="Query conditions (JSON string)"),
    sort: str = Query(None, description="Sort field (prefix with '-' for descending)"),
    skip: int = Query(0, ge=0, description="Number of records to skip"),
    limit: int = Query(20, ge=1, le=2000, description="Max number of records to return"),
    fields: str = Query(None, description="Comma-separated list of fields to return"),
    db: AsyncSession = Depends(get_db),
):
    # Query support_seatss with filtering, sorting, and pagination without user limitation
    logger.debug(f"Querying support_seatss: query={query}, sort={sort}, skip={skip}, limit={limit}, fields={fields}")

    service = Support_seatsService(db)
    try:
        # Parse query JSON if provided
        query_dict = None
        if query:
            try:
                query_dict = json.loads(query)
            except json.JSONDecodeError:
                raise HTTPException(status_code=400, detail="Invalid query JSON format")

        result = await service.get_list(
            skip=skip,
            limit=limit,
            query_dict=query_dict,
            sort=sort
        )
        logger.debug(f"Found {result['total']} support_seatss")
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error querying support_seatss: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.get("/{id}", response_model=Support_seatsResponse)
async def get_support_seats(
    id: int,
    fields: str = Query(None, description="Comma-separated list of fields to return"),
    db: AsyncSession = Depends(get_db),
):
    """Get a single support_seats by ID"""
    logger.debug(f"Fetching support_seats with id: {id}, fields={fields}")
    
    service = Support_seatsService(db)
    try:
        result = await service.get_by_id(id)
        if not result:
            logger.warning(f"Support_seats with id {id} not found")
            raise HTTPException(status_code=404, detail="Support_seats not found")
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error fetching support_seats {id}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.post("", response_model=Support_seatsResponse, status_code=201)
async def create_support_seats(
    data: Support_seatsData,
    db: AsyncSession = Depends(get_db),
):
    """Create a new support_seats"""
    logger.debug(f"Creating new support_seats with data: {data}")
    
    service = Support_seatsService(db)
    try:
        result = await service.create(data.model_dump())
        if not result:
            raise HTTPException(status_code=400, detail="Failed to create support_seats")
        
        logger.info(f"Support_seats created successfully with id: {result.id}")
        return result
    except ValueError as e:
        logger.error(f"Validation error creating support_seats: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error creating support_seats: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.post("/batch", response_model=List[Support_seatsResponse], status_code=201)
async def create_support_seatss_batch(
    request: Support_seatsBatchCreateRequest,
    db: AsyncSession = Depends(get_db),
):
    """Create multiple support_seatss in a single request"""
    logger.debug(f"Batch creating {len(request.items)} support_seatss")
    
    service = Support_seatsService(db)
    results = []
    
    try:
        for item_data in request.items:
            result = await service.create(item_data.model_dump())
            if result:
                results.append(result)
        
        logger.info(f"Batch created {len(results)} support_seatss successfully")
        return results
    except Exception as e:
        await db.rollback()
        logger.error(f"Error in batch create: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Batch create failed: {str(e)}")


@router.put("/batch", response_model=List[Support_seatsResponse])
async def update_support_seatss_batch(
    request: Support_seatsBatchUpdateRequest,
    db: AsyncSession = Depends(get_db),
):
    """Update multiple support_seatss in a single request"""
    logger.debug(f"Batch updating {len(request.items)} support_seatss")
    
    service = Support_seatsService(db)
    results = []
    
    try:
        for item in request.items:
            # Only include non-None values for partial updates
            update_dict = {k: v for k, v in item.updates.model_dump().items() if v is not None}
            result = await service.update(item.id, update_dict)
            if result:
                results.append(result)
        
        logger.info(f"Batch updated {len(results)} support_seatss successfully")
        return results
    except Exception as e:
        await db.rollback()
        logger.error(f"Error in batch update: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Batch update failed: {str(e)}")


@router.put("/{id}", response_model=Support_seatsResponse)
async def update_support_seats(
    id: int,
    data: Support_seatsUpdateData,
    db: AsyncSession = Depends(get_db),
):
    """Update an existing support_seats"""
    logger.debug(f"Updating support_seats {id} with data: {data}")

    service = Support_seatsService(db)
    try:
        # Only include non-None values for partial updates
        update_dict = {k: v for k, v in data.model_dump().items() if v is not None}
        result = await service.update(id, update_dict)
        if not result:
            logger.warning(f"Support_seats with id {id} not found for update")
            raise HTTPException(status_code=404, detail="Support_seats not found")
        
        logger.info(f"Support_seats {id} updated successfully")
        return result
    except HTTPException:
        raise
    except ValueError as e:
        logger.error(f"Validation error updating support_seats {id}: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error updating support_seats {id}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.delete("/batch")
async def delete_support_seatss_batch(
    request: Support_seatsBatchDeleteRequest,
    db: AsyncSession = Depends(get_db),
):
    """Delete multiple support_seatss by their IDs"""
    logger.debug(f"Batch deleting {len(request.ids)} support_seatss")
    
    service = Support_seatsService(db)
    deleted_count = 0
    
    try:
        for item_id in request.ids:
            success = await service.delete(item_id)
            if success:
                deleted_count += 1
        
        logger.info(f"Batch deleted {deleted_count} support_seatss successfully")
        return {"message": f"Successfully deleted {deleted_count} support_seatss", "deleted_count": deleted_count}
    except Exception as e:
        await db.rollback()
        logger.error(f"Error in batch delete: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Batch delete failed: {str(e)}")


@router.delete("/{id}")
async def delete_support_seats(
    id: int,
    db: AsyncSession = Depends(get_db),
):
    """Delete a single support_seats by ID"""
    logger.debug(f"Deleting support_seats with id: {id}")
    
    service = Support_seatsService(db)
    try:
        success = await service.delete(id)
        if not success:
            logger.warning(f"Support_seats with id {id} not found for deletion")
            raise HTTPException(status_code=404, detail="Support_seats not found")
        
        logger.info(f"Support_seats {id} deleted successfully")
        return {"message": "Support_seats deleted successfully", "id": id}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error deleting support_seats {id}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")