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


# ---------- Pydantic Schemas ----------
class Product_reviewsData(BaseModel):
    """Entity data schema (for create/update)"""
    product_id: int
    rating: int
    title: str = None
    comment: str = None
    is_approved: bool = None


class Product_reviewsUpdateData(BaseModel):
    """Update entity data (partial updates allowed)"""
    product_id: Optional[int] = None
    rating: Optional[int] = None
    title: Optional[str] = None
    comment: Optional[str] = None
    is_approved: Optional[bool] = None


class Product_reviewsResponse(BaseModel):
    """Entity response schema"""
    id: int
    user_id: str
    product_id: int
    rating: int
    title: Optional[str] = None
    comment: Optional[str] = None
    is_approved: Optional[bool] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


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


class Product_reviewsBatchCreateRequest(BaseModel):
    """Batch create request"""
    items: List[Product_reviewsData]


class Product_reviewsBatchUpdateItem(BaseModel):
    """Batch update item"""
    id: int
    updates: Product_reviewsUpdateData


class Product_reviewsBatchUpdateRequest(BaseModel):
    """Batch update request"""
    items: List[Product_reviewsBatchUpdateItem]


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


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


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

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


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


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


@router.post("/batch", response_model=List[Product_reviewsResponse], status_code=201)
async def create_product_reviewss_batch(
    request: Product_reviewsBatchCreateRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Create multiple product_reviewss in a single request"""
    logger.debug(f"Batch creating {len(request.items)} product_reviewss")
    
    service = Product_reviewsService(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)} product_reviewss 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[Product_reviewsResponse])
async def update_product_reviewss_batch(
    request: Product_reviewsBatchUpdateRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Update multiple product_reviewss in a single request (requires ownership)"""
    logger.debug(f"Batch updating {len(request.items)} product_reviewss")
    
    service = Product_reviewsService(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)} product_reviewss 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=Product_reviewsResponse)
async def update_product_reviews(
    id: int,
    data: Product_reviewsUpdateData,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Update an existing product_reviews (requires ownership)"""
    logger.debug(f"Updating product_reviews {id} with data: {data}")

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


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