"""
Product API router with CRUD operations.
"""

from typing import List, Optional, Dict, Union, Any
from fastapi import (
    APIRouter,
    Depends,
    HTTPException,
    status,
    Query,
    UploadFile,
    File as FastAPIFile,
    Form,
    Path,
)
from sqlalchemy.orm import Session

from src.apps.notes.schemas.note_requests import NoteCreateRequestSchema, NoteUpdateRequestSchema
from src.core.database import get_db
from src.apps.auth.utils.auth import get_current_user, get_current_merchant
from src.apps.merchants.schemas.merchant_common import MerchantSchema
from src.apps.users.schemas.user_common import UserSchema
from src.apps.products import services
from src.apps.products.schemas.common import ProductResponseSchema, ProductCreateSchema, ProductUpdateSchema,ProductListFilterSchema,ProductBulkDeleteSchema
from src.apps.base.utils import regexp
from src.core.utils import constants
from src.core.utils.enums import FileTypes

router = APIRouter()

@router.get("/", response_model=Dict[str, Any])
async def get_products_list(
    db: Session = Depends(get_db),
    # merchant: MerchantSchema = Depends(get_current_merchant),
    filters: ProductListFilterSchema = Depends(),
    _from: Optional[str] = Query(
        default=None,
        pattern=regexp.ISO_DATE_FORMAT,
        description="Start date of listing to be done. Must be of format YYYY-MM-DD",
    ),
    _to: Optional[str] = Query(
        default=None,
        pattern=regexp.ISO_DATE_FORMAT,
        description="End date of listing to be done. Must be of format YYYY-MM-DD",
    ),
    sort_by: str = Query(
        default="-created_at",
        description="Sort column name with direction. Prepend '-' to sort descending. E.g: ?sort_by=-created_at",
    ),
    fields: str = Query(
        default=None,
        description="Additional related fields that are requested. Could be any of ...",
    ),
    page: int = Query(
        default=1,
        ge=1,
        description="Number of page that needs to be fetched from the records",
    ),
    per_page: int = Query(
        default=constants.DEFAULT_PER_PAGE,
        ge=1,
        le=constants.MAX_PER_PAGE,
        description="Number of page that needs to be fetched from the records",
    ),
) -> Any:
    """
    Retrieve products with filtering and pagination.
    """
    # Calculate offset from page
    skip = (page - 1) * per_page
    
    # Get products using services
    result = await services.get_products_list(
        db=db,
        filters=filters,
        _from=_from,
        _to=_to,
        sort_by=sort_by,
        fields=fields,
        skip=skip,
        limit=per_page,
        paginate=True,
    )
    
    return result


@router.post("/", response_model=ProductResponseSchema)
async def create_product(
    payload: ProductCreateSchema,
    db: Session = Depends(get_db),
    # current_merchant: MerchantSchema = Depends(get_current_merchant),
    # current_user: UserSchema = Depends(get_current_user)
):
    """
    Create a new product.
    """
    return await services.create_product(
        db=db, 
        # merchant_id=current_user.id,
        payload=payload
    )


@router.get("/{slug}", response_model=ProductResponseSchema)
async def get_product(
    slug: str,
    db: Session = Depends(get_db),
    # current_merchant: MerchantSchema = Depends(get_current_merchant),
    # current_user: UserSchema = Depends(get_current_user)
):
    """
    Get a product by slug.
    """
    product = await services.get_product(
        db=db, 
        # merchant_id=current_user.id,
        slug=slug
    )
    if not product:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Product not found"
        )
    return product


@router.put("/{slug}", response_model=ProductResponseSchema)
async def update_product(
    slug: str,
    payload: ProductUpdateSchema,
    db: Session = Depends(get_db),
    # current_merchant: MerchantSchema = Depends(get_current_merchant),
    # current_user: UserSchema = Depends(get_current_user),
):
    """
    Update a product by slug.
    """
    updated_product = await services.update_product(
        db=db, 
        # merchant_id=current_user.id,
        slug=slug, 
        payload=payload
    )
    if not updated_product:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Product not found"
        )
    return updated_product


@router.delete("/{slug}")
async def delete_product(
    slug: str,
    db: Session = Depends(get_db),
    # current_merchant: MerchantSchema = Depends(get_current_merchant),
    # current_user: UserSchema = Depends(get_current_user)
):
    """
    Delete a product by slug.
    """
    success = await services.delete_product(
        db=db, 
        # merchant_id=current_user.id,
        slug=slug
    )
    if not success:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Product not found"
        )
    return {"message": "Product deleted successfully"}


@router.post("/bulk-delete")
async def bulk_delete_products(
    bulk_delete_data: ProductBulkDeleteSchema,
    db: Session = Depends(get_db),
    # current_merchant: MerchantSchema = Depends(get_current_merchant),
    # current_user: UserSchema = Depends(get_current_user)
):
    """
    Delete multiple products by slugs.
    """
    deleted_count = await services.bulk_delete_products(
        db=db, 
        # merchant_id=current_user.id,
        slugs=bulk_delete_data.slugs
    )
    return {
        "message": f"Successfully deleted {deleted_count} products",
        "deleted_count": deleted_count
    }


# Attachments endpoints
@router.post(
    "/{slug}/attachments",
    name="Upload multiple attachments files",
    response_model=Dict[str, Any],
)
async def create_multiple_files(
    files: List[UploadFile] = FastAPIFile(...),
    file_type: FileTypes = Form(default=FileTypes.GALLERY),
    db: Session = Depends(get_db),
    current_user: UserSchema = Depends(get_current_user),
    merchant: MerchantSchema = Depends(get_current_merchant),
    slug: str = Path(..., description="The unqiue slug of the product."),
) -> Dict[str, Any]:
    response = await services.upload_attachments_files(
        db=db,
        files=files,
        file_type=str(file_type.value) if hasattr(file_type, "value") else str(file_type),
        current_user=current_user,
        merchant=merchant,
        slug=slug,
    )
    return {"data": response, "message": "Attachment files uploaded successfully"}


@router.delete(
    "/{slug}/attachments/{file_id}",
    name="Delete attachments files",
    response_model=Dict[str, Any],
)
async def delete_attachments_files(
    db: Session = Depends(get_db),
    current_user: UserSchema = Depends(get_current_user),
    merchant: MerchantSchema = Depends(get_current_merchant),
    slug: str = Path(..., description="The unqiue slug of the product."),
    file_id: int = Path(..., description="The unique Id of the file."),
) -> Dict[str, Any]:
    response = await services.delete_attachments_files(
        db=db,
        slug=slug,
        merchant=merchant,
        file_id=file_id,
        current_user=current_user,
    )
    return {"data": response, "message": "Attachments Files deleted successfully"}


# Notes endpoints
@router.post(
    "/{slug}/notes",
    name="Add note for Product",
    response_model=Dict[str, Any],
)
async def create_note(
    payload: NoteCreateRequestSchema,
    slug: str = Path(
        ...,
        description="The slug of the product.",
    ),
    db: Session = Depends(get_db),
    current_user: UserSchema = Depends(get_current_user),
    merchant: MerchantSchema = Depends(get_current_merchant),
) -> Dict[str, Any]:
    response = await services.create_note(
        db=db,
        payload=payload,
        slug=slug,
        merchant=merchant,
        created_by=current_user,
    )
    return {"data": response, "message": "Note created successfully"}


@router.put(
    "/{slug}/notes/{note_id}",
    name="Add note for Product",
    response_model=Dict[str, Any],
)
async def update_note(
    payload: NoteUpdateRequestSchema,
    slug: str = Path(
        ...,
        description="The slug of the product.",
    ),
    note_id: int = Path(..., description="Id of the Note"),
    db: Session = Depends(get_db),
    current_user: UserSchema = Depends(get_current_user),
) -> Dict[str, Any]:
    response = await services.update_note(
        db=db, payload=payload, slug=slug, note_id=note_id
    )
    return {"data": response, "message": "Note updated successfully"}


@router.get(
    "/{slug}/notes",
    name="Get all product notes",
    response_model=Dict[str, Any],
)
async def list_note(
    slug: str = Path(
        ...,
        description="The slug of the product.",
    ),
    db: Session = Depends(get_db),
    merchant: MerchantSchema = Depends(get_current_merchant),
) -> Dict[str, Any]:
    response = await services.list_note(db=db, slug=slug, merchant=merchant)
    return {"data": response, "message": "Note fetched successfully"}


@router.get(
    "/{slug}/activities",
    name="Get all customer activities",
    response_model=Dict[str, Any],
)
async def activities(
    slug: str = Path(
        ...,
        description="The slug of the product",
    ),
    db: Session = Depends(get_db),
    merchant: MerchantSchema = Depends(get_current_merchant),
) -> Dict[str, Any]:
    response = await services.activities(db=db, slug=slug, merchant=merchant)
    return {"data": response, "message": "Activities fetched successfully"}