from fastapi import APIRouter, File, Form, UploadFile, Depends, HTTPException
from sqlalchemy.orm import Session
from models.user import User
from models.order_modals import DesignerCakeOrder
from db import get_db
from routes.order_routes import get_current_user
from datetime import datetime
import pytz, os
from typing import Optional

IST = pytz.timezone("Asia/Kolkata")
router = APIRouter()

# Helper to save file
def save_file(upload_dir: str, file: UploadFile) -> str:
    os.makedirs(upload_dir, exist_ok=True)
    file_path = os.path.join(upload_dir, file.filename)
    with open(file_path, "wb") as f:
        f.write(file.file.read())
    return file_path

# Place order
@router.post("/designer-cake/order")
def place_designer_cake_order(
    theme: str = Form(...),
    weight: float = Form(...),
    factory_id: int = Form(...),
    quantity: int = Form(...),
    price: float = Form(...),
    message_on_cake: str = Form(None),
    design_image: UploadFile = File(...),
    print_image: UploadFile = File(...),
    instruction_audio: UploadFile = File(None),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    if current_user.role not in ["MAIN_STORE", "STORE"]:
        raise HTTPException(status_code=403, detail="Only stores can order designer cakes")

    factory = db.query(User).filter(User.id == factory_id, User.role == "FACTORY").first()
    if not factory:
        raise HTTPException(status_code=404, detail="Factory not found")

    order = DesignerCakeOrder(
        user_id=current_user.id,
        factory_id=factory.id,
        theme=theme,
        weight=weight,
        price=price,
        quantity=quantity,
        message_on_cake=message_on_cake,
        image_url=save_file("media/designs", design_image),
        print_image_url=save_file("media/prints", print_image),
        audio_url=save_file("media/audio", instruction_audio) if instruction_audio else None,
        created_at=datetime.now(IST),
        order_status="PLACED"
    )

    db.add(order)
    db.commit()
    db.refresh(order)

    return {
        "designer_order_id": order.id,
        "theme": theme,
        "price": price,
        "quantity": quantity,
        "design_image": order.image_url,
        "print_image": order.print_image_url,
        "audio_instruction": order.audio_url,
        "message": "Designer cake order placed"
    }

# Get orders
@router.get("/designer-cake/orders")
def get_all_designer_cake_orders(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    query = db.query(DesignerCakeOrder)
    if current_user.role == "STORE":
        query = query.filter(DesignerCakeOrder.user_id == current_user.id)

    orders = query.all()
    return [{
        "designer_order_id": o.id,
        "theme": o.theme,
        "weight": o.weight,
        "price": o.price,
        "quantity": o.quantity,
        "message_on_cake": o.message_on_cake,
        "design_image": o.image_url,
        "print_image": o.print_image_url,
        "audio_instruction": o.audio_url,
        "order_status": getattr(o, "order_status", "PLACED"),
        "factory_id": o.factory_id,
        "user_id": o.user_id,
        "created_at": o.created_at.astimezone(IST).strftime("%Y-%m-%d %H:%M:%S") if o.created_at else None
    } for o in orders]

# Update order
@router.put("/designer-cake/orders/{designer_order_id}/update")
def update_designer_cake_order(
    designer_order_id: int,
    theme: Optional[str] = Form(None),
    weight: Optional[float] = Form(None),
    price: Optional[float] = Form(None),
    quantity: Optional[int] = Form(None),
    message_on_cake: Optional[str] = Form(None),
    design_image: Optional[UploadFile] = File(None),
    print_image: Optional[UploadFile] = File(None),
    audio_instruction: Optional[UploadFile] = File(None),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    order = db.query(DesignerCakeOrder).filter(DesignerCakeOrder.id == designer_order_id).first()
    if not order:
        raise HTTPException(status_code=404, detail="Designer cake order not found")
    if current_user.role == "STORE" and order.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Not authorized to update this order")

    if theme: order.theme = theme
    if weight: order.weight = weight
    if price: order.price = price
    if quantity: order.quantity = quantity
    if message_on_cake: order.message_on_cake = message_on_cake
    if design_image: order.image_url = save_file("media/designs", design_image)
    if print_image: order.print_image_url = save_file("media/prints", print_image)
    if audio_instruction: order.audio_url = save_file("media/audio", audio_instruction)

    db.commit()
    db.refresh(order)

    return {
        "designer_order_id": order.id,
        "theme": order.theme,
        "weight": order.weight,
        "price": order.price,
        "quantity": order.quantity,
        "message_on_cake": order.message_on_cake,
        "design_image": order.image_url,
        "print_image": order.print_image_url,
        "audio_instruction": order.audio_url,
        "message": "Designer cake order updated"
    }

# Accept order
@router.put("/designer-cake/orders/{designer_order_id}/accept")
def accept_designer_cake_order(
    designer_order_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    if current_user.role != "FACTORY":
        raise HTTPException(status_code=403, detail="Only FACTORY can accept orders")

    order = db.query(DesignerCakeOrder).filter(DesignerCakeOrder.id == designer_order_id).first()
    if not order or order.factory_id != current_user.id:
        raise HTTPException(status_code=403, detail="Unauthorized or not found")

    order.order_status = "ACCEPTED"
    db.commit()
    return {"designer_order_id": order.id, "status": order.order_status, "message": "Order accepted by factory"}

# Reject order
@router.put("/designer-cake/orders/{designer_order_id}/reject")
def reject_designer_cake_order(
    designer_order_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    if current_user.role != "FACTORY":
        raise HTTPException(status_code=403, detail="Only FACTORY can reject orders")

    order = db.query(DesignerCakeOrder).filter(DesignerCakeOrder.id == designer_order_id).first()
    if not order or order.factory_id != current_user.id:
        raise HTTPException(status_code=403, detail="Unauthorized or not found")

    order.order_status = "REJECTED"
    db.commit()
    return {"designer_order_id": order.id, "status": order.order_status, "message": "Order rejected by factory"}

# Ship order
@router.put("/designer-cake/orders/{designer_order_id}/ship")
def ship_designer_cake_order(
    designer_order_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    if current_user.role != "FACTORY":
        raise HTTPException(status_code=403, detail="Only FACTORY can ship orders")

    order = db.query(DesignerCakeOrder).filter(DesignerCakeOrder.id == designer_order_id).first()
    if not order or order.factory_id != current_user.id:
        raise HTTPException(status_code=403, detail="Unauthorized or not found")
    if order.order_status != "ACCEPTED":
        raise HTTPException(status_code=400, detail="Order must be accepted before shipping")

    order.order_status = "SHIPPED"
    db.commit()
    return {"designer_order_id": order.id, "status": order.order_status, "message": "Order shipped by factory"}

# Receive order
@router.put("/designer-cake/orders/{designer_order_id}/receive")
def receive_designer_cake_order(
    designer_order_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    if current_user.role not in ["STORE", "MAIN_STORE"]:
        raise HTTPException(status_code=403, detail="Only STORE or MAIN_STORE can receive orders")

    order = db.query(DesignerCakeOrder).filter(DesignerCakeOrder.id == designer_order_id).first()
    if not order:
        raise HTTPException(status_code=404, detail="Designer cake order not found")
    if current_user.role == "STORE" and order.user_id != current_user.id:
        raise HTTPException(status_code=403, detail="Unauthorized to receive this order")

    order.order_status = "RECEIVED"
    db.commit()
    return {
        "designer_order_id": order.id,
        "status": order.order_status,
        "message": "Designer cake order marked as received"
    }
