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.kb_article_feedback import Kb_article_feedbackService

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

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


# ---------- Pydantic Schemas ----------
class Kb_article_feedbackData(BaseModel):
    """Entity data schema (for create/update)"""
    article_id: str
    category_id: str = None
    rating: str
    comment: str = None
    user_id: str = None
    user_email: str = None
    page_url: str = None
    user_agent: str = None


class Kb_article_feedbackUpdateData(BaseModel):
    """Update entity data (partial updates allowed)"""
    article_id: Optional[str] = None
    category_id: Optional[str] = None
    rating: Optional[str] = None
    comment: Optional[str] = None
    user_id: Optional[str] = None
    user_email: Optional[str] = None
    page_url: Optional[str] = None
    user_agent: Optional[str] = None


class Kb_article_feedbackResponse(BaseModel):
    """Entity response schema"""
    id: int
    article_id: str
    category_id: Optional[str] = None
    rating: str
    comment: Optional[str] = None
    user_id: Optional[str] = None
    user_email: Optional[str] = None
    page_url: Optional[str] = None
    user_agent: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


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


class Kb_article_feedbackBatchCreateRequest(BaseModel):
    """Batch create request"""
    items: List[Kb_article_feedbackData]


class Kb_article_feedbackBatchUpdateItem(BaseModel):
    """Batch update item"""
    id: int
    updates: Kb_article_feedbackUpdateData


class Kb_article_feedbackBatchUpdateRequest(BaseModel):
    """Batch update request"""
    items: List[Kb_article_feedbackBatchUpdateItem]


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


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


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

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


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


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


@router.post("/batch", response_model=List[Kb_article_feedbackResponse], status_code=201)
async def create_kb_article_feedbacks_batch(
    request: Kb_article_feedbackBatchCreateRequest,
    db: AsyncSession = Depends(get_db),
):
    """Create multiple kb_article_feedbacks in a single request"""
    logger.debug(f"Batch creating {len(request.items)} kb_article_feedbacks")
    
    service = Kb_article_feedbackService(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)} kb_article_feedbacks 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[Kb_article_feedbackResponse])
async def update_kb_article_feedbacks_batch(
    request: Kb_article_feedbackBatchUpdateRequest,
    db: AsyncSession = Depends(get_db),
):
    """Update multiple kb_article_feedbacks in a single request"""
    logger.debug(f"Batch updating {len(request.items)} kb_article_feedbacks")
    
    service = Kb_article_feedbackService(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)} kb_article_feedbacks 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=Kb_article_feedbackResponse)
async def update_kb_article_feedback(
    id: int,
    data: Kb_article_feedbackUpdateData,
    db: AsyncSession = Depends(get_db),
):
    """Update an existing kb_article_feedback"""
    logger.debug(f"Updating kb_article_feedback {id} with data: {data}")

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


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