package entities

import (
	"time"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

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                       `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
	OrganizationID   uuid.UUID                       `gorm:"type:uuid;not null;index" json:"organization_id" validate:"required"`
	OutletID         uuid.UUID                       `gorm:"type:uuid;not null;index" json:"outlet_id" validate:"required"`
	ItemID           uuid.UUID                       `gorm:"type:uuid;not null;index" json:"item_id" validate:"required"`
	ItemType         string                          `gorm:"not null;size:20" json:"item_type" validate:"required"` // "PRODUCT" or "INGREDIENT"
	MovementType     InventoryMovementType           `gorm:"not null;size:50" json:"movement_type" validate:"required"`
	Quantity         float64                         `gorm:"type:decimal(12,3);not null" json:"quantity" validate:"required"`
	PreviousQuantity float64                         `gorm:"type:decimal(12,3)" json:"previous_quantity"`
	NewQuantity      float64                         `gorm:"type:decimal(12,3)" json:"new_quantity"`
	UnitCost         float64                         `gorm:"type:decimal(12,2);default:0.00" json:"unit_cost"`
	TotalCost        float64                         `gorm:"type:decimal(12,2);default:0.00" json:"total_cost"`
	ReferenceType    *InventoryMovementReferenceType `gorm:"size:50" json:"reference_type"`
	ReferenceID      *uuid.UUID                      `gorm:"type:uuid;index" json:"reference_id"`
	OrderID          *uuid.UUID                      `gorm:"type:uuid;index" json:"order_id"`
	PaymentID        *uuid.UUID                      `gorm:"type:uuid;index" json:"payment_id"`
	UserID           uuid.UUID                       `gorm:"type:uuid;not null;index" json:"user_id" validate:"required"`
	Reason           *string                         `gorm:"size:255" json:"reason"`
	Notes            *string                         `gorm:"type:text" json:"notes"`
	Metadata         Metadata                        `gorm:"type:jsonb;default:'{}'" json:"metadata"`
	CreatedAt        time.Time                       `gorm:"autoCreateTime" json:"created_at"`

	Organization Organization `gorm:"foreignKey:OrganizationID" json:"organization,omitempty"`
	Outlet       Outlet       `gorm:"foreignKey:OutletID" json:"outlet,omitempty"`
	Product      *Product     `gorm:"foreignKey:ItemID" json:"product,omitempty"`
	Ingredient   *Ingredient  `gorm:"foreignKey:ItemID" json:"ingredient,omitempty"`
	Order        *Order       `gorm:"foreignKey:OrderID" json:"order,omitempty"`
	Payment      *Payment     `gorm:"foreignKey:PaymentID" json:"payment,omitempty"`
	User         User         `gorm:"foreignKey:UserID" json:"user,omitempty"`
}

func (im *InventoryMovement) BeforeCreate(tx *gorm.DB) error {
	if im.ID == uuid.Nil {
		im.ID = uuid.New()
	}
	return nil
}

func (InventoryMovement) TableName() string {
	return "inventory_movements"
}

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"
	}
}
