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.service_testimonials import Service_testimonialsService

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

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


# ---------- Pydantic Schemas ----------
class Service_testimonialsData(BaseModel):
    """Entity data schema (for create/update)"""
    name: str
    company: str
    role: str = None
    quote: str
    rating: int
    avatar_url: str = None
    display_order: int = None
    is_active: bool = None


class Service_testimonialsUpdateData(BaseModel):
    """Update entity data (partial updates allowed)"""
    name: Optional[str] = None
    company: Optional[str] = None
    role: Optional[str] = None
    quote: Optional[str] = None
    rating: Optional[int] = None
    avatar_url: Optional[str] = None
    display_order: Optional[int] = None
    is_active: Optional[bool] = None


class Service_testimonialsResponse(BaseModel):
    """Entity response schema"""
    id: int
    name: str
    company: str
    role: Optional[str] = None
    quote: str
    rating: int
    avatar_url: Optional[str] = None
    display_order: Optional[int] = None
    is_active: Optional[bool] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


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


class Service_testimonialsBatchCreateRequest(BaseModel):
    """Batch create request"""
    items: List[Service_testimonialsData]


class Service_testimonialsBatchUpdateItem(BaseModel):
    """Batch update item"""
    id: int
    updates: Service_testimonialsUpdateData


class Service_testimonialsBatchUpdateRequest(BaseModel):
    """Batch update request"""
    items: List[Service_testimonialsBatchUpdateItem]


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


# ---------- Routes ----------
@router.get("", response_model=Service_testimonialsListResponse)
async def query_service_testimonialss(
    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 service_testimonialss with filtering, sorting, and pagination"""
    logger.debug(f"Querying service_testimonialss: query={query}, sort={sort}, skip={skip}, limit={limit}, fields={fields}")
    
    service = Service_testimonialsService(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']} service_testimonialss")
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error querying service_testimonialss: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.get("/all", response_model=Service_testimonialsListResponse)
async def query_service_testimonialss_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 service_testimonialss with filtering, sorting, and pagination without user limitation
    logger.debug(f"Querying service_testimonialss: query={query}, sort={sort}, skip={skip}, limit={limit}, fields={fields}")

    service = Service_testimonialsService(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']} service_testimonialss")
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error querying service_testimonialss: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


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


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


@router.post("/batch", response_model=List[Service_testimonialsResponse], status_code=201)
async def create_service_testimonialss_batch(
    request: Service_testimonialsBatchCreateRequest,
    db: AsyncSession = Depends(get_db),
):
    """Create multiple service_testimonialss in a single request"""
    logger.debug(f"Batch creating {len(request.items)} service_testimonialss")
    
    service = Service_testimonialsService(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)} service_testimonialss 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[Service_testimonialsResponse])
async def update_service_testimonialss_batch(
    request: Service_testimonialsBatchUpdateRequest,
    db: AsyncSession = Depends(get_db),
):
    """Update multiple service_testimonialss in a single request"""
    logger.debug(f"Batch updating {len(request.items)} service_testimonialss")
    
    service = Service_testimonialsService(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)} service_testimonialss 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=Service_testimonialsResponse)
async def update_service_testimonials(
    id: int,
    data: Service_testimonialsUpdateData,
    db: AsyncSession = Depends(get_db),
):
    """Update an existing service_testimonials"""
    logger.debug(f"Updating service_testimonials {id} with data: {data}")

    service = Service_testimonialsService(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"Service_testimonials with id {id} not found for update")
            raise HTTPException(status_code=404, detail="Service_testimonials not found")
        
        logger.info(f"Service_testimonials {id} updated successfully")
        return result
    except HTTPException:
        raise
    except ValueError as e:
        logger.error(f"Validation error updating service_testimonials {id}: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error updating service_testimonials {id}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.delete("/batch")
async def delete_service_testimonialss_batch(
    request: Service_testimonialsBatchDeleteRequest,
    db: AsyncSession = Depends(get_db),
):
    """Delete multiple service_testimonialss by their IDs"""
    logger.debug(f"Batch deleting {len(request.ids)} service_testimonialss")
    
    service = Service_testimonialsService(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} service_testimonialss successfully")
        return {"message": f"Successfully deleted {deleted_count} service_testimonialss", "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_service_testimonials(
    id: int,
    db: AsyncSession = Depends(get_db),
):
    """Delete a single service_testimonials by ID"""
    logger.debug(f"Deleting service_testimonials with id: {id}")
    
    service = Service_testimonialsService(db)
    try:
        success = await service.delete(id)
        if not success:
            logger.warning(f"Service_testimonials with id {id} not found for deletion")
            raise HTTPException(status_code=404, detail="Service_testimonials not found")
        
        logger.info(f"Service_testimonials {id} deleted successfully")
        return {"message": "Service_testimonials deleted successfully", "id": id}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error deleting service_testimonials {id}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")