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.ticket_sync_states import Ticket_sync_statesService
from dependencies.auth import get_current_user
from schemas.auth import UserResponse

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

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


# ---------- Pydantic Schemas ----------
class Ticket_sync_statesData(BaseModel):
    """Entity data schema (for create/update)"""
    snapshot: str


class Ticket_sync_statesUpdateData(BaseModel):
    """Update entity data (partial updates allowed)"""
    snapshot: Optional[str] = None


class Ticket_sync_statesResponse(BaseModel):
    """Entity response schema"""
    id: int
    user_id: str
    snapshot: str
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


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


class Ticket_sync_statesBatchCreateRequest(BaseModel):
    """Batch create request"""
    items: List[Ticket_sync_statesData]


class Ticket_sync_statesBatchUpdateItem(BaseModel):
    """Batch update item"""
    id: int
    updates: Ticket_sync_statesUpdateData


class Ticket_sync_statesBatchUpdateRequest(BaseModel):
    """Batch update request"""
    items: List[Ticket_sync_statesBatchUpdateItem]


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


# ---------- Routes ----------
@router.get("", response_model=Ticket_sync_statesListResponse)
async def query_ticket_sync_statess(
    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"),
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Query ticket_sync_statess with filtering, sorting, and pagination (user can only see their own records)"""
    logger.debug(f"Querying ticket_sync_statess: query={query}, sort={sort}, skip={skip}, limit={limit}, fields={fields}")
    
    service = Ticket_sync_statesService(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,
            user_id=str(current_user.id),
        )
        logger.debug(f"Found {result['total']} ticket_sync_statess")
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error querying ticket_sync_statess: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


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

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


@router.get("/{id}", response_model=Ticket_sync_statesResponse)
async def get_ticket_sync_states(
    id: int,
    fields: str = Query(None, description="Comma-separated list of fields to return"),
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Get a single ticket_sync_states by ID (user can only see their own records)"""
    logger.debug(f"Fetching ticket_sync_states with id: {id}, fields={fields}")
    
    service = Ticket_sync_statesService(db)
    try:
        result = await service.get_by_id(id, user_id=str(current_user.id))
        if not result:
            logger.warning(f"Ticket_sync_states with id {id} not found")
            raise HTTPException(status_code=404, detail="Ticket_sync_states not found")
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error fetching ticket_sync_states {id}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


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


@router.post("/batch", response_model=List[Ticket_sync_statesResponse], status_code=201)
async def create_ticket_sync_statess_batch(
    request: Ticket_sync_statesBatchCreateRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Create multiple ticket_sync_statess in a single request"""
    logger.debug(f"Batch creating {len(request.items)} ticket_sync_statess")
    
    service = Ticket_sync_statesService(db)
    results = []
    
    try:
        for item_data in request.items:
            result = await service.create(item_data.model_dump(), user_id=str(current_user.id))
            if result:
                results.append(result)
        
        logger.info(f"Batch created {len(results)} ticket_sync_statess 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[Ticket_sync_statesResponse])
async def update_ticket_sync_statess_batch(
    request: Ticket_sync_statesBatchUpdateRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Update multiple ticket_sync_statess in a single request (requires ownership)"""
    logger.debug(f"Batch updating {len(request.items)} ticket_sync_statess")
    
    service = Ticket_sync_statesService(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, user_id=str(current_user.id))
            if result:
                results.append(result)
        
        logger.info(f"Batch updated {len(results)} ticket_sync_statess 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=Ticket_sync_statesResponse)
async def update_ticket_sync_states(
    id: int,
    data: Ticket_sync_statesUpdateData,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Update an existing ticket_sync_states (requires ownership)"""
    logger.debug(f"Updating ticket_sync_states {id} with data: {data}")

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


@router.delete("/batch")
async def delete_ticket_sync_statess_batch(
    request: Ticket_sync_statesBatchDeleteRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Delete multiple ticket_sync_statess by their IDs (requires ownership)"""
    logger.debug(f"Batch deleting {len(request.ids)} ticket_sync_statess")
    
    service = Ticket_sync_statesService(db)
    deleted_count = 0
    
    try:
        for item_id in request.ids:
            success = await service.delete(item_id, user_id=str(current_user.id))
            if success:
                deleted_count += 1
        
        logger.info(f"Batch deleted {deleted_count} ticket_sync_statess successfully")
        return {"message": f"Successfully deleted {deleted_count} ticket_sync_statess", "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_ticket_sync_states(
    id: int,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Delete a single ticket_sync_states by ID (requires ownership)"""
    logger.debug(f"Deleting ticket_sync_states with id: {id}")
    
    service = Ticket_sync_statesService(db)
    try:
        success = await service.delete(id, user_id=str(current_user.id))
        if not success:
            logger.warning(f"Ticket_sync_states with id {id} not found for deletion")
            raise HTTPException(status_code=404, detail="Ticket_sync_states not found")
        
        logger.info(f"Ticket_sync_states {id} deleted successfully")
        return {"message": "Ticket_sync_states deleted successfully", "id": id}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error deleting ticket_sync_states {id}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")