from sqlalchemy.orm import Session
from app.models import Order, OrderItem, Cart, CartItem, Product
from app.schemas.order import OrderCreate, OrderItemCreate
from typing import Optional
import uuid
from datetime import datetime


def create_order(db: Session, user_id: int, order_data: OrderCreate) -> Optional[Order]:
    cart = db.query(Cart).filter(Cart.user_id == user_id).first()
    if not cart or not cart.items:
        return None

    total_amount = 0
    order_items_data = []

    for cart_item in cart.items:
        product = cart_item.product
        price = product.discount_price if product.discount_price else product.price
        total_amount += price * cart_item.quantity

        order_items_data.append({
            "product_id": product.id,
            "quantity": cart_item.quantity,
            "price": price,
            "size": cart_item.size,
            "color": cart_item.color,
        })

    order_number = f"ORD-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}-{uuid.uuid4().hex[:6].upper()}"

    order_dict = order_data.model_dump() if hasattr(order_data, 'model_dump') else order_data.dict()
    order = Order(
        user_id=user_id,
        order_number=order_number,
        status="pending",
        total_amount=total_amount,
        **order_dict,
    )

    db.add(order)
    db.flush()

    for item_data in order_items_data:
        order_item = OrderItem(order_id=order.id, **item_data)
        db.add(order_item)
        product = db.query(Product).filter(Product.id == item_data["product_id"]).first()
        product.stock -= item_data["quantity"]

    # Clear cart
    db.query(CartItem).filter(CartItem.cart_id == cart.id).delete()

    db.commit()
    db.refresh(order)
    return order


def get_order_by_id(db: Session, order_id: int) -> Optional[Order]:
    return db.query(Order).filter(Order.id == order_id).first()


def get_user_orders(db: Session, user_id: int) -> list:
    return db.query(Order).filter(Order.user_id == user_id).all()


def update_order_status(db: Session, order_id: int, status: str) -> Optional[Order]:
    order = get_order_by_id(db, order_id)
    if not order:
        return None

    order.status = status
    db.commit()
    db.refresh(order)
    return order
