package card_apple_account

import (
	"context"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/os/glog"
	"github.com/gogf/gf/v2/text/gstr"
	"kami/api/commonApi"
	"kami/utility/integration/apple"

	"github.com/gogf/gf/v2/util/gconv"
	"github.com/shopspring/decimal"

	"kami/internal/consts"
	"kami/internal/dao"
	"kami/internal/model"
	"kami/internal/model/do"
	"kami/internal/model/entity"
	"kami/internal/service"
	"kami/utility/config"
	"kami/utility/utils"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/os/gtime"
)

func init() {
	service.RegisterAppleAccount(New())
}

func New() *sAppleAccount {
	return &sAppleAccount{}
}

type sAppleAccount struct{}

func (a *sAppleAccount) Add(ctx context.Context, data *model.AppleAccountRecordInput, tx gdb.TX) (err error) {
	uploadRole := "admin"
	if data.UploadUserId != "" {
		uploadRole = "user"
	}

	// 使用 AES 对称加密密码（可逆）
	encryptedPassword, err := utils.EncryptPasswordAES(gstr.TrimAll(data.Password))
	if err != nil {
		return err
	}

	//查询余额
	balanceResp, err := apple.NewClient().QueryBalance(ctx, &apple.QueryBalanceReq{
		Account:  data.Account,
		Password: encryptedPassword,
		OrderId:  utils.GenerateRandomUUID(),
	})
	if err != nil {
		glog.Error(ctx, "查询余额失败", err)
		return gerror.NewCode(gcode.CodeValidationFailed, "添加失败"+err.Error())
	}
	if balanceResp.Code != apple.CodeSuccess {
		return gerror.NewCode(gcode.CodeValidationFailed, "添加失败："+balanceResp.Code.String())
	}
	doData := do.V1CardAppleAccountInfo{
		Account:         gstr.TrimAll(data.Account),
		Password:        encryptedPassword,
		CreatedUserId:   data.UploadUserId,
		CreatedUserRole: uploadRole,
		MaxAmountLimit:  data.MaxAmountLimit,
		MaxCountLimit:   data.MaxCountLimit,
		Remark:          data.Remark,
		BalanceItunes:   balanceResp.Data.Balance,
		Status:          consts.AppleAccountNormal,
	}
	m := dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}
	doData.Id = utils.GenerateRandomUUID()

	_, err = m.Insert(doData)
	if err != nil {
		return err
	}
	return
}

// Update 修改用户信息
func (a *sAppleAccount) Update(ctx context.Context, data *model.V1CardAppleAccountInfo, tx gdb.TX) (err error) {
	m := dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}

	var updateData do.V1CardAppleAccountInfo
	updateData.Status = data.Status
	updateData.MaxAmountLimit = data.MaxAmountLimit
	updateData.MaxCountLimit = data.MaxCountLimit

	existsData := entity.V1CardAppleAccountInfo{}
	if err = m.WherePri(data.ID).Scan(&existsData); err != nil {
		return err
	}
	// 如果密码不为空，说明需要更新密码，进行 AES 加密处理
	if data.Password != "" && gstr.TrimAll(data.Password) != gstr.TrimAll(existsData.Password) &&
		gstr.LenRune(data.Password) != gstr.Count(data.Password, "*") {
		encryptedPassword, err2 := utils.EncryptPasswordAES(gstr.TrimAll(data.Password))
		if err2 != nil {
			return err2
		}
		updateData.Password = encryptedPassword
	}

	updateData.Remark = data.Remark

	_, err = m.WherePri(data.ID).Update(updateData)
	return
}

// AddWalletAmount 添加金额到账户中
func (a *sAppleAccount) AddWalletAmount(ctx context.Context, input *model.AppleCardWalletInfo, tx gdb.TX) (isFull bool, err error) {
	isFull = false
	m := dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).WherePri(input.ID)
	if tx != nil {
		m = m.TX(tx)
	}
	err = m.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		// TODO: 如果充值金额大于最大充值金额，则限制充值
		accountEntity := entity.V1CardAppleAccountInfo{}
		if err = m.TX(tx).Scan(&accountEntity); err != nil || accountEntity.Id == "" {
			return err
		}
		//处理最大充值金额
		maxAmountLimit := consts.AppleCardMaxRechargeAmount
		if accountEntity.MaxAmountLimit > 0 {
			maxAmountLimit = gconv.Float64(accountEntity.MaxAmountLimit)
		}
		if accountEntity.TodayRechargeAmount+input.Amount > maxAmountLimit {
			accountEntity.Status = int(consts.AppleAccountLimited)
			isFull = true
		}
		if accountEntity.MaxCountLimit > 0 {
			if gconv.Int(accountEntity.TodayRechargeCount) >= accountEntity.MaxCountLimit {
				accountEntity.Status = int(consts.AppleAccountLimited)
				isFull = true
			}
		}
		// 冻结账号
		if input.Amount < consts.AppleCardMinRechargeAmount {
			accountEntity.Status = int(consts.AppleAccountForbiddenByLowRecharge)
			isFull = true
		}
		err2 := a.AddWalletHistory(ctx, model.AppleCardAccountHistoryInput{
			AccountId:           input.ID,
			OrderNo:             input.OrderNo,
			Amount:              input.Amount,
			BalanceBeforeItunes: accountEntity.Balance,
			BalanceFromItunes:   input.BalanceFromItunes,
			CreatedUserId:       accountEntity.CreatedUserId,
			TransactionType:     "PLUS",
			Description:         input.Remark,
		}, tx)
		if err2 != nil {
			return err2
		}
		_, err2 = m.TX(tx).Update(do.V1CardAppleAccountInfo{
			TodayRechargeAmount:   accountEntity.TodayRechargeAmount + input.Amount,
			TodayRechargeCount:    accountEntity.TodayRechargeCount + 1,
			Balance:               accountEntity.Balance + input.Amount,
			BalanceItunes:         input.BalanceFromItunes,
			Status:                accountEntity.Status,
			TodayRechargeDatetime: gtime.Now(),
		})
		if err2 != nil {
			return err2
		}
		if accountEntity.CreatedUserId != "" {
			sysUserPayment := service.SysUserPayment()
			_, err2 = sysUserPayment.Consumption(ctx, &model.SysUserPaymentRechargeOrConsumeInput{
				OrderNo:         input.OrderNo,
				UserId:          accountEntity.CreatedUserId,
				Amount:          decimal.NewFromFloat(input.Amount),
				TransactionType: consts.UserPaymentRecordStatusConsume,
				Category:        consts.CardRedeemAccountCategoryApple,
				Remark:          input.Remark,
			}, tx)
		}
		return err2
	})
	return
}

// Delete 删除苹果账号
func (a *sAppleAccount) Delete(ctx context.Context, id string, tx gdb.TX) (err error) {
	m := dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if tx != nil {
		m = m.TX(tx)
	}
	_, err = m.WherePri(id).Delete()
	return
}

// List 获取所有苹果账户
func (a *sAppleAccount) List(ctx context.Context, input *model.CardInfoParamsInput) (total int, data []model.AppleAccountListOutput, err error) {
	data = make([]model.AppleAccountListOutput, 0)
	total = 0
	m := dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if input.Account != "" {
		total = 0
		m = m.WhereLike(dao.V1CardAppleAccountInfo.Columns().Account, utils.OrmLike(input.Account))
	}
	if input.UploadUserId != "" {
		m = m.Where(dao.V1CardAppleAccountInfo.Columns().CreatedUserId, input.UploadUserId)
	}
	err = m.With(model.V1SysUserRecord{}).
		Page(input.Current, input.PageSize).
		OrderDesc(dao.V1CardAppleAccountInfo.Columns().CreatedAt).
		ScanAndCount(&data, &total, true)
	return
}

// ListUnscoped 获取所有苹果账户
func (a *sAppleAccount) ListUnscoped(ctx context.Context, input *model.CardInfoParamsInput) (total int, data []model.AppleAccountListOutput, err error) {
	data = make([]model.AppleAccountListOutput, 0)
	total = 0
	m := dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1())
	if input.Account != "" {
		total = 0
		m = m.WhereLike(dao.V1CardAppleAccountInfo.Columns().Account, utils.OrmLike(input.Account))
	}
	if input.UploadUserId != "" {
		m = m.Where(dao.V1CardAppleAccountInfo.Columns().CreatedUserId, input.UploadUserId)
	}
	err = m.With(model.V1SysUserRecord{}).
		Page(input.Current, input.PageSize).Unscoped().
		OrderDesc(dao.V1CardAppleAccountInfo.Columns().CreatedAt).
		ScanAndCount(&data, &total, true)
	return
}

// GetDetailById 根据ID获取账号详情
func (a *sAppleAccount) GetDetailById(ctx context.Context, id string) (data *entity.V1CardAppleAccountInfo, err error) {
	data = &entity.V1CardAppleAccountInfo{}
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).WherePri(id).Scan(&data)
	err = utils.HandleNoRowsError(err)
	return
}

func (a *sAppleAccount) GetUnscopedDetailById(ctx context.Context, id string) (data *entity.V1CardAppleAccountInfo, err error) {
	data = &entity.V1CardAppleAccountInfo{}
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).Where(dao.V1CardAppleAccountInfo.Columns().Id, id).Unscoped().Scan(&data)
	return
}

func (a *sAppleAccount) GetDetailsByCreatedUser(ctx context.Context, createdUserId string) (data []*entity.V1CardAppleAccountInfo, err error) {
	data = make([]*entity.V1CardAppleAccountInfo, 0)
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CardAppleAccountInfo.Columns().CreatedUserId, createdUserId).
		Scan(&data)
	err = utils.HandleNoRowsError(err)
	return
}

// GetFirstNormalByCreatedUser 通过上传人获取最先上传切正常的账号
func (a *sAppleAccount) GetFirstNormalByCreatedUser(ctx context.Context, createdUserId string) (data entity.V1CardAppleAccountInfo, err error) {
	data = entity.V1CardAppleAccountInfo{}
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CardAppleAccountInfo.Columns().CreatedUserId, createdUserId).
		Where(dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountNormal).
		OrderAsc(dao.V1CardAppleAccountInfo.Columns().CreatedAt).Scan(&data)
	return
}

// GetDetailByName 根据账号获取账号详情
func (a *sAppleAccount) GetDetailByName(ctx context.Context, account string) (data entity.V1CardAppleAccountInfo, err error) {
	data = entity.V1CardAppleAccountInfo{}
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CardAppleAccountInfo.Columns().Account, account).
		Scan(&data)
	err = utils.HandleNoRowsError(err)
	return
}

// IsUnscopedTodayRepeatedByName 判断档当前添加的账号是否重复
func (a *sAppleAccount) IsUnscopedTodayRepeatedByName(ctx context.Context, account string) (isRepeated bool, err error) {
	data := commonApi.CommonStrId{}
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
		Wheref("((`%s` BETWEEN '%s' AND '%s') OR (`%s` = %d))", dao.V1CardAppleAccountInfo.Columns().CreatedAt,
			gtime.Now().StartOfDay(), gtime.Now().EndOfDay(),
			dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountForbiddenByLowRecharge,
		).
		Where(dao.V1CardAppleAccountInfo.Columns().Account, account).Unscoped().
		Scan(&data)
	err = utils.HandleNoRowsError(err)
	if data.ID != "" {
		return true, nil
	}
	return false, err
}

// GetAll 获取所有账号
func (a *sAppleAccount) GetAll(ctx context.Context) (data []entity.V1CardAppleAccountInfo, err error) {
	data = make([]entity.V1CardAppleAccountInfo, 0)
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
		Scan(&data)
	err = utils.HandleNoRowsError(err)
	return
}

// GetAllNormal 获取所有可用账户
func (a *sAppleAccount) GetAllNormal(ctx context.Context) (data []*entity.V1CardAppleAccountInfo, err error) {
	data = make([]*entity.V1CardAppleAccountInfo, 0)
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountNormal).Scan(&data)
	return
}

// GetListByStatus 获取所有可用的账号
func (a *sAppleAccount) GetListByStatus(ctx context.Context, status consts.AppleAccountStatus) (data []entity.V1CardAppleAccountInfo, err error) {
	data = make([]entity.V1CardAppleAccountInfo, 0)
	err = dao.V1CardAppleAccountInfo.Ctx(ctx).DB(config.GetDatabaseV1()).
		Where(dao.V1CardAppleAccountInfo.Columns().Status, consts.AppleAccountNormal).
		Scan(&data)
	err = utils.HandleNoRowsError(err)
	return
}

// CheckIsNormal 查询当前账户是否正常
func (a *sAppleAccount) CheckIsNormal(ctx context.Context, accountId string) {

}

// GetDecryptedPassword 获取解密后的密码
func (a *sAppleAccount) GetDecryptedPassword(encryptedPassword string) (string, error) {
	return utils.DecryptPasswordAES(encryptedPassword)
}
