from .models import Order, Product, User
from .services import LABEL


def f(x):
    return float(x) if x is not None else None


def product(p: Product, admin: bool = False) -> dict:
    d = {
        "id": p.id, "sku": p.sku, "name": p.name, "brand": p.brand, "size": p.size,
        "description": p.description, "category": p.category.name if p.category else "",
        "category_id": p.category_id, "price": f(p.price), "stock": p.stock,
        "badge": p.badge, "image_url": p.image_url,
        "in_stock": p.stock > 0, "low": 0 < p.stock <= p.reorder_level,
    }
    if admin:
        d.update(cost=f(p.cost), reorder_level=p.reorder_level, active=p.active,
                 supplier_id=p.supplier_id, margin=f(p.price - p.cost))
    return d


def user(u: User) -> dict:
    return {"id": u.id, "name": u.name, "email": u.email, "phone": u.phone,
            "address": u.address, "role": u.role}


def order(o: Order, admin: bool = False) -> dict:
    d = {
        "number": o.number, "status": o.status, "status_label": LABEL[o.status],
        "payment_method": o.payment_method, "payment_status": o.payment_status,
        "customer_name": o.customer_name, "address": o.address, "zone": o.zone_name,
        "subtotal": f(o.subtotal), "delivery_fee": f(o.delivery_fee), "total": f(o.total),
        "created_at": o.created_at.isoformat(), "note": o.note,
        "items": [{"product_id": i.product_id, "name": i.name, "quantity": i.quantity, "unit_price": f(i.unit_price),
                   "line_total": f(i.unit_price * i.quantity)} for i in o.items],
        "events": [{"status": e.status, "label": LABEL[e.status], "note": e.note,
                    "at": e.at.isoformat()} for e in o.events],
    }
    if admin:
        d.update(phone=o.phone, email=o.email, payment_ref=o.payment_ref,
                 by_account=o.user_id is not None,
                 events=[{"status": e.status, "label": LABEL[e.status], "note": e.note,
                          "by": e.by, "at": e.at.isoformat()} for e in o.events])
    return d
