package database

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

// StringSlice is a JSON-serialized string slice stored as a MySQL TEXT/JSON column.
type StringSlice []string

func (s StringSlice) Value() (driver.Value, error) {
	if s == nil {
		return "[]", nil
	}
	b, err := json.Marshal(s)
	return string(b), err
}

func (s *StringSlice) Scan(src any) error {
	var raw []byte
	switch v := src.(type) {
	case string:
		raw = []byte(v)
	case []byte:
		raw = v
	default:
		return fmt.Errorf("StringSlice: unsupported type %T", src)
	}
	return json.Unmarshal(raw, s)
}

// ─── Products ────────────────────────────────────────────────────────────────

// ProductRow is the GORM model for the `products` table.
type ProductRow struct {
	ID              string      `gorm:"primaryKey;size:36"`
	Name            string      `gorm:"size:255;not null"`
	Price           float64     `gorm:"not null;default:0"`
	DiscountPrice   float64     `gorm:"default:0"`
	Tags            StringSlice `gorm:"type:json"`
	CoverURL        string      `gorm:"size:500"`
	ScreenshotURLs  StringSlice `gorm:"type:json"`
	VerificationURL string      `gorm:"size:500;default:''"`
	Description     string      `gorm:"type:text"`
	Active          bool        `gorm:"default:true;index"`
	RequireLogin    bool        `gorm:"default:false"`
	MaxPerAccount   int         `gorm:"default:0"`
	TotalSold       int         `gorm:"default:0"`
	ViewCount       int         `gorm:"default:0"`
	DeliveryMode    string      `gorm:"size:20;default:'auto'"`
	// FulfillmentType: card=卡密库存 / fixed=固定内容（不限库存，内容见 FixedContent）
	FulfillmentType string      `gorm:"size:16;default:card;index"`
	FixedContent    string      `gorm:"type:text"`
	ShowNote        bool        `gorm:"default:true"`
	ShowContact     bool        `gorm:"default:true"`
	CreatedAt       time.Time   `gorm:"index"`
}

func (ProductRow) TableName() string { return "products" }

// ProductCodeRow stores individual codes for a product (one row per code).
type ProductCodeRow struct {
	ID        uint   `gorm:"primaryKey;autoIncrement"`
	ProductID string `gorm:"size:36;not null;index"`
	Code      string `gorm:"type:text;not null"`
}

func (ProductCodeRow) TableName() string { return "product_codes" }

// ─── Orders ──────────────────────────────────────────────────────────────────

type OrderRow struct {
	ID             string      `gorm:"primaryKey;size:36"`
	ProductID      string      `gorm:"size:36;not null;index"`
	ProductName    string      `gorm:"size:255;not null"`
	UserAccount    string      `gorm:"size:255;index"`
	UserName       string      `gorm:"size:255"`
	Quantity       int         `gorm:"not null;default:1"`
	DeliveredCodes StringSlice `gorm:"type:json"`
	Status         string      `gorm:"size:20;not null;default:'pending';index"`
	DeliveryMode   string      `gorm:"size:20;default:'auto'"`
	Note           string      `gorm:"type:text"`
	ContactPhone   string      `gorm:"size:50"`
	ContactEmail   string      `gorm:"size:255"`
	NotifyEmail    string      `gorm:"size:255"`
	CreatedAt      time.Time
}

func (OrderRow) TableName() string { return "orders" }

// ─── Site settings ───────────────────────────────────────────────────────────

// SiteSettingRow stores arbitrary key-value pairs for site-wide settings.
type SiteSettingRow struct {
	Key   string `gorm:"primaryKey;size:64"`
	Value string `gorm:"type:text"`
}

func (SiteSettingRow) TableName() string { return "site_settings" }

// ─── Wishlists ───────────────────────────────────────────────────────────────

type WishlistRow struct {
	ID        uint   `gorm:"primaryKey;autoIncrement"`
	AccountID string `gorm:"size:255;not null;index:idx_wishlist,unique"`
	ProductID string `gorm:"size:36;not null;index:idx_wishlist,unique"`
}

func (WishlistRow) TableName() string { return "wishlists" }

// ─── Chat messages ───────────────────────────────────────────────────────────

type ChatMessageRow struct {
	ID          string    `gorm:"primaryKey;size:36"`
	AccountID   string    `gorm:"size:255;not null;index"`
	AccountName string    `gorm:"size:255"`
	Content     string    `gorm:"type:text;not null"`
	SentAt      time.Time `gorm:"not null"`
	FromAdmin   bool      `gorm:"default:false"`
}

func (ChatMessageRow) TableName() string { return "chat_messages" }
