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.notification_preferences import Notification_preferencesService
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/notification_preferences", tags=["notification_preferences"])


# ---------- Pydantic Schemas ----------
class Notification_preferencesData(BaseModel):
    """Entity data schema (for create/update)"""
    ticket_reply: bool = None
    ticket_status_change: bool = None
    ticket_new: bool = None
    email: bool = None


class Notification_preferencesUpdateData(BaseModel):
    """Update entity data (partial updates allowed)"""
    ticket_reply: Optional[bool] = None
    ticket_status_change: Optional[bool] = None
    ticket_new: Optional[bool] = None
    email: Optional[bool] = None


class Notification_preferencesResponse(BaseModel):
    """Entity response schema"""
    id: int
    user_id: str
    ticket_reply: Optional[bool] = None
    ticket_status_change: Optional[bool] = None
    ticket_new: Optional[bool] = None
    email: Optional[bool] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


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


class Notification_preferencesBatchCreateRequest(BaseModel):
    """Batch create request"""
    items: List[Notification_preferencesData]


class Notification_preferencesBatchUpdateItem(BaseModel):
    """Batch update item"""
    id: int
    updates: Notification_preferencesUpdateData


class Notification_preferencesBatchUpdateRequest(BaseModel):
    """Batch update request"""
    items: List[Notification_preferencesBatchUpdateItem]


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


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


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

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


@router.get("/{id}", response_model=Notification_preferencesResponse)
async def get_notification_preferences(
    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 notification_preferences by ID (user can only see their own records)"""
    logger.debug(f"Fetching notification_preferences with id: {id}, fields={fields}")
    
    service = Notification_preferencesService(db)
    try:
        result = await service.get_by_id(id, user_id=str(current_user.id))
        if not result:
            logger.warning(f"Notification_preferences with id {id} not found")
            raise HTTPException(status_code=404, detail="Notification_preferences not found")
        
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error fetching notification_preferences {id}: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.post("", response_model=Notification_preferencesResponse, status_code=201)
async def create_notification_preferences(
    data: Notification_preferencesData,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Create a new notification_preferences"""
    logger.debug(f"Creating new notification_preferences with data: {data}")
    
    service = Notification_preferencesService(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 notification_preferences")
        
        logger.info(f"Notification_preferences created successfully with id: {result.id}")
        return result
    except ValueError as e:
        logger.error(f"Validation error creating notification_preferences: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error creating notification_preferences: {str(e)}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.post("/batch", response_model=List[Notification_preferencesResponse], status_code=201)
async def create_notification_preferencess_batch(
    request: Notification_preferencesBatchCreateRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Create multiple notification_preferencess in a single request"""
    logger.debug(f"Batch creating {len(request.items)} notification_preferencess")
    
    service = Notification_preferencesService(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)} notification_preferencess 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[Notification_preferencesResponse])
async def update_notification_preferencess_batch(
    request: Notification_preferencesBatchUpdateRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Update multiple notification_preferencess in a single request (requires ownership)"""
    logger.debug(f"Batch updating {len(request.items)} notification_preferencess")
    
    service = Notification_preferencesService(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)} notification_preferencess 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=Notification_preferencesResponse)
async def update_notification_preferences(
    id: int,
    data: Notification_preferencesUpdateData,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Update an existing notification_preferences (requires ownership)"""
    logger.debug(f"Updating notification_preferences {id} with data: {data}")

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


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