from pydantic import BaseModel
from datetime import datetime
from typing import Optional, List
from schemas.base import UTCDatetime


class SelectedOptionInput(BaseModel):
    id: Optional[int] = None
    name: Optional[str] = None
    price_delta: Optional[float] = None
    extra_cost: Optional[float] = None
    # type tags: "quick" | "pref" | "pref_sub" | "extra" | "extra_sub"
    # Omitted by old clients — print code falls back gracefully.
    type: Optional[str] = None


class OrderItemInput(BaseModel):
    product_id: int
    quantity: float
    selected_options: Optional[List[SelectedOptionInput]] = None
    removed_ingredients: Optional[List[str]] = None
    notes: Optional[str] = None
    price_adjustment: Optional[float] = None  # on-the-fly price delta, applied at add-time
    is_service_item: bool = False             # priceless: print-once ephemeral; priced: saved as real item
    course_id: Optional[int] = None


class AddItemsRequest(BaseModel):
    items: List[OrderItemInput]
    order_note: Optional[str] = None  # whole-order note, written to Order.notes
    customer_count: Optional[int] = None  # number of customers at the table


class ProductNameOut(BaseModel):
    id: int
    name: str
    model_config = {"from_attributes": True}


class OrderItemOut(BaseModel):
    id: int
    order_id: int
    product_id: int
    product: Optional[ProductNameOut] = None
    added_by: int
    quantity: float
    unit_type: str = "piece"
    unit_price: float
    selected_options: Optional[str] = None
    removed_ingredients: Optional[str] = None
    notes: Optional[str] = None
    status: str
    kds_status: str = "pending"
    added_at: UTCDatetime
    printed: bool
    paid_by: Optional[int] = None
    paid_at: Optional[UTCDatetime] = None
    payment_method: Optional[str] = None
    paid_in_shift_id: Optional[int] = None
    price_adjustment: float = 0.0
    course_id: Optional[int] = None
    deal_id: Optional[int] = None
    linked_item_id: Optional[int] = None

    model_config = {"from_attributes": True}


class PrintResultOut(BaseModel):
    printer_name: str
    success: bool
    error: Optional[str] = None


class AddItemsResponse(BaseModel):
    order: "OrderOut"
    print_results: List[PrintResultOut]
    deal_offers: List[dict] = []  # DealOfferOut dicts — serialized to avoid circular imports

    model_config = {"from_attributes": True}


class OrderCreate(BaseModel):
    table_id: Optional[int] = None
    order_type: Optional[str] = "here"  # here | takeaway | delivery


class PayItemsRequest(BaseModel):
    item_ids: List[int]
    payment_method: Optional[str] = None  # 'cash' | 'card' | 'other' — optional for now


class OfflinePaymentRequest(BaseModel):
    uuid: str                          # client-generated UUID, used for duplicate detection
    item_ids: List[int]
    payment_method: Optional[str] = None
    offline_at: Optional[str] = None   # ISO timestamp of when payment was taken offline


class AssignWaiterRequest(BaseModel):
    waiter_id: int


class OrderWaiterOut(BaseModel):
    waiter_id: int
    model_config = {"from_attributes": True}


class AuditLogOut(BaseModel):
    id: int
    order_id: int
    event_type: str
    waiter_id: Optional[int] = None
    waiter_name: Optional[str] = None   # resolved server-side
    item_ids: Optional[str] = None
    amount: Optional[float] = None
    payment_method: Optional[str] = None
    note: Optional[str] = None
    created_at: UTCDatetime
    offline_at: Optional[str] = None
    is_duplicate: int = 0

    model_config = {"from_attributes": True}


class PrintJobOut(BaseModel):
    id: int
    printer_id: int
    zone_id: Optional[int] = None
    item_ids: str
    copies: int = 1
    status: str
    retry_count: int = 0
    first_attempted_at: Optional[UTCDatetime] = None
    last_attempted_at: Optional[UTCDatetime] = None
    succeeded_at: Optional[UTCDatetime] = None
    cancelled_at: Optional[UTCDatetime] = None
    cancel_reason: Optional[str] = None

    model_config = {"from_attributes": True}


class OrderOut(BaseModel):
    id: int
    table_id: Optional[int] = None
    opened_by: int
    opened_at: UTCDatetime
    status: str
    closed_at: Optional[UTCDatetime] = None
    closed_by: Optional[int] = None
    notes: Optional[str] = None
    business_day_id: Optional[int] = None
    # Xenia Connect — online order fields
    source: str = "pos"
    online_order_ref: Optional[str] = None
    online_order_cloud_id: Optional[int] = None
    online_status: Optional[str] = None
    online_customer_name: Optional[str] = None
    online_customer_phone: Optional[str] = None
    online_customer_address: Optional[str] = None
    online_customer_notes: Optional[str] = None
    online_order_type: Optional[str] = None
    order_type: str = "here"
    customer_count: Optional[int] = None
    items: List[OrderItemOut] = []
    waiters: List[OrderWaiterOut] = []
    audit_logs: List[AuditLogOut] = []
    print_jobs: List[PrintJobOut] = []

    model_config = {"from_attributes": True}
