package models

import (
	"time"

	"github.com/google/uuid"
)

type InventoryMovementType string

const (
	InventoryMovementTypeSale        InventoryMovementType = "sale"
	InventoryMovementTypePurchase    InventoryMovementType = "purchase"
	InventoryMovementTypeAdjustment  InventoryMovementType = "adjustment"
	InventoryMovementTypeReturn      InventoryMovementType = "return"
	InventoryMovementTypeRefund      InventoryMovementType = "refund"
	InventoryMovementTypeVoid        InventoryMovementType = "void"
	InventoryMovementTypeTransferIn  InventoryMovementType = "transfer_in"
	InventoryMovementTypeTransferOut InventoryMovementType = "transfer_out"
	InventoryMovementTypeDamage      InventoryMovementType = "damage"
	InventoryMovementTypeExpiry      InventoryMovementType = "expiry"
	InventoryMovementTypeIngredient  InventoryMovementType = "ingredient"
)

type InventoryMovementReferenceType string

const (
	InventoryMovementReferenceTypeOrder         InventoryMovementReferenceType = "order"
	InventoryMovementReferenceTypePayment       InventoryMovementReferenceType = "payment"
	InventoryMovementReferenceTypeRefund        InventoryMovementReferenceType = "refund"
	InventoryMovementReferenceTypeVoid          InventoryMovementReferenceType = "void"
	InventoryMovementReferenceTypeManual        InventoryMovementReferenceType = "manual"
	InventoryMovementReferenceTypeTransfer      InventoryMovementReferenceType = "transfer"
	InventoryMovementReferenceTypePurchaseOrder InventoryMovementReferenceType = "purchase_order"
)

type InventoryMovement struct {
	ID               uuid.UUID
	OrganizationID   uuid.UUID
	OutletID         uuid.UUID
	ItemID           uuid.UUID
	ItemType         string
	MovementType     InventoryMovementType
	Quantity         int
	PreviousQuantity int
	NewQuantity      int
	UnitCost         float64
	TotalCost        float64
	ReferenceType    *InventoryMovementReferenceType
	ReferenceID      *uuid.UUID
	OrderID          *uuid.UUID
	PaymentID        *uuid.UUID
	UserID           uuid.UUID
	Reason           *string
	Notes            *string
	Metadata         map[string]interface{}
	CreatedAt        time.Time
}

type CreateInventoryMovementRequest struct {
	OrganizationID uuid.UUID
	OutletID       uuid.UUID
	ItemID         uuid.UUID
	ItemType       string
	MovementType   InventoryMovementType
	Quantity       int
	UnitCost       float64
	ReferenceType  *InventoryMovementReferenceType
	ReferenceID    *uuid.UUID
	OrderID        *uuid.UUID
	PaymentID      *uuid.UUID
	UserID         uuid.UUID
	Reason         *string
	Notes          *string
	Metadata       map[string]interface{}
}

type InventoryMovementResponse struct {
	ID                  uuid.UUID
	OrganizationID      uuid.UUID
	OutletID            uuid.UUID
	ItemID              uuid.UUID
	ItemType            string
	MovementType        InventoryMovementType
	Quantity            int
	PreviousQuantity    int
	NewQuantity         int
	UnitCost            float64
	TotalCost           float64
	ReferenceType       *InventoryMovementReferenceType
	ReferenceID         *uuid.UUID
	OrderID             *uuid.UUID
	PaymentID           *uuid.UUID
	UserID              uuid.UUID
	Reason              *string
	Notes               *string
	Metadata            map[string]interface{}
	CreatedAt           time.Time
	MovementDescription string
}

type ListInventoryMovementsRequest struct {
	OrganizationID *uuid.UUID
	OutletID       *uuid.UUID
	ItemID         *uuid.UUID
	ItemType       *string
	MovementType   *InventoryMovementType
	ReferenceType  *InventoryMovementReferenceType
	ReferenceID    *uuid.UUID
	OrderID        *uuid.UUID
	PaymentID      *uuid.UUID
	UserID         *uuid.UUID
	DateFrom       *time.Time
	DateTo         *time.Time
	Page           int
	Limit          int
}

type ListInventoryMovementsResponse struct {
	Movements  []InventoryMovementResponse
	TotalCount int
	Page       int
	Limit      int
	TotalPages int
}

func (im *InventoryMovement) IsPositiveMovement() bool {
	return im.Quantity > 0
}

func (im *InventoryMovement) IsNegativeMovement() bool {
	return im.Quantity < 0
}

func (im *InventoryMovement) GetMovementDescription() string {
	switch im.MovementType {
	case InventoryMovementTypeSale:
		return "Sale"
	case InventoryMovementTypePurchase:
		return "Purchase"
	case InventoryMovementTypeAdjustment:
		return "Manual Adjustment"
	case InventoryMovementTypeReturn:
		return "Return"
	case InventoryMovementTypeRefund:
		return "Refund"
	case InventoryMovementTypeVoid:
		return "Void"
	case InventoryMovementTypeTransferIn:
		return "Transfer In"
	case InventoryMovementTypeTransferOut:
		return "Transfer Out"
	case InventoryMovementTypeDamage:
		return "Damage"
	case InventoryMovementTypeExpiry:
		return "Expiry"
	default:
		return "Unknown"
	}
}
