package models

import (
	"apskel-pos-be/internal/constants"
	"time"

	"github.com/google/uuid"
)

type Product struct {
	ID             uuid.UUID
	OrganizationID uuid.UUID
	CategoryID     uuid.UUID
	SKU            *string
	Name           string
	Description    *string
	Price          float64
	Cost           float64
	BusinessType   constants.BusinessType
	ImageURL       *string
	PrinterType    string
	UnitID         *uuid.UUID
	HasIngredients bool
	Metadata       map[string]interface{}
	IsActive       bool
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

type ProductVariant struct {
	ID            uuid.UUID
	ProductID     uuid.UUID
	Name          string
	PriceModifier float64
	Cost          float64
	Metadata      map[string]interface{}
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

type CreateProductRequest struct {
	OrganizationID uuid.UUID              `validate:"required"`
	CategoryID     uuid.UUID              `validate:"required"`
	SKU            *string                `validate:"omitempty,max=100"`
	Name           string                 `validate:"required,min=1,max=255"`
	Description    *string                `validate:"omitempty,max=1000"`
	Price          float64                `validate:"required,min=0"`
	Cost           float64                `validate:"min=0"`
	BusinessType   constants.BusinessType `validate:"required"`
	ImageURL       *string                `validate:"omitempty,max=500"`
	PrinterType    *string                `validate:"omitempty,max=50"`
	UnitID         *uuid.UUID             `validate:"omitempty"`
	HasIngredients bool                   `validate:"omitempty"`
	Metadata       map[string]interface{}
	Variants       []CreateProductVariantRequest `validate:"omitempty,dive"`
	// Stock management fields
	InitialStock    *int `validate:"omitempty,min=0"` // Initial stock quantity for all outlets
	ReorderLevel    *int `validate:"omitempty,min=0"` // Reorder level for all outlets
	CreateInventory bool `validate:"omitempty"`       // Whether to create inventory records for all outlets
}

type UpdateProductRequest struct {
	CategoryID     *uuid.UUID `validate:"omitempty"`
	SKU            *string    `validate:"omitempty,max=100"`
	Name           *string    `validate:"omitempty,min=1,max=255"`
	Description    *string    `validate:"omitempty,max=1000"`
	Price          *float64   `validate:"omitempty,min=0"`
	Cost           *float64   `validate:"omitempty,min=0"`
	ImageURL       *string    `validate:"omitempty,max=500"`
	PrinterType    *string    `validate:"omitempty,max=50"`
	UnitID         *uuid.UUID `validate:"omitempty"`
	HasIngredients *bool      `validate:"omitempty"`
	Metadata       map[string]interface{}
	IsActive       *bool
	// Stock management fields
	ReorderLevel *int `validate:"omitempty,min=0"` // Update reorder level for all existing inventory records
}

type CreateProductVariantRequest struct {
	ProductID     uuid.UUID `validate:"required"`
	Name          string    `validate:"required,min=1,max=255"`
	PriceModifier float64   `validate:"required"`
	Cost          float64   `validate:"min=0"`
	Metadata      map[string]interface{}
}

type UpdateProductVariantRequest struct {
	Name          *string `validate:"omitempty,min=1,max=255"`
	PriceModifier *float64
	Cost          *float64 `validate:"omitempty,min=0"`
	Metadata      map[string]interface{}
}

type ProductResponse struct {
	ID             uuid.UUID
	OrganizationID uuid.UUID
	CategoryID     uuid.UUID
	SKU            *string
	Name           string
	Description    *string
	Price          float64
	Cost           float64
	BusinessType   constants.BusinessType
	ImageURL       *string
	PrinterType    string
	UnitID         *uuid.UUID
	HasIngredients bool
	Metadata       map[string]interface{}
	IsActive       bool
	CreatedAt      time.Time
	UpdatedAt      time.Time
	Variants       []ProductVariantResponse
}

type ProductVariantResponse struct {
	ID            uuid.UUID
	ProductID     uuid.UUID
	Name          string
	PriceModifier float64
	Cost          float64
	Metadata      map[string]interface{}
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

func (p *Product) GetFinalPrice(variant *ProductVariant) float64 {
	if variant == nil {
		return p.Price
	}
	return p.Price + variant.PriceModifier
}

func (p *Product) GetProfitMargin() float64 {
	if p.Price == 0 {
		return 0
	}
	return ((p.Price - p.Cost) / p.Price) * 100
}

func (p *Product) IsValidPrice() bool {
	return p.Price > 0 && p.Cost >= 0 && p.Price > p.Cost
}
