package controllers

import (
	"encoding/json"
	"eta/eta_api/models"
	"eta/eta_api/services"
	"eta/eta_api/utils"
	"fmt"
	"github.com/shopspring/decimal"
	"html"
	"strconv"
	"strings"
	"time"
)

// BusinessConfController 商家配置
type BusinessConfController struct {
	BaseAuthController
}

type BusinessConfOpenController struct {
	BaseCommonController
}

// Save
// @Title 保存配置
// @Description 保存配置
// @Param	request	body map[string]interface{} true "type json string"
// @Success 200 Ret=200 操作成功
// @router /save [post]
func (this *BusinessConfController) Save() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req map[string]interface{}
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}

	// 获取配置信息
	confOb := new(models.BusinessConf)
	list, e := confOb.GetItemsByCondition("", make([]interface{}, 0), []string{}, "")
	if e != nil {
		br.Msg = "保存失败"
		br.ErrMsg = "获取配置列表失败, Err: " + e.Error()
		return
	}
	confMap := make(map[string]*models.BusinessConf)
	for _, c := range list {
		confMap[c.ConfKey] = c
	}

	openApprove := ""
	approveType := ""

	// 根据配置类型取值
	updates := make([]models.BusinessConfUpdate, 0)
	for k, v := range req {
		// 过滤掉表中没有的key
		conf := confMap[k]
		if conf == nil {
			continue
		}

		switch conf.ValType {
		case 1: // 字符串
			str, ok := v.(string)
			if !ok {
				continue
			}
			str = strings.TrimSpace(str)
			if conf.Necessary == 1 && str == "" {
				br.Msg = conf.Remark + "不可为空"
				return
			}
			updates = append(updates, models.BusinessConfUpdate{
				ConfKey: k,
				ConfVal: str,
			})

			// 取出审批参数
			if k == models.BusinessConfIsReportApprove {
				openApprove = str
			}
			if k == models.BusinessConfReportApproveType {
				// 打开审批默认为内部审批方式
				if openApprove == "true" && str == "" {
					str = models.BusinessConfReportApproveTypeEta
				}
				approveType = str
			}
		case 2: // 数值
			vDeci, err := decimal.NewFromString(fmt.Sprint(v))
			if err != nil {
				continue
			}
			num, _ := vDeci.Float64()
			if conf.Necessary == 1 && num <= 0 {
				br.Msg = conf.Remark + "不可为空"
				return
			}
			val := strconv.FormatFloat(num, 'f', 0, 64)
			updates = append(updates, models.BusinessConfUpdate{
				ConfKey: k,
				ConfVal: val,
			})
		case 3: // 字符串数组
			arr, ok := v.([]interface{})
			if !ok {
				continue
			}
			if conf.Necessary == 1 && len(arr) == 0 {
				br.Msg = conf.Remark + "不可为空"
				return
			}
			strArr := make([]string, 0)
			for _, a := range arr {
				if s, ok2 := a.(string); ok2 {
					strArr = append(strArr, s)
				}
			}
			val := strings.Join(strArr, ",")
			updates = append(updates, models.BusinessConfUpdate{
				ConfKey: k,
				ConfVal: val,
			})
		case 4: // 富文本
			content, ok := v.(string)
			if !ok {
				continue
			}
			content = strings.TrimSpace(content)
			if conf.Necessary == 1 && content == "" {
				br.Msg = conf.Remark + "不可为空"
				return
			}
			content = html.EscapeString(content)
			updates = append(updates, models.BusinessConfUpdate{
				ConfKey: k,
				ConfVal: content,
			})
		}
	}

	// 校验报告审批是否可以切换
	confOpenApprove := confMap[models.BusinessConfIsReportApprove]
	confApproveType := confMap[models.BusinessConfReportApproveType]
	if confOpenApprove != nil && confApproveType != nil {
		// 仅校验有审批->无审批, 或是有审批->切换审批方式的情况
		if openApprove == "false" && confOpenApprove.ConfVal == "true" || (openApprove == "true" && openApprove == confOpenApprove.ConfVal && confApproveType.ConfVal != approveType) {
			ok, e := services.CheckCloseReportApproveConf()
			if e != nil {
				br.Msg = "保存失败"
				br.ErrMsg = "校验是否可以关闭报告审批失败, Err: " + e.Error()
				return
			}
			if !ok {
				br.Msg = "当前有未走完流程的报告,请走完流程后再做变更"
				return
			}
		}
		// 审批设置切换对未发布/待提交报告状态的重置
		needReset := false
		changeType := ""
		if openApprove == "false" && confOpenApprove.ConfVal == "true" {
			needReset = true
		}
		if openApprove == "true" && confOpenApprove.ConfVal == "false" {
			needReset = true
			changeType = approveType
		}
		if openApprove == "true" && openApprove == confOpenApprove.ConfVal && confApproveType.ConfVal != approveType {
			needReset = true
			changeType = approveType
		}
		if needReset {
			go services.ConfigChangeResetReportState(changeType)
		}
	}

	if len(updates) > 0 {
		if e = models.UpdateBusinessConfMulti(updates); e != nil {
			br.Msg = "保存失败"
			br.ErrMsg = "保存商家配置失败, Err: " + e.Error()
			return
		}
	}
	// 删除研报声明缓存
	disclaimerCacheKey := "hongze_yb:business_conf:disclaimer"
	_ = utils.Rc.Delete(disclaimerCacheKey)

	// 操作日志
	go func() {
		b, e := json.Marshal(req)
		if e != nil {
			return
		}
		recordOb := new(models.BusinessConfOperationRecord)
		recordOb.SysUserId = sysUser.AdminId
		recordOb.SysRealName = sysUser.RealName
		recordOb.Content = string(b)
		recordOb.CreateTime = time.Now().Local()
		_ = recordOb.Create()
	}()

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// Fetch
// @Title 获取配置
// @Description 获取配置
// @Success 200 Ret=200 获取成功
// @router /fetch [get]
func (this *BusinessConfController) Fetch() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	list, e := models.GetBusinessConf()
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取商家配置失败, Err: " + e.Error()
		return
	}

	br.Data = list
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// CodeEncrypt
// @Title 商家编码加密
// @Description 商家编码加密
// @Success 200 Ret=200 获取成功
// @router /code_encrypt [get]
func (this *BusinessConfOpenController) CodeEncrypt() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()

	res := ""
	if utils.BusinessCode != "" {
		res = utils.MD5(fmt.Sprintf("%s%s", utils.BusinessCode, utils.BusinessCodeSalt))
	}

	br.Data = res
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
}

// SingleSave
// @Title 保存单项配置
// @Description 保存配置
// @Param	request	body map[string]interface{} true "type json string"
// @Success 200 Ret=200 操作成功
// @router /single/save [post]
func (this *BusinessConfController) SingleSave() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req models.BusinessConfSingleSaveReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}

	if req.ConfKey == "" {
		br.Msg = "参数异常!"
		return
	}

	// 设置白名单,只有白名单里的配置才允许保存
	writeList := []string{models.BusinessConfEdbStopRefreshRule}
	if !utils.InArrayByStr(writeList, req.ConfKey) {
		br.Msg = "不支持该项配置"
		return
	}
	// 获取配置信息
	confOb, e := models.GetBusinessConfByKey(req.ConfKey)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "配置不存在"
			return
		}
		br.Msg = "保存失败"
		br.ErrMsg = "获取配置失败, Err: " + e.Error()
		return
	}

	switch confOb.ValType {
	case 1: // 字符串
		req.ConfVal = strings.TrimSpace(req.ConfVal)
		if confOb.Necessary == 1 && req.ConfVal == "" {
			br.Msg = confOb.Remark + "不可为空"
			return
		}
	}
	if req.ConfKey == models.BusinessConfEdbStopRefreshRule {
		//将json转为结构体
		rule := new(models.EdbStopRefreshRule)
		err := json.Unmarshal([]byte(req.ConfVal), rule)
		if err != nil {
			br.Msg = confOb.Remark + "格式错误"
			return
		}
		if rule.IsOpen == 1 && (rule.EdbStopDays == 0 || rule.BaseIndexStopDays == 0) {
			br.Msg = confOb.Remark + "天数不可设置为0"
			return
		}
	}
	if confOb.ConfVal != req.ConfVal {
		confOb.ConfVal = req.ConfVal
		if e = confOb.Update([]string{"ConfVal"}); e != nil {
			br.Msg = "保存失败"
			br.ErrMsg = "保存商家配置失败, Err: " + e.Error()
			return
		}
		// 操作日志
		go func() {
			b, e := json.Marshal(req)
			if e != nil {
				return
			}
			recordOb := new(models.BusinessConfOperationRecord)
			recordOb.SysUserId = sysUser.AdminId
			recordOb.SysRealName = sysUser.RealName
			recordOb.Content = string(b)
			recordOb.CreateTime = time.Now().Local()
			_ = recordOb.Create()
		}()
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// GetSingle
// @Title 获取单项配置
// @Description 保存配置
// @Param	request	body map[string]interface{} true "type json string"
// @Success 200 Ret=200 操作成功
// @router /single [get]
func (this *BusinessConfController) GetSingle() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	confKey := this.GetString("ConfKey")
	if confKey == "" {
		br.Msg = "参数异常!"
		return
	}

	// 设置白名单,只有白名单里的配置才允许保存
	writeList := []string{models.BusinessConfEdbStopRefreshRule}
	if !utils.InArrayByStr(writeList, confKey) {
		br.Msg = "不支持该项配置"
		return
	}
	// 获取配置信息
	confOb, e := models.GetBusinessConfByKey(confKey)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "配置不存在"
			return
		}
		br.Msg = "保存失败"
		br.ErrMsg = "获取配置失败, Err: " + e.Error()
		return
	}
	resp := models.BusinessConfSingleResp{ConfVal: confOb.ConfVal}
	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
	br.Data = resp
}