package models

import (
	"database/sql/driver"
	"encoding/json"
	"errors"
	"time"
)

type ConfigItem struct {
	LotName   string  `json:"lot_name"`
	Quantity  int     `json:"quantity"`
	UnitPrice float64 `json:"unit_price"`
}

type ConfigItems []ConfigItem

func (c ConfigItems) Value() (driver.Value, error) {
	return json.Marshal(c)
}

func (c *ConfigItems) Scan(value interface{}) error {
	if value == nil {
		*c = make(ConfigItems, 0)
		return nil
	}
	bytes, ok := value.([]byte)
	if !ok {
		return errors.New("type assertion to []byte failed")
	}
	return json.Unmarshal(bytes, c)
}

func (c ConfigItems) Total() float64 {
	var total float64
	for _, item := range c {
		total += item.UnitPrice * float64(item.Quantity)
	}
	return total
}

type VendorSpecLotAllocation struct {
	LotName  string `json:"lot_name"`
	Quantity int    `json:"quantity"`
}

type VendorSpecLotMapping struct {
	LotName       string `json:"lot_name"`
	QuantityPerPN int    `json:"quantity_per_pn"`
}

type VendorSpecItem struct {
	SortOrder           int                       `json:"sort_order"`
	VendorPartnumber    string                    `json:"vendor_partnumber"`
	Quantity            int                       `json:"quantity"`
	Description         string                    `json:"description,omitempty"`
	UnitPrice           *float64                  `json:"unit_price,omitempty"`
	TotalPrice          *float64                  `json:"total_price,omitempty"`
	ResolvedLotName     string                    `json:"resolved_lot_name,omitempty"`
	ResolutionSource    string                    `json:"resolution_source,omitempty"`
	ManualLotSuggestion string                    `json:"manual_lot_suggestion,omitempty"`
	LotQtyPerPN         int                       `json:"lot_qty_per_pn,omitempty"`
	LotAllocations      []VendorSpecLotAllocation `json:"lot_allocations,omitempty"`
	LotMappings         []VendorSpecLotMapping    `json:"lot_mappings,omitempty"`
}

type VendorSpec []VendorSpecItem

func (v VendorSpec) Value() (driver.Value, error) {
	if v == nil {
		return nil, nil
	}
	return json.Marshal(v)
}

func (v *VendorSpec) Scan(value interface{}) error {
	if value == nil {
		*v = nil
		return nil
	}
	var bytes []byte
	switch val := value.(type) {
	case []byte:
		bytes = val
	case string:
		bytes = []byte(val)
	default:
		return errors.New("type assertion failed for VendorSpec")
	}
	return json.Unmarshal(bytes, v)
}

type Configuration struct {
	ID                    uint        `gorm:"primaryKey;autoIncrement" json:"id"`
	UUID                  string      `gorm:"size:36;uniqueIndex;not null" json:"uuid"`
	UserID                *uint       `json:"user_id,omitempty"` // Legacy field, no longer required for ownership
	OwnerUsername         string      `gorm:"size:100;not null;default:'';index" json:"owner_username"`
	ProjectUUID           *string     `gorm:"size:36;index" json:"project_uuid,omitempty"`
	AppVersion            string      `gorm:"size:64" json:"app_version,omitempty"`
	Name                  string      `gorm:"size:200;not null" json:"name"`
	Items                 ConfigItems `gorm:"type:json;not null" json:"items"`
	TotalPrice            *float64    `gorm:"type:decimal(12,2)" json:"total_price"`
	CustomPrice           *float64    `gorm:"type:decimal(12,2)" json:"custom_price"`
	Notes                 string      `gorm:"type:text" json:"notes"`
	IsTemplate            bool        `gorm:"default:false" json:"is_template"`
	ServerCount           int         `gorm:"default:1" json:"server_count"`
	ServerModel           string      `gorm:"size:100" json:"server_model,omitempty"`
	SupportCode           string      `gorm:"size:20" json:"support_code,omitempty"`
	Article               string      `gorm:"size:80" json:"article,omitempty"`
	PricelistID           *uint       `gorm:"index" json:"pricelist_id,omitempty"`
	WarehousePricelistID  *uint       `gorm:"index" json:"warehouse_pricelist_id,omitempty"`
	CompetitorPricelistID *uint       `gorm:"index" json:"competitor_pricelist_id,omitempty"`
	VendorSpec            VendorSpec  `gorm:"type:json" json:"vendor_spec,omitempty"`
	ConfigType            string      `gorm:"size:20;default:server" json:"config_type"` // "server" | "storage"
	DisablePriceRefresh   bool        `gorm:"default:false" json:"disable_price_refresh"`
	OnlyInStock           bool        `gorm:"default:false" json:"only_in_stock"`
	Line                  int         `gorm:"column:line_no;index" json:"line"`
	PriceUpdatedAt        *time.Time  `gorm:"type:timestamp" json:"price_updated_at,omitempty"`
	CreatedAt             time.Time   `gorm:"autoCreateTime" json:"created_at"`
	CurrentVersionNo      int         `gorm:"-" json:"current_version_no,omitempty"`
}

func (Configuration) TableName() string {
	return "qt_configurations"
}

