package commerce

import "time"

type CategoryResponse struct {
	ID            int64   `json:"id"`
	Slug          string  `json:"slug"`
	Name          string  `json:"name"`
	Description   *string `json:"description"`
	Icon          *string `json:"icon"`
	SortOrder     int     `json:"sort_order"`
	Status        string  `json:"status"`
	IsFeatured    bool    `json:"is_featured"`
	FeaturedLabel string  `json:"featured_label"`
}

type GroupResponse struct {
	ID               int64     `json:"id"`
	CategoryID       int64     `json:"category_id"`
	ParentID         *int64    `json:"parent_id"`
	Slug             string    `json:"slug"`
	Name             string    `json:"name"`
	Headline         *string   `json:"headline"`
	Description      *string   `json:"description"`
	Icon             *string   `json:"icon"`
	NetworkType      *string   `json:"network_type"`
	SortOrder        int       `json:"sort_order"`
	RequiresRealName bool      `json:"requires_real_name"`
	Area             *int      `json:"area"`
	Node             *int      `json:"node"`
	OSOptions        []any     `json:"os_options"`
	CreatedAt        time.Time `json:"created_at"`
	UpdatedAt        time.Time `json:"updated_at"`
}

type PricingResponse struct {
	ID            int64    `json:"id"`
	Cycle         string   `json:"cycle"`
	Price         float64  `json:"price"`
	OriginalPrice *float64 `json:"original_price"`
	SetupFee      float64  `json:"setup_fee"`
	IsEnabled     bool     `json:"is_enabled"`
	SortOrder     int      `json:"sort_order"`
}

type ProductResponse struct {
	ID                   int64             `json:"id"`
	GroupID              int64             `json:"group_id"`
	SKU                  string            `json:"sku"`
	Name                 string            `json:"name"`
	Type                 string            `json:"type"`
	Status               string            `json:"status"`
	VCPU                 *int              `json:"vcpu"`
	CPUModel             *string           `json:"cpu_model"`
	CPUBaseMHz           *int              `json:"cpu_base_mhz"`
	CPUTurboMHz          *int              `json:"cpu_turbo_mhz"`
	Memory               *string           `json:"memory"`
	Disk                 *string           `json:"disk"`
	Bandwidth            *string           `json:"bandwidth"`
	Features             *string           `json:"features"`
	Badges               *string           `json:"badges"`
	BaseSetupFee         float64           `json:"base_setup_fee"`
	BasePrice            float64           `json:"base_price"`
	StockPolicy          string            `json:"stock_policy"`
	Stock                int               `json:"stock"`
	MinQuantity          int               `json:"min_quantity"`
	MaxQuantity          int               `json:"max_quantity"`
	AutoProvision        bool              `json:"auto_provision"`
	TrialEnabled         bool              `json:"trial_enabled"`
	TrialDays            int               `json:"trial_days"`
	SortOrder            int               `json:"sort_order"`
	IsFeatured           bool              `json:"is_featured"`
	RequiresRealName     bool              `json:"requires_real_name"`
	CloudServerID        *int64            `json:"cloud_server_id"`
	APIType              string            `json:"api_type"`
	APIIdentifier        *string           `json:"api_identifier"`
	ProvisionInterfaceID *int64            `json:"provision_interface_id"`
	ProvisionConfig      []any             `json:"provision_config"`
	ProvisionPlugin      map[string]any    `json:"provision_plugin"`
	ProvisionInterface   map[string]any    `json:"provision_interface"`
	ProductPage          map[string]any    `json:"product_page"`
	Pricings             []PricingResponse `json:"pricings"`
	CreatedAt            time.Time         `json:"created_at"`
	UpdatedAt            time.Time         `json:"updated_at"`
}

type CartProductSummary struct {
	ID          int64   `json:"id"`
	SKU         string  `json:"sku"`
	Name        string  `json:"name"`
	Status      string  `json:"status"`
	VCPU        *int    `json:"vcpu"`
	Memory      *string `json:"memory"`
	Disk        *string `json:"disk"`
	Bandwidth   *string `json:"bandwidth"`
	StockPolicy string  `json:"stock_policy"`
	Stock       int     `json:"stock"`
	MinQuantity int     `json:"min_quantity"`
	MaxQuantity int     `json:"max_quantity"`
	GroupID     int64   `json:"group_id"`
}

type CartItemResponse struct {
	ID           int64               `json:"id"`
	UserID       int64               `json:"user_id"`
	ProductID    int64               `json:"product_id"`
	Cycle        string              `json:"cycle"`
	Quantity     int                 `json:"quantity"`
	AutoRenew    bool                `json:"auto_renew"`
	Alias        *string             `json:"alias"`
	OSImage      *string             `json:"os_image"`
	UnitPrice    float64             `json:"unit_price"`
	AddonPrice   float64             `json:"addon_price"`
	SetupFee     float64             `json:"setup_fee"`
	SliderValues map[string]any      `json:"slider_values"`
	CreatedAt    time.Time           `json:"created_at"`
	UpdatedAt    time.Time           `json:"updated_at"`
	Product      *CartProductSummary `json:"product"`
}

func newCategoryResponse(category ProductCategory) CategoryResponse {
	return CategoryResponse{
		ID:            category.ID,
		Slug:          category.Slug,
		Name:          category.Name,
		Description:   category.Description,
		Icon:          category.Icon,
		SortOrder:     category.SortOrder,
		Status:        category.Status,
		IsFeatured:    category.IsFeatured,
		FeaturedLabel: category.FeaturedLabel,
	}
}

func newGroupResponse(group ProductGroup) GroupResponse {
	return GroupResponse{
		ID:               group.ID,
		CategoryID:       group.CategoryID,
		ParentID:         group.ParentID,
		Slug:             group.Slug,
		Name:             group.Name,
		Headline:         group.Headline,
		Description:      group.Description,
		Icon:             group.Icon,
		NetworkType:      group.NetworkType,
		SortOrder:        group.SortOrder,
		RequiresRealName: group.RequiresRealName,
		Area:             group.Area,
		Node:             group.Node,
		OSOptions:        jsonList(group.OSOptions),
		CreatedAt:        group.CreatedAt,
		UpdatedAt:        group.UpdatedAt,
	}
}

func newPricingResponse(pricing ProductPricing) PricingResponse {
	return PricingResponse{
		ID:            pricing.ID,
		Cycle:         pricing.Cycle,
		Price:         pricing.Price,
		OriginalPrice: pricing.OriginalPrice,
		SetupFee:      pricing.SetupFee,
		IsEnabled:     pricing.IsEnabled,
		SortOrder:     pricing.SortOrder,
	}
}

func newProductResponse(product Product, pricings []ProductPricing, plugin map[string]any) ProductResponse {
	out := ProductResponse{
		ID:                   product.ID,
		GroupID:              product.GroupID,
		SKU:                  product.SKU,
		Name:                 product.Name,
		Type:                 product.Type,
		Status:               product.Status,
		VCPU:                 product.VCPU,
		CPUModel:             product.CPUModel,
		CPUBaseMHz:           product.CPUBaseMHz,
		CPUTurboMHz:          product.CPUTurboMHz,
		Memory:               product.Memory,
		Disk:                 product.Disk,
		Bandwidth:            product.Bandwidth,
		Features:             product.Features,
		Badges:               product.Badges,
		BaseSetupFee:         product.BaseSetupFee,
		BasePrice:            product.BasePrice,
		StockPolicy:          product.StockPolicy,
		Stock:                product.Stock,
		MinQuantity:          product.MinQuantity,
		MaxQuantity:          product.MaxQuantity,
		AutoProvision:        product.AutoProvision,
		TrialEnabled:         product.TrialEnabled,
		TrialDays:            product.TrialDays,
		SortOrder:            product.SortOrder,
		IsFeatured:           product.IsFeatured,
		RequiresRealName:     product.RequiresRealName,
		CloudServerID:        product.CloudServerID,
		APIType:              product.APIType,
		APIIdentifier:        product.APIIdentifier,
		ProvisionInterfaceID: product.ProvisionInterfaceID,
		ProvisionConfig:      jsonList(product.ProvisionConfig),
		ProvisionPlugin:      plugin,
		CreatedAt:            product.CreatedAt,
		UpdatedAt:            product.UpdatedAt,
	}
	if page, ok := plugin["product_page"].(map[string]any); ok {
		out.ProductPage = page
	}
	out.Pricings = make([]PricingResponse, 0, len(pricings))
	for _, pricing := range pricings {
		out.Pricings = append(out.Pricings, newPricingResponse(pricing))
	}
	return out
}

func newCartProductSummary(product Product) CartProductSummary {
	return CartProductSummary{
		ID:          product.ID,
		SKU:         product.SKU,
		Name:        product.Name,
		Status:      product.Status,
		VCPU:        product.VCPU,
		Memory:      product.Memory,
		Disk:        product.Disk,
		Bandwidth:   product.Bandwidth,
		StockPolicy: product.StockPolicy,
		Stock:       product.Stock,
		MinQuantity: product.MinQuantity,
		MaxQuantity: product.MaxQuantity,
		GroupID:     product.GroupID,
	}
}

func newCartItemResponse(item CartItem, product *Product) CartItemResponse {
	out := CartItemResponse{
		ID:           item.ID,
		UserID:       item.UserID,
		ProductID:    item.ProductID,
		Cycle:        item.Cycle,
		Quantity:     item.Quantity,
		AutoRenew:    item.AutoRenew,
		Alias:        item.Alias,
		OSImage:      item.OSImage,
		UnitPrice:    item.UnitPrice,
		AddonPrice:   item.AddonPrice,
		SetupFee:     item.SetupFee,
		SliderValues: jsonObject(item.SliderValues),
		CreatedAt:    item.CreatedAt,
		UpdatedAt:    item.UpdatedAt,
	}
	if product != nil {
		summary := newCartProductSummary(*product)
		out.Product = &summary
	}
	return out
}
