package models

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/xuri/excelize/v2"
	"go-admin/logger"
	"go-admin/tools/config"
	"gorm.io/gorm"
	"log"
	"sort"
	"strings"
	"time"

	"golang.org/x/crypto/bcrypt"

	orm "go-admin/common/global"
	"go-admin/tools"
)

// User
type User struct {
	// key
	IdentityKey string
	// 用户名
	UserName  string
	FirstName string
	LastName  string
	// 角色
	Role string
}

type UserName struct {
	Username string `gorm:"size:64" json:"username"` // 用户名
}

type PassWord struct {
	Password string `gorm:"size:128" json:"password"` // 密码
}

type LoginM struct {
	UserName
	PassWord
}

type SysUserId struct {
	UserId int `gorm:"primary_key;AUTO_INCREMENT"  json:"userId"` // 编码
}

type SysUserB struct {
	NickName              string      `gorm:"size:128" json:"nickName"`              // 昵称
	Phone                 string      `gorm:"size:11" json:"phone"`                  // 手机号
	RoleId                int         `gorm:"" json:"roleId"`                        // 角色编码
	Salt                  string      `gorm:"size:255" json:"salt"`                  // 盐
	Avatar                string      `gorm:"size:255" json:"avatar"`                // 头像
	Sex                   string      `gorm:"size:255" json:"sex"`                   // 性别
	Email                 string      `gorm:"size:128" json:"email"`                 // 邮箱
	DeptId                int         `gorm:"" json:"deptId"`                        // 部门编码
	PostId                int         `gorm:"" json:"postId"`                        // 职位编码
	CreateBy              string      `gorm:"size:128" json:"createBy"`              //
	UpdateBy              string      `gorm:"size:128" json:"updateBy"`              //
	Remark                string      `gorm:"size:255" json:"remark"`                // 备注
	Status                string      `gorm:"size:4;" json:"status"`                 // 状态
	StoreId               uint32      `json:"store_id"`                              // 门店id
	StoreName             string      `json:"store_name"`                            // 门店名称
	CooperativeBusinessId uint32      `json:"cooperative_business_id" gorm:"index"`  // 合作商id
	CooperativeName       string      `json:"cooperative_name"`                      // 合作商名称
	AccountType           uint32      `json:"account_type"`                          // 账号类型:1-管理端
	StoreData             string      `gorm:"type:json" json:"store_data,omitempty"` // 有效门店
	StoreList             []StoreInfo `json:"store_list" gorm:"-" `                  // 有效门店列表
	SalesCommRate         float64     `json:"sales_comm_rate"`                       // 销售提成比例
	Uid                   uint32      `json:"uid" gorm:"column:uid;unique_index"`    // 用户uid todo 待添加
	ShopperCode           string      `json:"shopper_code" gorm:"-"`                 // 店员兑换码

	BaseModel

	DataScope string `gorm:"-" json:"dataScope"`
	Params    string `gorm:"-" json:"params"`
}

type StoreInfo struct {
	StoreID    int    `json:"storeId"`    //门店id
	StoreName  string `json:"storeName"`  //门店名称
	ExpireTime string `json:"expireTime"` //有效期
}

type SysUser struct {
	SysUserId
	LoginM
	SysUserB
}

type InsertSysUserReq struct {
	SysUserId
	LoginM
	NickName              string      `json:"nickName"`                // 昵称
	Phone                 string      `json:"phone"`                   // 手机号
	RoleId                int         `json:"roleId"`                  // 角色编码
	Salt                  string      `json:"salt"`                    // 盐
	Avatar                string      `json:"avatar"`                  // 头像
	Sex                   string      `json:"sex"`                     // 性别
	Email                 string      `json:"email"`                   // 邮箱
	DeptId                int         `json:"deptId"`                  // 部门编码
	PostId                int         `json:"postId"`                  // 职位编码
	Remark                string      `json:"remark"`                  // 备注
	Status                string      `json:"status"`                  // 状态
	StoreId               uint32      `json:"store_id"`                // 门店id
	StoreName             string      `json:"store_name"`              // 门店名称
	CooperativeBusinessId uint32      `json:"cooperative_business_id"` // 合作商id
	CooperativeName       string      `json:"cooperative_name"`        // 合作商名称
	AccountType           uint32      `json:"account_type"`            // 账号类型:1-管理端
	SalesCommRate         string      `json:"sales_comm_rate"`         // 销售提成比例
	StoreList             []StoreInfo `json:"store_list"`              // 有效门店
	Uid                   uint32      `json:"uid"`                     // 用户uid
	ShopperCode           string      `json:"shopper_code"`            // 店员兑换码
}

func (SysUser) TableName() string {
	return "sys_user"
}

type SysUserPwd struct {
	OldPassword string `json:"oldPassword"`
	NewPassword string `json:"newPassword"`
}

type SysUserPage struct {
	SysUserId
	SysUserB
	LoginM
	DeptName string `gorm:"-" json:"deptName"`
}

type SysUserView struct {
	SysUserId
	SysUserB
	LoginM
	RoleName string `gorm:"column:role_name"  json:"role_name"`
}

// 获取用户数据
func (e *SysUser) Get() (SysUserView SysUserView, err error) {

	table := orm.Eloquent.Table(e.TableName()).Select([]string{"sys_user.*", "sys_role.role_name"})
	table = table.Joins("left join sys_role on sys_user.role_id=sys_role.role_id")
	if e.UserId != 0 {
		table = table.Where("user_id = ?", e.UserId)
	}

	if e.Username != "" {
		table = table.Where("username = ?", e.Username)
	}

	if e.Password != "" {
		table = table.Where("password = ?", e.Password)
	}

	if e.RoleId != 0 {
		table = table.Where("role_id = ?", e.RoleId)
	}

	if e.DeptId != 0 {
		table = table.Where("dept_id = ?", e.DeptId)
	}

	if e.PostId != 0 {
		table = table.Where("post_id = ?", e.PostId)
	}

	if err = table.First(&SysUserView).Error; err != nil {
		return
	}

	SysUserView.Password = ""
	if SysUserView.RoleName == "系统管理员" {
		// 查询组合所有门店数据
		stores := make([]Store, 0)
		orm.Eloquent.Table("store").Where("cooperative_business_id = ?", SysUserView.CooperativeBusinessId).Find(&stores)
		for _, item := range stores {
			storeInfo := StoreInfo{
				StoreID:    int(item.ID),
				StoreName:  item.Name,
				ExpireTime: "2099.12.30",
			}
			SysUserView.StoreList = append(SysUserView.StoreList, storeInfo)
		}
	} else { // 普通用户
		if SysUserView.StoreData != "" {
			SysUserView.StoreList = deserializeStoreData(SysUserView.StoreData)
		}
	}

	return
}

func (e *SysUser) GetUserInfo() (SysUserView SysUserView, err error) {

	table := orm.Eloquent.Table(e.TableName()).Select([]string{"sys_user.*", "sys_role.role_name"})
	table = table.Joins("left join sys_role on sys_user.role_id=sys_role.role_id")
	if e.UserId != 0 {
		table = table.Where("user_id = ?", e.UserId)
	}

	if e.Username != "" {
		table = table.Where("username = ?", e.Username)
	}

	if e.Password != "" {
		table = table.Where("password = ?", e.Password)
	}

	if e.RoleId != 0 {
		table = table.Where("role_id = ?", e.RoleId)
	}

	if e.DeptId != 0 {
		table = table.Where("dept_id = ?", e.DeptId)
	}

	if e.PostId != 0 {
		table = table.Where("post_id = ?", e.PostId)
	}

	if err = table.First(&SysUserView).Error; err != nil {
		return
	}
	return
}

func (e *SysUser) GetList() (SysUserView []SysUserView, err error) {

	table := orm.Eloquent.Table(e.TableName()).Select([]string{"sys_user.*", "sys_role.role_name"})
	table = table.Joins("left join sys_role on sys_user.role_id=sys_role.role_id")
	if e.UserId != 0 {
		table = table.Where("user_id = ?", e.UserId)
	}

	if e.Username != "" {
		table = table.Where("username = ?", e.Username)
	}

	if e.Password != "" {
		table = table.Where("password = ?", e.Password)
	}

	if e.RoleId != 0 {
		table = table.Where("role_id = ?", e.RoleId)
	}

	if e.DeptId != 0 {
		table = table.Where("dept_id = ?", e.DeptId)
	}

	if e.PostId != 0 {
		table = table.Where("post_id = ?", e.PostId)
	}

	if err = table.Find(&SysUserView).Error; err != nil {
		return
	}
	return
}

type SysUserListResp struct {
	Total     int           `json:"count"`      // 总条数
	PageIndex int           `json:"pageIndex"`  // 页码
	PageSize  int           `json:"pageSize"`   // 页面条数
	ExportUrl string        `json:"export_url"` // 导出excel路径
	List      []SysUserPage `json:"list"`       // 采购报表信息
}

func (e *SysUser) GetPage(pageSize int, pageIndex int, exportFlag int, storeList []int) ([]SysUserPage, int, string, error) {
	if e.ShopperCode != "" {
		var shopperCode ShopperPromotionCode
		err := orm.Eloquent.Table("shopper_promotion_code").Where("code = ?", e.ShopperCode).Find(&shopperCode).Error
		if err != nil {
			logger.Error("query shopper_promotion_code err:", logger.Field("err", err))
			return nil, 0, "", err
		}
		if shopperCode.ID == 0 {
			return nil, 0, "", nil
		} else {
			e.Uid = shopperCode.Uid
		}
	}

	var doc []SysUserPage
	table := orm.Eloquent.Select("sys_user.*,sys_dept.dept_name").Table(e.TableName())
	table = table.Joins("left join sys_dept on sys_dept.dept_id = sys_user.dept_id") //es := orm.Eloquent.Select("sys_user.*,sys_dept.dept_name").Table(e.TableName()) //es = table.Joins("left join sys_dept on sys_dept.dept_id = sys_user.dept_id")

	if e.Uid != 0 {
		table = table.Where("uid = ?", e.Uid)
	}
	if e.Username != "" {
		table = table.Where("username = ?", e.Username)
	}
	if e.Status != "" {
		table = table.Where("sys_user.status = ?", e.Status)
	}

	if e.Phone != "" {
		table = table.Where("sys_user.phone = ?", e.Phone)
	}

	if e.RoleId != 0 {
		table = table.Where("sys_user.role_id = ?", e.RoleId)
	}

	if e.NickName != "" {
		table = table.Where("sys_user.nick_name = ?", e.NickName)
	}

	//if e.StoreId != 0 {
	//	table = table.Where("JSON_CONTAINS(store_data, ?)", fmt.Sprintf(`{"storeId":%d}`, e.StoreId))
	//}

	// 假设 e.StoreId 是 []int 类型
	if len(storeList) > 0 {
		// 在 SQL 查询中使用 JSON_CONTAINS
		// 如果需要匹配多个 storeId，可以使用 OR 连接条件
		var conditions []string
		for _, storeId := range storeList {
			condition := fmt.Sprintf("JSON_CONTAINS(store_data, '{\"storeId\": %d}')", storeId)
			conditions = append(conditions, condition)
		}

		// 使用 OR 连接多个查询条件
		// 最终的查询条件形如：JSON_CONTAINS(store_data, '{"storeId": 13}') OR JSON_CONTAINS(store_data, '{"storeId": 19}')
		queryCondition := strings.Join(conditions, " OR ")

		// 将构造好的条件传递给 WHERE 子句
		table = table.Where(queryCondition)
	}

	if e.DeptId != 0 {
		table = table.Where("sys_user.dept_id in (select dept_id from sys_dept where dept_path like ? )", "%"+tools.IntToString(e.DeptId)+"%") //es = table.Where("sys_user.dept_id in (select dept_id from sys_dept where dept_path like ? )", "%"+tools.IntToString(e.DeptId)+"%")
	}

	// 数据权限控制(如果不需要数据权限请将此处去掉)
	dataPermission := new(DataPermission)
	dataPermission.UserId, _ = tools.StringToInt(e.DataScope)
	table, err := dataPermission.GetDataScope(e.TableName(), table)
	if err != nil {
		return nil, 0, "", err
	}

	es := table
	var count int64
	err = es.Count(&count).Error
	if err != nil {
		//logger.Error("count err:", err)
		return nil, 0, "", err
	}

	//if err := table.Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Order("sys_user.created_at DESC").Offset(-1).Limit(-1).Total(&count).Error; err != nil {
	//	return nil, 0, err
	//}

	if exportFlag == 1 { // 导出excel
		if err = table.Order("sys_user.user_id DESC").Find(&doc).Error; err != nil {
			return nil, 0, "", err
		}
	} else {
		if err = table.Order("sys_user.user_id DESC").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&doc).Error; err != nil {
			return nil, 0, "", err
		}
	}

	var resp []SysUserPage
	var exportUrl string
	// 反序列化 StoreData
	for i, v := range doc {
		if doc[i].StoreData != "" {
			doc[i].StoreList = deserializeStoreData(v.StoreData)
			doc[i].StoreData = ""
		}

		if e.StoreId != 0 { // 查询某个门店的销售员时，判断用户门店有效期
			// 返回sysUser未过期的门店id列表
			storeList := GetValidStoreIDs(v.StoreData)
			if len(storeList) > 0 {
				tempList := CompareLists(storeList, []uint32{e.StoreId})
				if len(tempList) == 0 { // 没有匹配的数据
					continue
				}
			} else {
				continue
			}
		}

		if doc[i].Uid != 0 {
			// 添加店员兑换码
			var shopperCode ShopperPromotionCode
			err = orm.Eloquent.Table("shopper_promotion_code").Where("uid = ?", doc[i].Uid).Find(&shopperCode).Error
			if err != nil {
				logger.Error("query shopper_promotion_code err:", logger.Field("err", err))
			}
			doc[i].ShopperCode = shopperCode.Code
		}

		resp = append(resp, doc[i])
	}

	if exportFlag == 1 { // 导出excel
		exportUrl, err = sysUserExport(resp)
		if err != nil {
			return nil, 0, "", err
		}
		resp = nil
	}

	return resp, int(count), exportUrl, nil
}

func getValidStoreNames(storeList []StoreInfo) (string, error) {
	var validStoreNames []string
	currentTime := time.Now()

	for _, store := range storeList {
		expireTime, err := time.Parse(StoreDateTimeFormat, store.ExpireTime)
		if err != nil {
			return "", fmt.Errorf("invalid expire time format for store ID %d: %v", store.StoreID, err)
		}
		if expireTime.After(currentTime) {
			validStoreNames = append(validStoreNames, store.StoreName)
		}
	}

	return strings.Join(validStoreNames, ","), nil
}

// 导出系统用户列表
func sysUserExport(req []SysUserPage) (string, error) {
	file := excelize.NewFile()
	fSheet := "Sheet1"

	url := config.ExportConfig.Url
	fileName := time.Now().Format(TimeFormat) + "系统用户" + ".xlsx"
	fmt.Println("url fileName:", url+fileName)

	// 组合标题栏数据
	title := []interface{}{"用户名称", "用户昵称", "角色", "合作商", "门店", "手机号", "店员识别码", "状态", "小程序账号ID"}
	for i, _ := range title {
		cell, _ := excelize.CoordinatesToCellName(1+i, 1)
		err := file.SetCellValue(fSheet, cell, title[i])
		if err != nil {
			logger.Errorf("file set value err:", err)
		}
	}

	// 查询系统角色
	var doc []SysRole
	err := orm.Eloquent.Table("sys_role").Find(&doc).Error
	if err != nil {
		logger.Errorf("query sys_role error:", err)
	}
	roleMap := make(map[int]string)
	for _, item := range doc {
		roleMap[item.RoleId] = item.RoleName
	}

	var row []interface{}
	nExcelStartRow := 0
	for _, userData := range req {
		// 门店
		storeName, _ := getValidStoreNames(userData.StoreList)

		var status string
		if userData.Status == "0" {
			status = "正常"
		} else {
			status = "停用"
		}

		var userUid string
		if userData.UserId == 0 {
			userUid = ""
		} else {
			userUid = tools.IntToString(int(userData.Uid))
		}

		row = []interface{}{
			userData.UserName.Username, // 用户名称
			userData.NickName,          // 用户昵称
			roleMap[userData.RoleId],   // 角色
			userData.CooperativeName,   // 合作商
			storeName,                  // 门店
			userData.Phone,             // 手机号
			userData.ShopperCode,       // 店员识别码
			status,                     // 状态
			userUid,                    // 用户UID
		}

		for j, _ := range row {
			cell, _ := excelize.CoordinatesToCellName(1+j, nExcelStartRow+2)
			err := file.SetCellValue(fSheet, cell, row[j])
			if err != nil {
				logger.Error("file set value err:", logger.Field("err", err))
			}
		}
		nExcelStartRow++
	}

	// 设置所有单元格的样式: 居中、加边框
	style, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},
	"border":[{"type":"left","color":"000000","style":1},
	{"type":"top","color":"000000","style":1},
	{"type":"right","color":"000000","style":1},
	{"type":"bottom","color":"000000","style":1}]}`)

	// 设置单元格的样式: 居中、加边框、自动换行
	style1, _ := file.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center","wrap_text":true},
	"border":[{"type":"left","color":"000000","style":1},
	{"type":"top","color":"000000","style":1},
	{"type":"right","color":"000000","style":1},
	{"type":"bottom","color":"000000","style":1}]}`)

	//设置单元格高度
	file.SetRowHeight("Sheet1", 1, 20)

	// 设置单元格大小
	file.SetColWidth("Sheet1", "B", "B", 15)
	file.SetColWidth("Sheet1", "C", "C", 15)
	file.SetColWidth("Sheet1", "D", "D", 15)
	file.SetColWidth("Sheet1", "E", "E", 30)
	file.SetColWidth("Sheet1", "F", "F", 15)
	file.SetColWidth("Sheet1", "G", "G", 15)
	file.SetColWidth("Sheet1", "I", "I", 15)

	endRow := fmt.Sprintf("I"+"%d", nExcelStartRow+2)
	// 应用样式到整个表格
	_ = file.SetCellStyle("Sheet1", "A1", endRow, style)

	endRow1 := fmt.Sprintf("E%d", nExcelStartRow+2)
	_ = file.SetCellStyle("Sheet1", "E2", endRow1, style1)

	fmt.Println("save fileName:", config.ExportConfig.Path+fileName)
	if err := file.SaveAs(config.ExportConfig.Path + fileName); err != nil {
		fmt.Println(err)
	}
	return url + fileName, nil
}

// 反序列化 StoreData
func deserializeStoreData(storeData string) []StoreInfo {
	var StoreData []StoreInfo
	if err := json.Unmarshal([]byte(storeData), &StoreData); err != nil {
		// 可以根据实际情况处理反序列化失败的情况
		log.Println("反序列化 StoreData 失败:", err)
	}
	return StoreData
}

// DeserializeBankData 反序列化 BankData
func DeserializeBankData(bankData string) []SupplierBankInfo {
	var BankData []SupplierBankInfo
	if err := json.Unmarshal([]byte(bankData), &BankData); err != nil {
		// 可以根据实际情况处理反序列化失败的情况
		log.Println("反序列化 BankData 失败:", err)
	}
	return BankData
}

// 加密
func (e *SysUser) Encrypt() (err error) {
	if e.Password == "" {
		return
	}

	var hash []byte
	if hash, err = bcrypt.GenerateFromPassword([]byte(e.Password), bcrypt.DefaultCost); err != nil {
		return
	} else {
		e.Password = string(hash)
		return
	}
}

// 添加
func (e SysUser) Insert(begin *gorm.DB) (id int, err error) {
	if err = e.Encrypt(); err != nil {
		return
	}

	// check 用户名
	var count int64
	orm.Eloquent.Table(e.TableName()).Where("username = ?", e.Username).Count(&count)
	if count > 0 {
		err = errors.New("账户已存在！")
		return
	}

	//添加数据
	if err = begin.Table(e.TableName()).Create(&e).Error; err != nil {
		return
	}
	id = e.UserId
	return
}

// 修改
func (e *SysUser) Update(begin *gorm.DB, id int) (update SysUser, err error) {
	if e.Password != "" {
		if err = e.Encrypt(); err != nil {
			return
		}
	}
	if err = orm.Eloquent.Table(e.TableName()).First(&update, id).Error; err != nil {
		return
	}
	if e.RoleId == 0 {
		e.RoleId = update.RoleId
	}

	if len(e.StoreList) != 0 {
		// 将 StoreData 转换为 JSON 字符串
		storeDataJSON, err := json.Marshal(e.StoreList)
		if err != nil {
			return SysUser{}, err
		}
		e.StoreData = string(storeDataJSON)
	}

	if begin == nil {
		begin = orm.Eloquent
	}

	//参数1:是要修改的数据
	//参数2:是修改的数据
	if err = begin.Table(e.TableName()).Model(&update).Updates(&e).Error; err != nil {
		return
	}

	if e.Uid == 0 {
		if err = begin.Table(e.TableName()).Model(&update).UpdateColumn("uid", 0).Error; err != nil {
			return
		}
	}

	return
}

func (e *SysUser) BatchDelete(begin *gorm.DB, id []int) (Result bool, err error) {
	if err = begin.Table(e.TableName()).Where("user_id in (?)", id).Delete(&SysUser{}).Error; err != nil {
		return false, err
	}

	return true, nil
}

func (e *SysUser) SetPwd(pwd SysUserPwd) (Result bool, err error) {
	user, err := e.GetUserInfo()
	if err != nil {
		tools.HasError(err, "获取用户数据失败(代码202)", 500)
	}
	_, err = tools.CompareHashAndPassword(user.Password, pwd.OldPassword)
	if err != nil {
		if strings.Contains(err.Error(), "hashedPassword is not the hash of the given password") {
			tools.HasError(err, "密码错误(代码202)", 500)
		}
		log.Print(err)
		return
	}
	e.Password = pwd.NewPassword
	_, err = e.Update(nil, e.UserId)
	tools.HasError(err, "更新密码失败(代码202)", 500)
	return
}

func GetUserById(id uint32) *SysUserB {
	var u = new(SysUserB)
	orm.Eloquent.Table("sys_user").Where("user_id", id).First(u)

	return u
}

func GetSysUserById(id uint32) *SysUser {
	var u = new(SysUser)
	orm.Eloquent.Table("sys_user").Where("user_id", id).First(u)

	return u
}

// UpdateUserType 更新uid的user_type为2
func UpdateUserType(begin *gorm.DB, uid, nType, roleId uint32) error {
	// 更新库存表
	err := begin.Table("user").Where("uid = ?", uid).
		Updates(map[string]interface{}{
			"user_type":   nType,
			"xcx_role_id": roleId,
		}).Error
	if err != nil {
		return err
	}

	return nil
}

// UpdateUserTypeAndShopperName 更新uid的user_type为2 和 店员名称
func UpdateUserTypeAndShopperName(begin *gorm.DB, uid, nType, roleId uint32, shopperName string) error {
	// 更新库存表
	err := begin.Table("user").Where("uid = ?", uid).
		Updates(map[string]interface{}{
			"user_type":           nType,
			"xcx_role_id":         roleId,
			"shop_assistant_name": shopperName,
		}).Error
	if err != nil {
		return err
	}

	return nil
}

// GetUserEffectiveStore 获取店员当前的有效门店（邀请客户时使用）
func GetUserEffectiveStore(uid uint32) ([]StoreInfo, error) {
	user := new(SysUser)
	err := orm.Eloquent.Table("sys_user").Where("uid", uid).Find(&user).Error
	if err != nil {
		log.Println("Error:", err, "UID:", uid)
		return nil, err
	}

	// 解析门店数据
	if err := json.Unmarshal([]byte(user.StoreData), &user.StoreList); err != nil {
		return nil, err
	}

	if len(user.StoreList) == 0 {
		return nil, errors.New("no stores found")
	}

	// 当前时间
	now := time.Now()

	// 过滤掉过期的门店
	validStores := make([]StoreInfo, 0)
	for _, store := range user.StoreList {
		expireTime, err := time.Parse(StoreDateTimeFormat, store.ExpireTime)
		if err != nil {
			log.Println("Error parsing time:", err, "ExpireTime:", store.ExpireTime)
			continue
		}

		// 包含当天有效时间
		expireTime = expireTime.Add(24*time.Hour - time.Second)
		if expireTime.After(now) {
			validStores = append(validStores, store)
		}
	}

	if len(validStores) == 0 {
		return nil, nil
	}

	// 按有效时间和 store_id 排序
	sort.Slice(validStores, func(i, j int) bool {
		timeI, _ := time.Parse(StoreDateTimeFormat, validStores[i].ExpireTime)
		timeJ, _ := time.Parse(StoreDateTimeFormat, validStores[j].ExpireTime)

		if timeI.Equal(timeJ) {
			return validStores[i].StoreID < validStores[j].StoreID
		}
		return timeI.Before(timeJ)
	})

	return validStores, nil
}

// GetUserEffectiveStoreById 获取店员当前的有效门店（商城发货使用）
func GetUserEffectiveStoreById(id uint32) ([]StoreInfo, error) {
	user := new(SysUser)
	err := orm.Eloquent.Table("sys_user").Where("user_id", id).Find(&user).Error
	if err != nil {
		log.Println("Error:", err, "UID:", id)
		return nil, err
	}

	// 解析门店数据
	if err := json.Unmarshal([]byte(user.StoreData), &user.StoreList); err != nil {
		return nil, err
	}

	if len(user.StoreList) == 0 {
		return nil, errors.New("no stores found")
	}

	// 当前时间
	now := time.Now()

	// 过滤掉过期的门店
	validStores := make([]StoreInfo, 0)
	for _, store := range user.StoreList {
		expireTime, err := time.Parse(StoreDateTimeFormat, store.ExpireTime)
		if err != nil {
			log.Println("Error parsing time:", err, "ExpireTime:", store.ExpireTime)
			continue
		}

		// 包含当天有效时间
		expireTime = expireTime.Add(24*time.Hour - time.Second)
		if expireTime.After(now) {
			validStores = append(validStores, store)
		}
	}

	if len(validStores) == 0 {
		return nil, nil
	}

	// 按有效时间和 store_id 排序
	sort.Slice(validStores, func(i, j int) bool {
		timeI, _ := time.Parse(StoreDateTimeFormat, validStores[i].ExpireTime)
		timeJ, _ := time.Parse(StoreDateTimeFormat, validStores[j].ExpireTime)

		if timeI.Equal(timeJ) {
			return validStores[i].StoreID < validStores[j].StoreID
		}
		return timeI.Before(timeJ)
	})

	return validStores, nil
}

// AddShopperCode 添加店员兑换码
func AddShopperCode(req InsertSysUserReq, begin *gorm.DB) error {
	// 获取有效门店id
	now := time.Now()
	// 过滤掉过期的门店
	validStores := make([]StoreInfo, 0)
	for _, store := range req.StoreList {
		expireTime, err := time.Parse(StoreDateTimeFormat, store.ExpireTime)
		if err != nil {
			log.Println("Error parsing time:", err, "ExpireTime:", store.ExpireTime)
			continue
		}

		// 包含当天有效时间
		expireTime = expireTime.Add(24*time.Hour - time.Second)
		if expireTime.After(now) {
			validStores = append(validStores, store)
		}
	}

	if len(validStores) == 0 {
		return errors.New("设置兑换码失败，无有效门店")
	}

	// 按有效时间和 store_id 排序
	sort.Slice(validStores, func(i, j int) bool {
		timeI, _ := time.Parse(StoreDateTimeFormat, validStores[i].ExpireTime)
		timeJ, _ := time.Parse(StoreDateTimeFormat, validStores[j].ExpireTime)

		if timeI.Equal(timeJ) {
			return validStores[i].StoreID < validStores[j].StoreID
		}
		return timeI.Before(timeJ)
	})

	var shopperCode ShopperPromotionCode
	shopperCode.Code = req.ShopperCode
	shopperCode.Uid = req.Uid
	shopperCode.State = 2
	shopperCode.StoreId = uint32(validStores[0].StoreID)
	if err := begin.Table("shopper_promotion_code").Create(&shopperCode).Error; err != nil {
		logger.Error("create shopper_promotion_code err:", logger.Field("err", err))
		return err
	}

	return nil
}

// UpdateShopperCode 更新店员兑换码
func UpdateShopperCode(req InsertSysUserReq, begin *gorm.DB, sysInfo *SysUser) error {
	if req.Uid == sysInfo.Uid && req.ShopperCode == sysInfo.ShopperCode { // 兑换码没变化
		return nil
	}

	var oldShopperCode ShopperPromotionCode
	orm.Eloquent.Debug().Model(&ShopperPromotionCode{}).
		Where("code = ? and state = ?", req.ShopperCode, 2).Find(&oldShopperCode)
	if oldShopperCode.ID != 0 && oldShopperCode.Uid != sysInfo.Uid {
		return errors.New(fmt.Sprintf("[%s]与已有店员识别码重复", req.ShopperCode))
	}

	// 获取有效门店id
	now := time.Now()
	// 过滤掉过期的门店
	validStores := make([]StoreInfo, 0)
	for _, store := range req.StoreList {
		expireTime, err := time.Parse(StoreDateTimeFormat, store.ExpireTime)
		if err != nil {
			log.Println("Error parsing time:", err, "ExpireTime:", store.ExpireTime)
			continue
		}

		// 包含当天有效时间
		expireTime = expireTime.Add(24*time.Hour - time.Second)
		if expireTime.After(now) {
			validStores = append(validStores, store)
		}
	}

	if len(validStores) == 0 {
		return errors.New("设置兑换码失败，无有效门店")
	}

	// 按有效时间和 store_id 排序
	sort.Slice(validStores, func(i, j int) bool {
		timeI, _ := time.Parse(StoreDateTimeFormat, validStores[i].ExpireTime)
		timeJ, _ := time.Parse(StoreDateTimeFormat, validStores[j].ExpireTime)

		if timeI.Equal(timeJ) {
			return validStores[i].StoreID < validStores[j].StoreID
		}
		return timeI.Before(timeJ)
	})

	// 删除原有的兑换码
	if sysInfo.Uid != 0 && sysInfo.ShopperCode != "" {
		err := orm.Eloquent.Table("shopper_promotion_code").Where("uid = ?", sysInfo.Uid).Delete(&ShopperPromotionCode{}).Error
		if err != nil {
			logger.Error("delete shopper_promotion_code err:", logger.Field("err", err))
			return err
		}
	}

	// 删除新配置的uid的兑换码
	err := orm.Eloquent.Table("shopper_promotion_code").Where("uid = ?", req.Uid).Delete(&ShopperPromotionCode{}).Error
	if err != nil {
		logger.Error("delete shopper_promotion_code err:", logger.Field("err", err))
		return err
	}

	// 添加新的兑换码
	var shopperCode ShopperPromotionCode
	shopperCode.Code = req.ShopperCode
	shopperCode.Uid = req.Uid
	shopperCode.State = 2
	shopperCode.StoreId = uint32(validStores[0].StoreID)
	if err := begin.Table("shopper_promotion_code").Create(&shopperCode).Error; err != nil {
		logger.Error("create shopper_promotion_code err:", logger.Field("err", err))
		return err
	}

	return nil
}

// IsShopperCodeExists 查询兑换码是否重复
func IsShopperCodeExists(code string) bool {
	var count int64
	orm.Eloquent.Debug().Model(&ShopperPromotionCode{}).
		Where("code = ? and state = ?", code, 2).
		Count(&count)

	return count > 0
}
