package data_manage

import (
	"encoding/json"
	"eta_gn/eta_api/controllers"
	"eta_gn/eta_api/models"
	"eta_gn/eta_api/models/data_manage"
	"eta_gn/eta_api/models/data_manage/request"
	"eta_gn/eta_api/services/data"
	"eta_gn/eta_api/utils"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"strconv"
	"strings"
	"time"
)

// EdbBusinessController 自有数据(商家)
type EdbBusinessController struct {
	controllers.BaseAuthController
}

// SourceList
// @Title 来源列表
// @Description 来源列表接口
// @Success 200 {object} []*data_manageEdbBusinessSource
// @router /business_data/source/list [get]
func (c *EdbBusinessController) SourceList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	obj := data_manage.EdbBusinessSource{}
	list, err := obj.GetAllList()
	if err != nil && !utils.IsErrNoRow(err) {
		br.Msg = "获取失败"
		br.ErrMsg = "获取数据失败,Err:" + err.Error()
		return
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = list
}

// List
// @Title 获取指标列表
// @Description 获取指标列表接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
// @Param   Frequency   query   string  true       "频度"
// @Param   Source   query   int  true       "来源"
// @Param   Keywords   query   string  true       "编码/名称关键词"
// @Success 200 {object} models.DataListResp
// @router /business_data/list [get]
func (c *EdbBusinessController) List() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	req := &request.BusinessDataListReq{}
	if e := c.ParseForm(req); e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "参数解析失败, Err: " + e.Error()
		return
	}

	pageSize := req.PageSize
	currentIndex := req.CurrentIndex
	keywords := req.Keywords
	frequency := req.Frequency
	source := req.Source

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = utils.StartIndex(currentIndex, pageSize)

	var condition string
	var pars []interface{}

	if keywords != "" {
		keywordSlice := strings.Split(keywords, " ")
		if len(keywordSlice) > 0 {
			tmpConditionSlice := make([]string, 0)
			tmpConditionSlice = append(tmpConditionSlice, ` a.index_name like ? or a.index_code like ? `)
			pars = utils.GetLikeKeywordPars(pars, keywords, 2)

			for _, v := range keywordSlice {
				if v == ` ` || v == `` {
					continue
				}
				tmpConditionSlice = append(tmpConditionSlice, ` a.index_name like ? or a.index_code like ? `)
				pars = utils.GetLikeKeywordPars(pars, v, 2)
			}
			condition += ` AND (` + strings.Join(tmpConditionSlice, " or ") + `)`

		} else {
			condition += ` a.index_name like ? or a.index_code like ? `
			pars = utils.GetLikeKeywordPars(pars, keywords, 2)
		}
	}

	if frequency != "" {
		condition += ` AND a.frequency = ? `
		pars = append(pars, frequency)
	}

	if source > 0 {
		condition += ` AND a.source = ? `
		pars = append(pars, source)
	}

	// 排序, 默认创建时间倒序
	orderFields := map[int]string{
		0: data_manage.BaseFromBusinessIndexCols.CreateTime, 1: data_manage.BaseFromBusinessIndexCols.StartDate,
		2: data_manage.BaseFromBusinessIndexCols.EndDate,
	}
	orderType := map[int]string{0: "DESC", 1: "ASC", 2: "DESC"}
	orderRule := ``

	_, ok1 := orderFields[req.SortField]
	_, ok2 := orderType[req.SortRule]
	if ok1 && ok2 {
		orderRule = fmt.Sprintf("%s %s", orderFields[req.SortField], orderType[req.SortRule])
	}

	obj := data_manage.BaseFromBusinessIndex{}

	total, err := obj.GetListCount(condition, pars)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	list, err := obj.GetPageItemsByCondition(condition, pars, orderRule, startSize, pageSize)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取失败,Err:" + err.Error()
		return
	}
	if len(list) <= 0 {
		list = make([]*data_manage.BaseFromBusinessIndexItem, 0)
	}

	page := paging.GetPaging(currentIndex, pageSize, total)
	resp := data_manage.BusinessIndexListResp{
		List:   list,
		Paging: page,
	}

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

// AddCheck
// @Title 新增校验
// @Description 新增校验
// @Param	request	body request.BusinessDataBatchAddCheckReq true "type json string"
// @Success 200 string "操作成功"
// @router /business_data/add_check [post]
func (c *EdbBusinessController) AddCheck() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		c.Data["json"] = br
		c.ServeJSON()
	}()
	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req *request.BusinessDataBatchAddCheckReq
	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	codeMax := 100
	codeLen := len(req.IndexCodes)

	// 获取指标库已有指标
	existsEdb, e := data_manage.GetEdbCodesBySource(utils.DATA_SOURCE_BUSINESS)
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取自有数据已添加的指标失败, Err: " + e.Error()
		return
	}
	existMap := make(map[string]*data_manage.EdbInfo)
	for _, v := range existsEdb {
		existMap[v.EdbCode] = v
	}

	list := make([]*data_manage.BaseFromBusinessIndexItem, 0)
	obj := data_manage.BaseFromBusinessIndex{}
	if !req.ListAll {
		// 非全选-不需要频率等筛选条件
		if codeLen == 0 {
			br.Msg = "请选择指标"
			return
		}
		if codeLen > codeMax {
			br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
			return
		}

		// 查询选中的指标
		cond := fmt.Sprintf(` AND %s IN (%s)`, data_manage.BaseFromBusinessIndexCols.IndexCode, utils.GetOrmInReplace(codeLen))
		pars := make([]interface{}, 0)
		pars = append(pars, req.IndexCodes)
		list, e = obj.GeItemsByCondition(cond, pars, 0)
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取自有数据原始指标列表失败, Err: " + e.Error()
			return
		}
	} else {
		// 全选-需要频率等筛选条件
		condition := ``
		pars := make([]interface{}, 0)

		// 筛选项
		req.Keywords = strings.TrimSpace(req.Keywords)
		if req.Keywords != "" {
			keywordSlice := strings.Split(req.Keywords, " ")
			if len(keywordSlice) > 0 {
				tmpConditionSlice := make([]string, 0)
				tmpConditionSlice = append(tmpConditionSlice, ` a.index_name like ? or a.index_code like ? `)
				pars = utils.GetLikeKeywordPars(pars, req.Keywords, 2)

				for _, v := range keywordSlice {
					if v == ` ` || v == `` {
						continue
					}
					tmpConditionSlice = append(tmpConditionSlice, ` a.index_name like ? or a.index_code like ? `)
					pars = utils.GetLikeKeywordPars(pars, v, 2)
				}
				condition += ` AND (` + strings.Join(tmpConditionSlice, " or ") + `)`

			} else {
				condition += ` a.index_name like ? or a.index_code like ? `
				pars = utils.GetLikeKeywordPars(pars, req.Keywords, 2)
			}
		}

		if req.Frequency != "" {
			condition += ` AND a.frequency = ? `
			pars = append(pars, req.Frequency)
		}

		if req.Source > 0 {
			condition += ` AND a.source = ? `
			pars = append(pars, req.Source)
		}

		// 排除对应指标
		if codeLen > 0 {
			condition += fmt.Sprintf(` AND a.%s NOT IN (%s)`, data_manage.BaseFromBusinessIndexCols.IndexCode, utils.GetOrmInReplace(codeLen))
			pars = append(pars, req.IndexCodes)
		}
		// 查询max+1个指标
		list, e = obj.GeItemsByCondition(condition, pars, codeMax+1)
		if e != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取外部原始指标列表失败, Err: " + e.Error()
			return
		}
	}

	if len(list) > codeMax {
		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
		return
	}

	resp := make([]*data_manage.BaseFromBusinessIndexItem, 0)
	for _, v := range list {
		if v.EdbInfoId > 0 {
			v.EdbExist = 1
		}
		resp = append(resp, v)
	}

	br.Data = resp
	br.Msg = "校验成功"
	br.Ret = 200
	br.Success = true
}

// NameCheck
// @Title 重名校验
// @Description 批量新增
// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
// @Success 200 string "操作成功"
// @router /business_data/name_check [post]
func (c *EdbBusinessController) NameCheck() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		c.Data["json"] = br
		c.ServeJSON()
	}()
	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	var req []*data_manage.AddEdbInfoReq
	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if len(req) == 0 {
		br.Msg = "请选择指标"
		return
	}

	type NameCheckResult struct {
		EdbCode string
		EdbName string
		Exist   bool
	}
	indexNames := make([]string, 0)
	resp := make([]*NameCheckResult, 0)
	for _, v := range req {
		v.EdbCode = strings.TrimSpace(v.EdbCode)
		if v.EdbCode == "" {
			br.Msg = "指标ID不可为空"
			return
		}
		v.EdbName = strings.TrimSpace(v.EdbName)
		if v.EdbName == "" {
			br.Msg = "请输入指标名称"
			return
		}
		indexNames = append(indexNames, v.EdbName)
		resp = append(resp, &NameCheckResult{
			EdbCode: v.EdbCode,
			EdbName: v.EdbName,
		})
	}

	// 重名校验
	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames, utils.EDB_INFO_TYPE)
	if e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "获取重名指标失败, Err: " + e.Error()
		return
	}
	nameExists := make(map[string]bool)
	for _, v := range edbList {
		nameExists[v.EdbName] = true
	}
	if len(nameExists) > 0 {
		for _, v := range resp {
			v.Exist = nameExists[v.EdbName]
		}
	}

	br.Data = resp
	br.Msg = "校验成功"
	br.Ret = 200
	br.Success = true
}

// BatchAdd
// @Title 批量新增
// @Description 批量新增
// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
// @Success 200 string "操作成功"
// @router /business_data/batch_add [post]
func (c *EdbBusinessController) BatchAdd() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		c.Data["json"] = br
		c.ServeJSON()
	}()
	sysUser := c.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	deleteCache := true
	cacheKey := "CACHE_EDB_INFO_BATCH_ADD_BUSINESS_" + strconv.Itoa(sysUser.AdminId)
	defer func() {
		if deleteCache {
			_ = utils.Rc.Delete(cacheKey)
		}
	}()
	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
		deleteCache = false
		br.Msg = "系统处理中,请稍后重试!"
		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(c.Ctx.Input.RequestBody)
		return
	}
	var req []*data_manage.AddEdbInfoReq
	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if len(req) == 0 {
		br.Msg = "请选择指标"
		return
	}
	if len(req) > 30 {
		br.Msg = "批量添加指标数量不得超过30个"
		return
	}
	indexNames := make([]string, 0)
	for _, v := range req {
		v.EdbCode = strings.TrimSpace(v.EdbCode)
		if v.EdbCode == "" {
			br.Msg = "指标ID不可为空"
			return
		}
		v.EdbName = strings.TrimSpace(v.EdbName)
		if v.EdbName == "" {
			br.Msg = "请输入指标名称"
			return
		}
		indexNames = append(indexNames, v.EdbName)
		v.Frequency = strings.TrimSpace(v.Frequency)
		if v.Frequency == "" {
			br.Msg = "请选择频度"
			return
		}
		v.Unit = strings.TrimSpace(v.Unit)
		if v.Unit == "" {
			br.Msg = "请输入单位"
			return
		}
		if v.ClassifyId <= 0 {
			br.Msg = "请选择分类"
			return
		}
	}

	// 限定同一时间最多批量新增100个指标
	for _, v := range req {
		var r data.BusinessIndexSource2EdbReq
		r.EdbCode = v.EdbCode
		r.EdbName = v.EdbName
		r.Frequency = v.Frequency
		r.Unit = v.Unit
		r.ClassifyId = v.ClassifyId
		r.AdminId = sysUser.AdminId
		r.AdminRealName = sysUser.RealName

		edbInfo, e, errMsg, skip := data.BusinessIndexSource2Edb(r, c.Lang)
		if e != nil {
			br.Msg = "操作失败"
			if errMsg != "" {
				br.Msg = errMsg
			}
			br.ErrMsg = e.Error()
			return
		}
		if skip {
			continue
		}

		// 新增操作日志
		{
			edbLog := new(data_manage.EdbInfoLog)
			edbLog.EdbInfoId = edbInfo.EdbInfoId
			edbLog.SourceName = edbInfo.SourceName
			edbLog.Source = edbInfo.Source
			edbLog.EdbCode = edbInfo.EdbCode
			edbLog.EdbName = edbInfo.EdbName
			edbLog.ClassifyId = edbInfo.ClassifyId
			edbLog.SysUserId = sysUser.AdminId
			edbLog.SysUserRealName = sysUser.RealName
			edbLog.CreateTime = time.Now()
			edbLog.Content = string(c.Ctx.Input.RequestBody)
			edbLog.Status = "新增指标"
			edbLog.Method = c.Ctx.Input.URI()
			go data_manage.AddEdbInfoLog(edbLog)
		}
	}

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

// DataList
// @Title 获取指标数据列表
// @Description 获取指标数据列表接口
// @Param   PageSize   query   int  true       "每页数据条数"
// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
// @Param   IndexCode   query   string  true       "频度"
// @Success 200 {object} models.DataListResp
// @router /business_data/data/list [get]
func (c *EdbBusinessController) DataList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		c.Data["json"] = br
		c.ServeJSON()
	}()

	req := &request.BusinessDataDataListReq{}
	if e := c.ParseForm(req); e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "参数解析失败, Err: " + e.Error()
		return
	}

	pageSize := req.PageSize
	currentIndex := req.CurrentIndex

	var startSize int
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = utils.StartIndex(currentIndex, pageSize)

	if req.IndexCode == "" {
		br.Msg = "指标编码为空"
		br.ErrMsg = "指标编码为空"
		br.IsSendEmail = false
		return
	}

	// 获取分页数据
	dataCount, dataList, err := data.GetPageBaseBusinessIndexData(req.IndexCode, startSize, pageSize)
	if err != nil && !utils.IsErrNoRow(err) {
		br.Msg = "获取指标信息失败"
		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
		return
	}
	page := paging.GetPaging(currentIndex, pageSize, dataCount)
	resp := data_manage.BusinessIndexDataListResp{
		List:   dataList,
		Paging: page,
	}

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