from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.params import Path, Query
from sqlalchemy.orm import Session
from src.apps.wine.producer.schemas.producer_noise import (
    ProducerNoiseAdditionSchema,
    ProducerNoiseFilterSchema,
    ProducerNoiseOutputSchema,
    ProducerNoiseUpdateSchema,
    ProducerNoiseAdditionWithWineDBId
)
from src.apps.wine.producer.services.producer_noise import (
    create_producer_noise,
    update_producer_noise,
    get_all_producer_noises,
    get_producer_noise_by_id,
    delete_producer_noise,
    create_producer_noise_with_wine_db_id,
    remove_producer_noise_by_wine_db_id,
    download_noise_service
)
from src.core.dependencies import get_db
from src.utils import constants
from src.utils.guard import get_current_user
from src.apps.base.schemas.response_model import ResponseModel

router = APIRouter()


@router.get("", response_model=ResponseModel, summary="Get all producer noises")
async def get_all_producer_noises_list(
    payload: ProducerNoiseFilterSchema = Depends(),
    sort_by: str = Query(
        default="-date_created",
        description="Sort by fields, use '-' for descending order (e.g., -date_created,noise)",
    ),
    page: int = Query(default=1, ge=1, description="Page number"),
    per_page: int = Query(
        default=constants.DEFAULT_PER_PAGE,
        ge=1,
        le=constants.MAX_PER_PAGE,
        description="Items per page",
    ),
    db: Session = Depends(get_db),
):
    response= await get_all_producer_noises(
        db, 
        page=page, 
        per_page=per_page, 
        payload=payload, 
        sort_by=sort_by.split(",") if sort_by else []
    )
    
    return ResponseModel(
        data=response, 
        status_code=status.HTTP_200_OK, 
        success=True,
        message="Record fetched successfully"
    )
    
@router.get("/download", summary="Download all producer noise entries")
async def download_producer_noise_list(
    payload: ProducerNoiseFilterSchema = Depends(),
    db: Session = Depends(get_db),
):
    """
    Download all producer noise entries based on the provided filter criteria.
    Args:
        payload (ProducerNoiseFilterSchema): Filter criteria for producer noises.
        db (Session): Database session dependency.
    Returns:
        StreamingResponse: A streaming response containing the producer noise data in TSV format.
    """
    return await download_noise_service(db=db, payload=payload)
    
@router.post("", response_model=ResponseModel, status_code=status.HTTP_201_CREATED, summary="Create a new producer noise")
async def create_new_producer_noise(
    payload: ProducerNoiseAdditionSchema,
    db: Session = Depends(get_db),
):
    new_noise = await create_producer_noise(db, payload)
    return ResponseModel(
        data=new_noise,
        status_code=status.HTTP_201_CREATED,
        success=True,
        message="Producer noise created successfully"
    )

@router.post("/by-wine-db-id", response_model=ResponseModel, status_code=status.HTTP_201_CREATED, summary="Add producer noise by Wine DB ID")
async def add_producer_noise_by_wine_db_id(
    payload: ProducerNoiseAdditionWithWineDBId,
    db: Session = Depends(get_db),
):
    new_noise = await create_producer_noise_with_wine_db_id(db, payload)
    return ResponseModel(
        data=new_noise,
        status_code=status.HTTP_201_CREATED,
        success=True,
        message="Producer noise added successfully"
    )
    
@router.delete("/by-wine-db-id", response_model=ResponseModel, summary="Remove producer noise by Wine DB ID")
async def remove_producer_noise_by_wine_db_id_entry(
    payload: ProducerNoiseAdditionWithWineDBId,
    db: Session = Depends(get_db),
):
    data = await remove_producer_noise_by_wine_db_id(db, payload)
    return ResponseModel(
        data=data,
        status_code=status.HTTP_200_OK,
        success=True,
        message="Producer noise removed successfully"
    )
    
@router.get("/{producer_noise_id}", response_model=ResponseModel, summary="Get producer noise by ID")
async def get_producer_noise(
    producer_noise_id: int,
    db: Session = Depends(get_db),
):
    noise = await get_producer_noise_by_id(db, producer_noise_id)
    return ResponseModel(
        data=ProducerNoiseOutputSchema.model_validate(noise),
        status_code=status.HTTP_200_OK,
        success=True,
        message="Producer noise fetched successfully"
    )
    
@router.put("/{producer_noise_id}", response_model=ResponseModel, summary="Update a producer noise")
async def update_producer_noise_entry(
    producer_noise_id: int,
    payload: ProducerNoiseUpdateSchema,
    db: Session = Depends(get_db),
):
    updated_noise = await update_producer_noise(db, producer_noise_id, payload)
    return ResponseModel(
        data=updated_noise,
        status_code=status.HTTP_200_OK,
        success=True,
        message="Producer noise updated successfully"
    )
    
@router.delete("/{producer_noise_id}", response_model=ResponseModel, summary="Delete a producer noise")
async def delete_producer_noise_entry(
    producer_noise_id: int,
    db: Session = Depends(get_db),
):
    data = await delete_producer_noise(db, producer_noise_id)
    return ResponseModel(
        data=data,
        status_code=status.HTTP_200_OK,
        success=True,
        message="Producer noise deleted successfully"
    )

    
    
