from typing import Optional
from fastapi import APIRouter, Query, Depends, HTTPException, UploadFile, File, Path
from sqlalchemy.ext.asyncio import AsyncSession
from starlette import status

from src.cart.schemas import *
from src.database import get_db
from src.user.dependencies import decode_token

from src.cart.service import CartService

router = APIRouter(prefix="/cart", tags=["Корзина"])

@router.get("/current", summary="Отримати поточну корзину")
async def get_current_products(session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        return {
            "data": await CartService.get_current_cart_products(session, current_account['user_id']),
            "status": True
        }

@router.get("/current/product/{current_cart_product_id}", summary="Отримати товар з поточноъ корзини")
async def get_current_cart_product(current_cart_product_id: int, session: AsyncSession = Depends(get_db),
                                   current_account=Depends(decode_token)):
    data = await CartService.get_current_cart_product(session, current_cart_product_id)

    return {
        "data": data,
        "status": True,
    }

@router.post("/current/product", summary="Додати товари в корзину")
async def add_products_to_current_cart(request: AddProductsToCart, session: AsyncSession = Depends(get_db),
                                       current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        if len(request.products) == 0:
            return {
                "data": [],
                "status": False,
                "error": "Виберіть товар для додавання в корзину"
            }

        await CartService.add_current_cart_products(session, current_account['user_id'], request)

        return await get_current_products(session=session, current_account=current_account)

@router.patch("/current/product/{current_cart_product_id}", summary="Редагувати товар в поточній корзині")
async def edit_current_cart_product(current_cart_product_id: int, request: EditCartProduct,
                                    session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    await CartService.edit_current_cart_products(session, current_cart_product_id, request.quantity, request.store_id)

    return await get_current_cart_product(current_cart_product_id=current_cart_product_id, session=session, current_account=current_account)

@router.delete("/current/product/{current_cart_product_id}", summary="Видалити товар з поточної корзини")
async def delete_current_cart_product(current_cart_product_id: int, session: AsyncSession = Depends(get_db),
                                      current_account=Depends(decode_token)):
    await CartService.delete_current_cart_products(session, current_cart_product_id)

    return await get_current_products(session=session, current_account=current_account)

@router.post("/current", summary="Зберегти поточну корзину")
async def save_current_cart(
        request: SaveCart,
        session: AsyncSession = Depends(get_db),
        current_account=Depends(decode_token)
):

    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }

    try:
        cart_service = CartService()
        result = await cart_service.save_current_cart(
            session,
            current_account['user_id'],
            request.name,
            request.product_ids
        )

        return {
            "data": result,
            "status": True
        }
    except HTTPException as e:
        return {
            "data": [],
            "status": False,
            "error": e.detail
        }

@router.delete("/current", summary="Очистити поточну корзину")
async def clear_current_cart(
        session: AsyncSession = Depends(get_db),
        current_account=Depends(decode_token)
):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }

    try:
        cart_service = CartService()
        await cart_service.clear_current_cart(
            session,
            current_account['user_id'],
        )

        return {
            "data": [],
            "status": True
        }
    except HTTPException as e:
        return {
            "data": [],
            "status": False,
            "error": e.detail
        }

@router.get("", summary="Отримати список корзин")
async def get_cart_list(session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        return {
            "data": await CartService.get_cart_list(db=session, customer_id=current_account['user_id']),
            "status": True
        }

@router.get("/{cart_id}/product")
async def get_cart_product(cart_id: int, session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        return {
            "data": await CartService.get_cart_products(db=session, cart_id=cart_id),
            "status": True
        }

@router.delete("/{cart_id}")
async def delete_cart_product(cart_id: int, session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        await CartService.delete_cart_products(db=session, cart_id=cart_id)
        return {
            "data": [],
            "status": True
        }

@router.patch("/{cart_id}/product/{cart_product_id}")
async def edit_cart_product(cart_product_id: int, request:EditCartProduct, session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        await CartService.edit_cart_product(db=session, cart_product_id=cart_product_id, quantity=request.quantity,
                                            store_id=request.store_id)

        return {
            "data": await CartService.get_cart_product(db=session, cart_product_id=cart_product_id),
            "status": True
        }

@router.delete("/{cart_id}/product/{cart_product_id}")
async def delete_cart_product(cart_product_id: int,session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        await CartService.delete_cart_product(db=session, cart_product_id=cart_product_id)
        return {
            "data": [],
            "status": True
        }


@router.post("/{cart_id}/product/{cart_product_id}/transfer/{new_cart_id}")
async def transfer_cart_product(cart_product_id: int, new_cart_id: int, session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": [],
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        result = await CartService.transfer_cart_product(db=session, cart_product_id=cart_product_id, new_cart_id=new_cart_id)
        return {
            "data": result,
            "status": True
        }

@router.post("/{cart_id}/share", summary="Поделиться корзиной")
async def share_cart(cart_id: int, session: AsyncSession = Depends(get_db), current_account=Depends(decode_token)):
    if not current_account['user_id']:
        return {
            "data": None,
            "status": False,
            "error": "Невідомий користувач"
        }
    
    try:
        result = await CartService.share_cart(
            db=session, 
            cart_id=cart_id, 
            customer_id=current_account['user_id']
        )
        
        return {
            "data": result,
            "status": True
        }
    except HTTPException as e:
        return {
            "data": None,
            "status": False,
            "error": e.detail
        }

@router.get("/selected_product")
async def get_selected_products(
        db: AsyncSession = Depends(get_db),
        current_account=Depends(decode_token),
        sort_field: Optional[str] = Query("name", regex="^(name|price|category|date_added|product_id)$", description="Поле сортування"),
        sort_order: Optional[str] = Query("asc", regex="^(asc|desc|ASC|DESC)$", description="Напрям сортування"),
        page: int = Query(1, ge=1, description="Номер сторінки"),
        limit: int = Query(10, ge=1, description="Кількість на сторінці"),
):
    if not current_account['user_id']:
        return {
            "data": None,
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        return await CartService.get_selected_products(db=db, customer_id=current_account['user_id'], page=page, limit=limit, sort_field=sort_field, sort_order=sort_order)


@router.post("/selected_product/{product_id}")
async def toggle_selected_product(
        product_id: int = Path(..., description="ID товару"),
        db: AsyncSession = Depends(get_db),
        current_account=Depends(decode_token)
):
    """
    Переключає товар в обраних: додає якщо немає, видаляє якщо є
    """
    if not current_account['user_id']:
        return {
            "data": None,
            "status": False,
            "error": "Невідомий користувач"
        }
    else:
        return await CartService.toggle_selected_product(
            db=db,
            customer_id=current_account['user_id'],
            product_id=product_id
        )