package contract

import (
	"time"

	"github.com/google/uuid"
)

type CreateOrderRequest struct {
	OutletID     uuid.UUID                `json:"outlet_id" validate:"required"`
	UserID       uuid.UUID                `json:"user_id" validate:"required"`
	CustomerID   *uuid.UUID               `json:"customer_id"`
	TableID      *uuid.UUID               `json:"table_id,omitempty" validate:"omitempty"`
	TableNumber  *string                  `json:"table_number,omitempty" validate:"omitempty,max=50"`
	OrderType    string                   `json:"order_type" validate:"required,oneof=dine_in takeaway delivery"`
	Notes        *string                  `json:"notes,omitempty" validate:"omitempty,max=1000"`
	OrderItems   []CreateOrderItemRequest `json:"order_items" validate:"required,min=1,dive"`
	CustomerName *string                  `json:"customer_name,omitempty" validate:"omitempty,max=255"`
}

type AddToOrderRequest struct {
	OrderItems []CreateOrderItemRequest `json:"order_items" validate:"required,min=1,dive"`
	Notes      *string                  `json:"notes,omitempty" validate:"omitempty,max=1000"`
	Metadata   map[string]interface{}   `json:"metadata,omitempty"`
}

type AddToOrderResponse struct {
	OrderID      uuid.UUID           `json:"order_id"`
	OrderNumber  string              `json:"order_number"`
	AddedItems   []OrderItemResponse `json:"added_items"`
	UpdatedOrder OrderResponse       `json:"updated_order"`
}

type UpdateOrderRequest struct {
	TableNumber    *string                `json:"table_number,omitempty" validate:"omitempty,max=50"`
	Status         *string                `json:"status,omitempty" validate:"omitempty,oneof=pending preparing ready completed cancelled"`
	DiscountAmount *float64               `json:"discount_amount,omitempty" validate:"omitempty,min=0"`
	Notes          *string                `json:"notes,omitempty" validate:"omitempty,max=1000"`
	Metadata       map[string]interface{} `json:"metadata,omitempty"`
}

type CreateOrderItemRequest struct {
	ProductID        uuid.UUID                `json:"product_id" validate:"required"`
	ProductVariantID *uuid.UUID               `json:"product_variant_id,omitempty"`
	Quantity         int                      `json:"quantity" validate:"required,min=1"`
	UnitPrice        *float64                 `json:"unit_price,omitempty" validate:"omitempty,min=0"` // Optional, will use database price if not provided
	Modifiers        []map[string]interface{} `json:"modifiers,omitempty"`
	Notes            *string                  `json:"notes,omitempty" validate:"omitempty,max=500"`
	Metadata         map[string]interface{}   `json:"metadata,omitempty"`
}

type UpdateOrderItemRequest struct {
	Quantity  *int                     `json:"quantity,omitempty" validate:"omitempty,min=1"`
	UnitPrice *float64                 `json:"unit_price,omitempty" validate:"omitempty,min=0"`
	Modifiers []map[string]interface{} `json:"modifiers,omitempty"`
	Status    *string                  `json:"status,omitempty" validate:"omitempty,oneof=pending preparing completed cancelled"`
}

type OrderResponse struct {
	ID              uuid.UUID              `json:"id"`
	OrderNumber     string                 `json:"order_number"`
	OutletID        uuid.UUID              `json:"outlet_id"`
	UserID          uuid.UUID              `json:"user_id"`
	TableNumber     *string                `json:"table_number"`
	OrderType       string                 `json:"order_type"`
	Status          string                 `json:"status"`
	Subtotal        float64                `json:"subtotal"`
	TaxAmount       float64                `json:"tax_amount"`
	DiscountAmount  float64                `json:"discount_amount"`
	TotalAmount     float64                `json:"total_amount"`
	TotalCost       float64                `json:"total_cost"`
	RemainingAmount float64                `json:"remaining_amount"`
	PaymentStatus   string                 `json:"payment_status"`
	RefundAmount    float64                `json:"refund_amount"`
	IsVoid          bool                   `json:"is_void"`
	IsRefund        bool                   `json:"is_refund"`
	VoidReason      *string                `json:"void_reason,omitempty"`
	VoidedAt        *time.Time             `json:"voided_at,omitempty"`
	VoidedBy        *uuid.UUID             `json:"voided_by,omitempty"`
	RefundReason    *string                `json:"refund_reason,omitempty"`
	RefundedAt      *time.Time             `json:"refunded_at,omitempty"`
	RefundedBy      *uuid.UUID             `json:"refunded_by,omitempty"`
	Notes           *string                `json:"notes"`
	Metadata        map[string]interface{} `json:"metadata,omitempty"`
	CreatedAt       time.Time              `json:"created_at"`
	UpdatedAt       time.Time              `json:"updated_at"`
	OrderItems      []OrderItemResponse    `json:"order_items,omitempty"`
	Payments        []PaymentResponse      `json:"payments,omitempty"`
	TotalPaid       float64                `json:"total_paid"`
	PaymentCount    int                    `json:"payment_count"`
	SplitType       *string                `json:"split_type,omitempty"`
}

type OrderItemResponse struct {
	ID                 uuid.UUID                `json:"id"`
	OrderID            uuid.UUID                `json:"order_id"`
	ProductID          uuid.UUID                `json:"product_id"`
	ProductName        string                   `json:"product_name"`
	ProductVariantID   *uuid.UUID               `json:"product_variant_id"`
	ProductVariantName *string                  `json:"product_variant_name,omitempty"`
	Quantity           int                      `json:"quantity"`
	UnitPrice          float64                  `json:"unit_price"`
	TotalPrice         float64                  `json:"total_price"`
	Modifiers          []map[string]interface{} `json:"modifiers"`
	Notes              *string                  `json:"notes,omitempty"`
	Metadata           map[string]interface{}   `json:"metadata,omitempty"`
	Status             string                   `json:"status"`
	CreatedAt          time.Time                `json:"created_at"`
	UpdatedAt          time.Time                `json:"updated_at"`
	PrinterType        string                   `json:"printer_type"`
	PaidQuantity       int                      `json:"paid_quantity"`
}

type ListOrdersQuery struct {
	OrganizationID string `form:"organization_id"`
	OutletID       string `form:"outlet_id"`
	UserID         string `form:"user_id"`
	CustomerID     string `form:"customer_id"`
	OrderType      string `form:"order_type"`
	Status         string `form:"status"`
	PaymentStatus  string `form:"payment_status"`
	IsVoid         string `form:"is_void"`
	IsRefund       string `form:"is_refund"`
	DateFrom       string `form:"date_from"`
	DateTo         string `form:"date_to"`
	Search         string `form:"search"`
	Page           int    `form:"page,default=1"`
	Limit          int    `form:"limit,default=10"`
}

type ListOrdersRequest struct {
	Page      int        `json:"page" validate:"min=1"`
	Limit     int        `json:"limit" validate:"min=1,max=100"`
	OutletID  *uuid.UUID `json:"outlet_id,omitempty"`
	UserID    *uuid.UUID `json:"user_id,omitempty"`
	Status    *string    `json:"status,omitempty" validate:"omitempty,oneof=pending preparing ready completed cancelled"`
	OrderType *string    `json:"order_type,omitempty" validate:"omitempty,oneof=dine_in takeaway delivery"`
	DateFrom  *time.Time `json:"date_from,omitempty"`
	DateTo    *time.Time `json:"date_to,omitempty"`
}

type ListOrdersResponse struct {
	Orders     []OrderResponse   `json:"orders"`
	Payments   []PaymentResponse `json:"payments"`
	TotalCount int               `json:"total_count"`
	Page       int               `json:"page"`
	Limit      int               `json:"limit"`
	TotalPages int               `json:"total_pages"`
}

type VoidOrderRequest struct {
	OrderID uuid.UUID         `json:"order_id" validate:"required"`
	Reason  string            `json:"reason" validate:"required"`
	Type    string            `json:"type" validate:"required,oneof=ALL ITEM"`
	Items   []VoidItemRequest `json:"items,omitempty" validate:"required_if=Type ITEM,dive"`
}

type VoidItemRequest struct {
	OrderItemID uuid.UUID `json:"order_item_id" validate:"required"`
	Quantity    int       `json:"quantity" validate:"required,min=1"`
}

type SetOrderCustomerRequest struct {
	CustomerID uuid.UUID `json:"customer_id" validate:"required"`
}

type SetOrderCustomerResponse struct {
	OrderID    uuid.UUID `json:"order_id"`
	CustomerID uuid.UUID `json:"customer_id"`
	Message    string    `json:"message"`
}

type CreatePaymentRequest struct {
	OrderID           uuid.UUID                       `json:"order_id" validate:"required"`
	PaymentMethodID   uuid.UUID                       `json:"payment_method_id" validate:"required"`
	Amount            float64                         `json:"amount" validate:"required,min=0"`
	TransactionID     *string                         `json:"transaction_id,omitempty" validate:"omitempty"`
	SplitNumber       int                             `json:"split_number,omitempty" validate:"omitempty,min=1"`
	SplitTotal        int                             `json:"split_total,omitempty" validate:"omitempty,min=1"`
	SplitType         *string                         `json:"split_type,omitempty" validate:"omitempty,oneof=AMOUNT ITEM"`
	SplitDescription  *string                         `json:"split_description,omitempty" validate:"omitempty,max=255"`
	PaymentOrderItems []CreatePaymentOrderItemRequest `json:"payment_order_items,omitempty" validate:"omitempty,dive"`
	Metadata          map[string]interface{}          `json:"metadata,omitempty"`
}

type CreatePaymentOrderItemRequest struct {
	OrderItemID uuid.UUID `json:"order_item_id" validate:"required"`
	Amount      float64   `json:"amount" validate:"required,min=0"`
}

type PaymentResponse struct {
	ID                uuid.UUID                  `json:"id"`
	OrderID           uuid.UUID                  `json:"order_id"`
	PaymentMethodID   uuid.UUID                  `json:"payment_method_id"`
	PaymentMethodName string                     `json:"payment_method_name"`
	PaymentMethodType string                     `json:"payment_method_type"`
	Amount            float64                    `json:"amount"`
	Status            string                     `json:"status"`
	TransactionID     *string                    `json:"transaction_id,omitempty"`
	SplitNumber       int                        `json:"split_number"`
	SplitTotal        int                        `json:"split_total"`
	SplitType         *string                    `json:"split_type,omitempty"`
	SplitDescription  *string                    `json:"split_description,omitempty"`
	RefundAmount      float64                    `json:"refund_amount"`
	RefundReason      *string                    `json:"refund_reason,omitempty"`
	RefundedAt        *time.Time                 `json:"refunded_at,omitempty"`
	RefundedBy        *uuid.UUID                 `json:"refunded_by,omitempty"`
	Metadata          map[string]interface{}     `json:"metadata,omitempty"`
	CreatedAt         time.Time                  `json:"created_at"`
	UpdatedAt         time.Time                  `json:"updated_at"`
	PaymentOrderItems []PaymentOrderItemResponse `json:"payment_order_items,omitempty"`
}

type PaymentOrderItemResponse struct {
	ID          uuid.UUID `json:"id"`
	PaymentID   uuid.UUID `json:"payment_id"`
	OrderItemID uuid.UUID `json:"order_item_id"`
	Amount      float64   `json:"amount"`
	CreatedAt   time.Time `json:"created_at"`
	UpdatedAt   time.Time `json:"updated_at"`
}

type RefundOrderRequest struct {
	Reason       *string                  `json:"reason,omitempty" validate:"omitempty,max=255"`
	RefundAmount *float64                 `json:"refund_amount,omitempty" validate:"omitempty,min=0"`
	OrderItems   []RefundOrderItemRequest `json:"order_items,omitempty" validate:"omitempty,dive"`
}

type RefundOrderItemRequest struct {
	OrderItemID    uuid.UUID `json:"order_item_id" validate:"required"`
	RefundQuantity int       `json:"refund_quantity,omitempty" validate:"omitempty,min=1"`
	RefundAmount   *float64  `json:"refund_amount,omitempty" validate:"omitempty,min=0"`
	Reason         *string   `json:"reason,omitempty" validate:"omitempty,max=255"`
}

type RefundPaymentRequest struct {
	RefundAmount float64 `json:"refund_amount" validate:"required,min=0"`
	Reason       string  `json:"reason" validate:"omitempty,max=255"`
}

type SplitBillRequest struct {
	OrderID         uuid.UUID              `json:"order_id" validate:"required"`
	OrganizationID  uuid.UUID              `json:"organization_id"`
	PaymentMethodID uuid.UUID              `json:"payment_method_id" validate:"required"`
	CustomerID      uuid.UUID              `json:"customer_id"`
	Type            string                 `json:"type" validate:"required,oneof=ITEM AMOUNT"`
	Items           []SplitBillItemRequest `json:"items,omitempty" validate:"required_if=Type ITEM,dive"`
	Amount          float64                `json:"amount,omitempty" validate:"required_if=Type AMOUNT,min=0"`
}

type SplitBillItemRequest struct {
	OrderItemID uuid.UUID `json:"order_item_id" validate:"required"`
	Quantity    int       `json:"quantity" validate:"required,min=0"`
}

type SplitBillResponse struct {
	PaymentID  uuid.UUID               `json:"payment_id"`
	OrderID    uuid.UUID               `json:"order_id"`
	CustomerID uuid.UUID               `json:"customer_id"`
	Type       string                  `json:"type"`
	Amount     float64                 `json:"amount"`
	Items      []SplitBillItemResponse `json:"items,omitempty"`
	Message    string                  `json:"message"`
}

type SplitBillItemResponse struct {
	OrderItemID uuid.UUID `json:"order_item_id"`
	Amount      float64   `json:"amount"`
}
