from typing import List, Optional
from sqlalchemy.orm import Session
from app.models.order import Order
from app.models.order_item import OrderItem
from app.models.product import Product
from app.repositories.base import BaseRepository
from app.core.exceptions import BadRequestException

class OrderRepository(BaseRepository[Order]):
    """Repository handling checkout actions and customer order retrieval."""

    def create_order_with_items(
        self, 
        db: Session, 
        *, 
        order_obj: Order, 
        items_in: List[dict]
    ) -> Order:
        """Create a order transaction block: saves order, decreases product stock, and inserts order items."""
        try:
            # 1. Simpan order header
            db.add(order_obj)
            db.flush()  # Dapatkan order_obj.id

            total_calculated_price = 0

            # 2. Iterasi & proses order items
            for item in items_in:
                product_id = item["product_id"]
                qty = item["quantity"]

                # Ambil data produk untuk memotong stok dan membaca harga terbaru
                product = db.query(Product).filter(Product.id == product_id, Product.deleted_at == None).first()
                if not product:
                    raise BadRequestException(f"Product not found.")
                
                if product.stock < qty:
                    raise BadRequestException(f"Insufficient stock for product '{product.name}'. Sisa stok: {product.stock}")

                # Kurangi stok produk
                product.stock -= qty
                db.add(product)

                # Hitung subtotal
                subtotal = float(product.price) * qty
                total_calculated_price += subtotal

                # Buat baris detail order item
                order_item = OrderItem(
                    order_id=order_obj.id,
                    product_id=product.id,
                    quantity=qty,
                    price=float(product.price)
                )
                db.add(order_item)

            # Update total price yang terhitung
            order_obj.total_price = total_calculated_price
            db.add(order_obj)
            
            db.commit()
            db.refresh(order_obj)
            return order_obj

        except Exception as e:
            db.rollback()
            raise e

    def get_user_orders(self, db: Session, user_id: str) -> List[Order]:
        """Retrieve all transaction logs belonging to a specific logged-in user."""
        return db.query(self.model).filter(self.model.user_id == user_id).order_by(self.model.created_at.desc()).all()

order_repository = OrderRepository(Order)
