package entity

import (
	"database/sql"
	"strings"
	"time"

	. "app.yhyue.com/moapp/jybase/common"
	. "app.yhyue.com/moapp/jybase/date"
	. "bp.jydev.jianyu360.cn/BaseService/resourceCenter/public/db"
	"github.com/zeromicro/go-zero/core/logx"
)

var Base_power = base_power{}

//企业/用户权益表
type base_power struct {
	Id             int64
	Appid          string
	Function_code  string //功能代码
	Power_type     int64  //权益所属类型；1：个人 2：企业
	Account_id     int64  //账户id
	Start_time     string //开始时间
	End_time       string //结束时间
	Use_count      int64  //使用数量
	Surplus_count  int64  //剩余数量
	Limit_strategy string //限制频率；1d：1天 1m：1个月
	Strategy_count int64  //频率数量
}

//获取所有权益
func (b *base_power) FindMyPowers(appid string, account_id, ent_account_id int64) *[]*base_power {
	now := NowFormat(Date_Full_Layout)
	list := Mysql_BaseService.SelectBySql(`select * from base_power where appid=? and ((power_type=1 and account_id=?) or (power_type=2 and account_id=?)) and end_time>? and status=1 order by power_type`, appid, account_id, ent_account_id, now)
	return JsonUnmarshal(list, &[]*base_power{}).(*[]*base_power)
}

//查找我的权益
func (b *base_power) FindMyPowersByFc(appid, function_code string, account_id, ent_account_id int64) *[]*base_power {
	now := NowFormat(Date_Full_Layout)
	list := Mysql_BaseService.SelectBySql(`select * from base_power where appid=? and function_code=? and ((power_type=1 and account_id=?) or (power_type=2 and account_id=?)) and end_time>? and status=1 order by power_type`, appid, function_code, account_id, ent_account_id, now)
	return JsonUnmarshal(list, &[]*base_power{}).(*[]*base_power)
}

//查找我最新一条的权益，没有过期限制
func (b *base_power) FindMyLastPowerByFc(appid, function_code string, account_id, ent_account_id int64) *base_power {
	list := Mysql_BaseService.SelectBySql(`select * from base_power where appid=? and function_code=? and ((power_type=1 and account_id=?) or (power_type=2 and account_id=?)) order by update_time desc limit 1`, appid, function_code, account_id, ent_account_id)
	if len(*list) == 0 {
		return nil
	}
	return JsonUnmarshal((*list)[0], &base_power{}).(*base_power)
}

//查找我的权益，加锁
func (b *base_power) FindMyPowerForUpdate(id int64) *base_power {
	list := Mysql_BaseService.SelectBySql(`select * from base_power where id=? for update wait 5`, id)
	if list == nil || len(*list) == 0 {
		return nil
	}
	return JsonUnmarshal((*list)[0], &base_power{}).(*base_power)
}

//开通权益
func (b *base_power) OpenPower(goods_spec_id int64, appid, goods_code string, account_id, ent_account_id, ent_id int64, buy_num int64, start_time, end_time string, bgss *[]*base_goods_spec) bool {
	return Mysql_BaseService.ExecTx("开通权益", func(tx *sql.Tx) bool {
		//互斥的功能失效掉
		ok1 := Mysql_BaseService.UpdateOrDeleteBySqlByTx(tx, `update base_power a inner join base_goods_spec_power b 
			on (a.appid=? and ((a.account_id=? and a.power_type=1) or (a.account_id=? and a.power_type=2)) and a.status=1 and b.appid=? and b.goods_code=? and b.spec_id=? and a.function_code=b.function_code) 
			inner join base_function c on (c.appid=? and c.status=1 and c.power_type=1 and c.code=a.function_code) 
			set a.status=0,update_time=?`, appid, account_id, ent_account_id, appid, goods_code, goods_spec_id, appid, NowFormat(Date_Full_Layout)) > -1
		power_values, wait_empower_values := []interface{}{}, []interface{}{}
		if start_time == "" {
			start_time = NowFormat(Date_Full_Layout)
		}
		for _, bgs := range *bgss {
			if bgs.Base_goods_spec_powers == nil {
				continue
			}
			for _, v := range bgs.Base_goods_spec_powers {
				if v.Base_function == nil {
					continue
				} else if v.Base_function.Haspower == 0 {
					continue
				} else if v.Power_type == 1 && account_id == 0 {
					continue
				} else if v.Power_type == 2 && (ent_account_id == 0 || ent_id == 0) {
					continue
				}
				power_values = append(power_values, appid, v.Id, v.Function_code, v.Power_type)
				if v.Power_type == 2 {
					power_values = append(power_values, ent_account_id)
				} else {
					power_values = append(power_values, account_id)
				}
				if end_time == "" {
					now := time.Now()
					end := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, time.Local)
					if strings.HasSuffix(v.Cycle, "d") {
						cycle := IntAll(strings.TrimSuffix(v.Cycle, "d"))
						end = end.AddDate(0, 0, cycle-1)
					} else if strings.HasSuffix(v.Cycle, "m") {
						cycle := IntAll(strings.TrimSuffix(v.Cycle, "m"))
						end = end.AddDate(0, cycle, 0)
					} else if strings.HasSuffix(v.Cycle, "y") {
						cycle := IntAll(strings.TrimSuffix(v.Cycle, "y"))
						end = end.AddDate(cycle, 0, 0)
					} else {
						logx.Error(appid, goods_code, goods_spec_id, v.Function_code, "无效的cycle", v.Cycle)
						continue
					}
					end_time = FormatDate(&end, Date_Full_Layout)
				}
				power_values = append(power_values, start_time, end_time)
				use_count := buy_num
				if bgs.Calculation_type == 2 {
					use_count = buy_num * v.Use_count
				}
				surplus_count := use_count
				if v.Base_function.Function_type == 2 {
					lastPower := b.FindMyLastPowerByFc(appid, v.Function_code, account_id, account_id)
					if lastPower != nil {
						surplus_count = lastPower.Surplus_count
					}
				}
				power_values = append(power_values, use_count, surplus_count, v.Limit_strategy, v.Strategy_count, 1, start_time, start_time)
				//
				if v.Power_type == 2 {
					wait_empower_values = append(wait_empower_values, appid, v.Id, v.Function_code, ent_id, start_time, end_time, use_count, v.Power_count, v.Limit_strategy, start_time)
				}
			}
		}
		if len(power_values) == 0 {
			logx.Error(appid, goods_code, goods_spec_id, account_id, ent_id, "没有找到需要开通的权益")
			return false
		}
		v1, v2 := Mysql_BaseService.InsertBatchByTx(tx, "base_power", []string{"appid", "goods_spec_power_id", "function_code", "power_type", "account_id", "start_time", "end_time", "use_count", "surplus_count", "limit_strategy", "strategy_count", "status", "create_time", "update_time"}, power_values)
		ok2 := true
		if len(wait_empower_values) > 0 {
			v5, v6 := Mysql_BaseService.InsertBatchByTx(tx, "base_ent_wait_empower", []string{"appid", "goods_spec_power_id", "function_code", "ent_id", "start_time", "end_time", "use_count", "empower_count", "limit_strategy", "create_time"}, wait_empower_values)
			ok2 = v5 > 0 && v6 > 0
		}
		return ok1 && ok2 && v1 > 0 && v2 > 0
	})
}

//取消权益
func (b *base_power) CancelPower(appid, goods_code string, spec_id, account_id, ent_account_id, ent_id int64) bool {
	accountId := account_id
	if accountId == 0 {
		accountId = ent_account_id
	}
	return Mysql_BaseService.ExecTx("取消权益", func(tx *sql.Tx) bool {
		nowFormat := NowFormat(Date_Full_Layout)
		var r1 int64 = 1
		if ent_id > 0 {
			r1 = Mysql_BaseService.UpdateOrDeleteBySqlByTx(tx, `update base_ent_wait_empower a inner join base_goods_spec_power b 
				on (a.appid=? and a.ent_id=? and a.end_time>? and b.appid=? and b.goods_code=? and b.spec_id=? and a.goods_spec_power_id=b.id) 
				set a.end_time=?`, appid, ent_id, nowFormat, appid, goods_code, spec_id, nowFormat)
		}
		r2 := Mysql_BaseService.UpdateOrDeleteBySqlByTx(tx, `update base_power a inner join base_goods_spec_power b 
			on (a.appid=? and a.account_id=? and a.status=1 and b.appid=? and b.goods_code=? and b.spec_id=? and a.goods_spec_power_id=b.id) 
			set a.status=-1,a.update_time=?`, appid, accountId, appid, goods_code, spec_id, nowFormat)
		return r1 > 0 || r2 > 0
	})
}
