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.chat_analytics_daily import Chat_analytics_dailyService

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

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


# ---------- Pydantic Schemas ----------
class Chat_analytics_dailyData(BaseModel):
    """Entity data schema (for create/update)"""
    date: date
    department_id: int = None
    total_chats: int = None
    ai_resolved: int = None
    human_resolved: int = None
    avg_first_response_sec: int = None
    avg_resolution_sec: int = None
    sla_breaches: int = None
    escalations: int = None


class Chat_analytics_dailyUpdateData(BaseModel):
    """Update entity data (partial updates allowed)"""
    date: Optional[date] = None
    department_id: Optional[int] = None
    total_chats: Optional[int] = None
    ai_resolved: Optional[int] = None
    human_resolved: Optional[int] = None
    avg_first_response_sec: Optional[int] = None
    avg_resolution_sec: Optional[int] = None
    sla_breaches: Optional[int] = None
    escalations: Optional[int] = None


class Chat_analytics_dailyResponse(BaseModel):
    """Entity response schema"""
    id: int
    date: date
    department_id: Optional[int] = None
    total_chats: Optional[int] = None
    ai_resolved: Optional[int] = None
    human_resolved: Optional[int] = None
    avg_first_response_sec: Optional[int] = None
    avg_resolution_sec: Optional[int] = None
    sla_breaches: Optional[int] = None
    escalations: Optional[int] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


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


class Chat_analytics_dailyBatchCreateRequest(BaseModel):
    """Batch create request"""
    items: List[Chat_analytics_dailyData]


class Chat_analytics_dailyBatchUpdateItem(BaseModel):
    """Batch update item"""
    id: int
    updates: Chat_analytics_dailyUpdateData


class Chat_analytics_dailyBatchUpdateRequest(BaseModel):
    """Batch update request"""
    items: List[Chat_analytics_dailyBatchUpdateItem]


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


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


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

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


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


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


@router.post("/batch", response_model=List[Chat_analytics_dailyResponse], status_code=201)
async def create_chat_analytics_dailys_batch(
    request: Chat_analytics_dailyBatchCreateRequest,
    db: AsyncSession = Depends(get_db),
):
    """Create multiple chat_analytics_dailys in a single request"""
    logger.debug(f"Batch creating {len(request.items)} chat_analytics_dailys")
    
    service = Chat_analytics_dailyService(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)} chat_analytics_dailys 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[Chat_analytics_dailyResponse])
async def update_chat_analytics_dailys_batch(
    request: Chat_analytics_dailyBatchUpdateRequest,
    db: AsyncSession = Depends(get_db),
):
    """Update multiple chat_analytics_dailys in a single request"""
    logger.debug(f"Batch updating {len(request.items)} chat_analytics_dailys")
    
    service = Chat_analytics_dailyService(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)} chat_analytics_dailys 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=Chat_analytics_dailyResponse)
async def update_chat_analytics_daily(
    id: int,
    data: Chat_analytics_dailyUpdateData,
    db: AsyncSession = Depends(get_db),
):
    """Update an existing chat_analytics_daily"""
    logger.debug(f"Updating chat_analytics_daily {id} with data: {data}")

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


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