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


# ---------- Pydantic Schemas ----------
class Order_itemsData(BaseModel):
    """Entity data schema (for create/update)"""
    order_id: int
    product_id: int
    product_name: str = None
    product_type: str = None
    variant_label: str = None
    unit_price: float = None
    quantity: int
    line_total: float = None
    download_url: str = None
    license_key: str = None


class Order_itemsUpdateData(BaseModel):
    """Update entity data (partial updates allowed)"""
    order_id: Optional[int] = None
    product_id: Optional[int] = None
    product_name: Optional[str] = None
    product_type: Optional[str] = None
    variant_label: Optional[str] = None
    unit_price: Optional[float] = None
    quantity: Optional[int] = None
    line_total: Optional[float] = None
    download_url: Optional[str] = None
    license_key: Optional[str] = None


class Order_itemsResponse(BaseModel):
    """Entity response schema"""
    id: int
    user_id: str
    order_id: int
    product_id: int
    product_name: Optional[str] = None
    product_type: Optional[str] = None
    variant_label: Optional[str] = None
    unit_price: Optional[float] = None
    quantity: int
    line_total: Optional[float] = None
    download_url: Optional[str] = None
    license_key: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    class Config:
        from_attributes = True


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


class Order_itemsBatchCreateRequest(BaseModel):
    """Batch create request"""
    items: List[Order_itemsData]


class Order_itemsBatchUpdateItem(BaseModel):
    """Batch update item"""
    id: int
    updates: Order_itemsUpdateData


class Order_itemsBatchUpdateRequest(BaseModel):
    """Batch update request"""
    items: List[Order_itemsBatchUpdateItem]


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


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


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

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


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


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


@router.post("/batch", response_model=List[Order_itemsResponse], status_code=201)
async def create_order_itemss_batch(
    request: Order_itemsBatchCreateRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Create multiple order_itemss in a single request"""
    logger.debug(f"Batch creating {len(request.items)} order_itemss")
    
    service = Order_itemsService(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)} order_itemss 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[Order_itemsResponse])
async def update_order_itemss_batch(
    request: Order_itemsBatchUpdateRequest,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Update multiple order_itemss in a single request (requires ownership)"""
    logger.debug(f"Batch updating {len(request.items)} order_itemss")
    
    service = Order_itemsService(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)} order_itemss 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=Order_itemsResponse)
async def update_order_items(
    id: int,
    data: Order_itemsUpdateData,
    current_user: UserResponse = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """Update an existing order_items (requires ownership)"""
    logger.debug(f"Updating order_items {id} with data: {data}")

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


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