package models

import (
	database "WorldEpcho/src/datasource"
	"errors"
	"fmt"
	"github.com/go-xorm/xorm"
)

//激活码表结构体
type ActivationCode struct {
	ActiveCode         string  `json:"active_code" xorm:"unique"`
	CreatorId          int64   `json:"creator_id"`
	UseingId           int64   `json:"useing_id"`
	ActivateTime       int64   `json:"activate_time"`
	ExpireTime         int64   `json:"expire_time"`
	DurationHours      int     `json:"duration_hours"`
	DefaultApps        []int64 `json:"default_apps"`                    //默认可以参与的应用id
	AppData            string  `xorm:"'app_data' json" json:"app_data"` //应用数据
	Remark             string  `xorm:"remark" json:"remark"`
	MonthLimitAmount   int64   `xorm:"month_limit_amount" json:"month_limit_amount"`
	InitialInspiration int64   `xorm:"initial_inspiration" json:"initial_inspiration"`
}

// InsertActivationCode 插入一条激活码数据到数据库
func InsertActivationCode(session *xorm.Session, code *ActivationCode) error {
	// 检查激活码是否已存在
	has, err := session.Where("active_code = ?", code.ActiveCode).Exist(&ActivationCode{})
	if err != nil {
		return err
	}
	if has {
		// 如果激活码已经存在，返回错误
		return errors.New("激活码已存在")
	}
	// 如果激活码不存在，插入新记录
	_, err = session.Insert(code)
	return err
}

// GetActivationCode 通过激活码获取一条记录
func GetActivationCode(activeCode string) (bool, *ActivationCode, error) {
	// 创建激活码对象的空实例用于查询
	code := &ActivationCode{ActiveCode: activeCode}
	// 使用Get方法，尝试根据ActiveCode找到记录
	found, err := database.Engine.Get(code)
	if err != nil {
		// 查询出错，返回错误
		return false, nil, err
	}
	if !found {
		// 未找到激活码，返回false和nil
		return false, nil, nil
	}
	// 找到激活码，返回true和激活码对象
	return true, code, nil
}

//

func GetActivationCode_Tx(session *xorm.Session, activeCode string) (bool, *ActivationCode, error) {
	// 创建激活码对象的空实例用于查询
	code := &ActivationCode{ActiveCode: activeCode}
	// 使用Get方法，尝试根据ActiveCode找到记录
	found, err := session.Where("active_code = ?", activeCode).Get(code)
	if err != nil {
		// 查询出错，返回错误
		return false, nil, err
	}
	if !found {
		// 未找到激活码，返回false和nil
		return false, nil, nil
	}
	// 找到激活码，返回true和激活码对象
	return true, code, nil
}

// UpdateActivationCode 更新激活码的数据
func UpdateActivationCode(session *xorm.Session, code *ActivationCode) (err error) {
	_, err = session.Where("active_code = ?", code.ActiveCode).Update(code)
	return
}

// DeleteActivationCode 删除一条激活码数据
func DeleteActivationCode(activeCode string) (err error) {
	_, err = database.Engine.Where("active_code = ?", activeCode).Delete(&ActivationCode{})
	return
}

// GetActivationCodeByUserID 使用用户 ID 查找关联的激活码信息。
// 如果找到了关联的激活码，返回 true 和激活码的详细信息。
// 如果没有找到匹配的激活码，返回 false 和 nil。
func GetActivationCodeByUserID(userID int64) (bool, *ActivationCode, error) {
	var activationCode ActivationCode

	// 找到用户ID对应的激活码
	has, err := database.Engine.Where("useing_id = ?", userID).Get(&activationCode)
	if err != nil {
		// 错误查询激活码时返回错误
		return false, nil, err
	}

	if !has {
		// 如果没有找到激活码，返回false和nil
		return false, nil, nil
	}

	// 找到了激活码，返回true和激活码对象
	return true, &activationCode, nil
}

// GetActivationCodesByCreator 查询激活码表中，根据创建者 ID 查询所有的激活码。
// 返回两个值：激活码字符串数组和对应的激活码对象数组。
// 如果没有找到记录或者发生查询错误，返回错误。
func GetActivationCodesByCreator(creatorID int64) ([]string, []ActivationCode, error) {
	var activationCodes []ActivationCode

	// 执行查询，查找所有匹配 CreatorId 的激活码记录
	err := database.Engine.Where("creator_id = ?", creatorID).Find(&activationCodes)
	if err != nil {
		// 查询出错，返回错误
		return nil, nil, err
	} else if len(activationCodes) == 0 {
		// 如果没有找到匹配的记录，返回错误
		return nil, nil, errors.New("激活码不存在")
	}

	// 提取激活码字符串
	codes := make([]string, len(activationCodes))
	for i, ac := range activationCodes {
		codes[i] = ac.ActiveCode
	}

	// 返回激活码字符串数组和激活码对象数组
	return codes, activationCodes, nil
}

// 根据提供的激活码查询AppData的函数
func GetAppDataByActiveCode(session *xorm.Session, activeCode string) (string, error) {
	var activationCode ActivationCode
	has, err := session.Where("active_code = ?", activeCode).Get(&activationCode)
	if err != nil {
		return "", err // 查询过程中出现了错误
	}
	if !has {
		return "", fmt.Errorf("no record found for active code: %s", activeCode) // 没有找到记录
	}
	return activationCode.AppData, nil
}
