package controllers

import (
	"encoding/json"
	"eta/eta_forum_admin/models"
	"eta/eta_forum_admin/services"
	"eta/eta_forum_admin/utils"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"strconv"
	"strings"
	"time"
)

type ChartInfoController struct {
	BaseAuthController
}

// ChartInfoDetail
// @Title 获取图表详情
// @Description 获取图表详情接口
// @Param   ChartInfoId   query   int  true       "图表id"
// @Param   DateType   query   int  true       "日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"
// @Param   StartDate   query   string  true       "自定义开始日期"
// @Param   EndDate   query   string  true       "自定义结束日期"
// @Param   Calendar   query   string  true       "公历/农历"
// @Param   SeasonStartDate   query   string  true       "季节性图开始日期"
// @Param   SeasonEndDate   query   string  true       "季节性图结束日期"
// @Param   EdbInfoId   query   string  true       "指标ID,多个用英文逗号隔开"
// @Param   ChartType   query   int  true       "生成样式:1:曲线图,2:季节性图"
// @Success 200 {object} models.ChartInfoDetailResp
// @router /detail [get]
func (this *ChartInfoController) ChartInfoDetail() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	chartInfoId, _ := this.GetInt("ChartInfoId")

	dateType, _ := this.GetInt("DateType")
	fmt.Println("dateType:", dateType)
	if dateType <= 0 {
		dateType = 3
	}

	startDate := this.GetString("StartDate")
	endDate := this.GetString("EndDate")
	startYear, _ := this.GetInt("StartYear")

	edbInfoId := this.GetString("EdbInfoId")
	chartType, _ := this.GetInt("ChartType")

	calendar := this.GetString("Calendar")
	if calendar == "" {
		calendar = "公历"
	}

	var err error
	chartInfo := new(models.ChartInfoView)
	chartInfo.HaveOperaAuth = true

	if chartInfoId > 0 {
		chartInfo, err = models.GetChartInfoViewById(chartInfoId)
		if err != nil {
			if err.Error() == utils.ErrNoRow() {
				br.Msg = "该图表已删除,自动查看下一图表"
				br.ErrMsg = "该图表已删除,自动查看下一图表,Err:" + err.Error()
				br.Ret = 406
				return
			}
			br.Msg = "获取失败"
			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
			return
		}
		chartType = chartInfo.ChartType

		// 获取主题样式
		chartTheme, err := services.GetChartThemeConfig(chartInfo.ChartThemeId, chartInfo.Source, chartInfo.ChartType)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取主题信息失败,Err:" + err.Error()
			return
		}
		chartInfo.ChartThemeStyle = chartTheme.Config
		chartInfo.ChartThemeId = chartTheme.ChartThemeId
	}

	resp := new(models.ChartInfoDetailResp)

	mappingList := make([]*models.ChartEdbInfoMapping, 0)
	if chartInfoId > 0 {
		mappingList, err = models.GetChartEdbMappingList(chartInfoId)
		if err != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
			return
		}
	} else {
		if edbInfoId != "" {
			edbInfoIds := strings.Split(edbInfoId, ",")
			mappingList, err = models.GetChartEdbMappingListByEdbInfoId(edbInfoIds)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
				return
			}
		}
	}

	// 图表额外数据参数
	extraConfigStr := chartInfo.ExtraConfig
	// 柱方图的一些配置
	var barConfig models.BarChartInfoReq
	if chartInfo != nil && chartInfo.ChartType == 7 {
		if chartInfo.BarConfig == `` {
			br.Msg = "柱方图未配置"
			br.ErrMsg = "柱方图未配置"
			return
		}
		err := json.Unmarshal([]byte(chartInfo.BarConfig), &barConfig)
		if err != nil {
			br.Msg = "柱方图配置异常"
			br.ErrMsg = "柱方图配置异常"
			return
		}
		extraConfigStr = chartInfo.BarConfig
	}
	yearMax := 0
	if dateType == utils.DateTypeNYears {
		for _, v := range mappingList {
			if v.LatestDate != "" {
				lastDateT, tErr := time.Parse(utils.FormatDate, v.LatestDate)
				if tErr != nil {
					br.Msg = "获取失败"
					br.ErrMsg = "获取图表日期信息失败,Err:" + tErr.Error()
					return
				}
				if lastDateT.Year() > yearMax {
					yearMax = lastDateT.Year()
				}
			}
		}
	}
	// 开始/结束日期
	startDate, endDate = utils.GetDateByDateTypeV2(dateType, startDate, endDate, startYear, yearMax)

	// 获取图表中的指标数据
	edbList, xEdbIdValue, yDataList, dataResp, err, errMsg := services.GetChartEdbData(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr, chartInfo.SeasonExtraConfig)
	if err != nil {
		br.Msg = "获取失败"
		if errMsg != `` {
			br.Msg = errMsg
		}
		br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
		return
	}
	// 单位
	if chartType == utils.CHART_TYPE_BAR && len(yDataList) > 0 {
		chartInfo.Unit = yDataList[0].Unit
		chartInfo.UnitEn = yDataList[0].UnitEn
	}
	warnEdbList := make([]string, 0)
	for _, v := range edbList {
		if v.IsNullData {
			warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
		}
	}
	if len(warnEdbList) > 0 {
		chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
	}
	if chartInfoId > 0 && chartInfo != nil {
		if chartInfo.ChartType == 2 {
			if chartInfo.SeasonStartDate != "" {
				chartInfo.StartDate = chartInfo.SeasonStartDate
				chartInfo.EndDate = chartInfo.SeasonEndDate
				if chartInfo.DateType == 3 {
					chartInfo.DateType = 5
				}
			}
		}
	}

	// 图表的指标来源
	sourceNameList, sourceNameEnList := services.GetEdbSourceByEdbInfoIdList(edbList)
	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
	//判断是否需要展示英文标识
	chartInfo.IsEnChart = services.CheckIsEnChart(chartInfo.ChartNameEn, edbList, chartInfo.Source, chartInfo.ChartType)

	resp.EdbInfoList = edbList
	resp.XEdbIdValue = xEdbIdValue
	resp.YDataList = yDataList
	resp.DataResp = dataResp

	chartInfo.Button = models.ChartViewButton{
		IsEdit:    chartInfo.IsEdit,
		IsEnChart: chartInfo.IsEnChart,
		IsAdd:     chartInfo.IsAdd,
		IsCopy:    true,
		IsSetName: chartInfo.IsSetName,
	}

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

// ChartInfoSearchByEs
// @Title 图表模糊搜索(从es获取)
// @Description  图表模糊搜索(从es获取)
// @Param   Keyword   query   string  true       "图表名称"
// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
// @Success 200 {object} models.ChartInfo
// @router /search_by_es [get]
func (this *ChartInfoController) ChartInfoSearchByEs() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}
	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")

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

	keyword := this.GetString("Keyword")

	//只看我的
	sysUserIds := this.GetString("SysUserIds")
	adminIdsSlice := make([]int, 0)
	if sysUserIds != "" {
		adminIds := strings.Split(sysUserIds, ",")
		if len(adminIds) == 0 {
			br.Msg = "请选择正确的创建人"
			return
		}
		for _, adminId := range adminIds {
			adminIdInt, e := strconv.Atoi(adminId)
			if e != nil {
				br.Msg = "请选择正确的创建人"
				return
			}
			adminIdsSlice = append(adminIdsSlice, adminIdInt)
		}
	}

	var searchList []*models.ChartInfo
	var total int64
	var err error

	if keyword != "" {
		searchList, total, err = services.EsSearchChartInfo(keyword, adminIdsSlice, []int{utils.CHART_SOURCE_DEFAULT}, startSize, pageSize)
	} else {
		total, searchList, err = models.ChartInfoSearchByEmptyKeyWord(adminIdsSlice, []int{utils.CHART_SOURCE_DEFAULT}, startSize, pageSize)
		if err != nil && err.Error() != utils.ErrNoRow() {
			br.Msg = "获取失败"
			br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
			return
		}
	}

	finalList := make([]*models.ChartInfoMore, 0)
	if len(searchList) > 0 {
		// 涉及分类id
		classifyIdList := make([]int, 0)
		// 图表id
		chartInfoIdList := make([]int, 0)

		chartInfoIds := ""
		chartEdbMap := make(map[int][]*models.ChartEdbInfoMapping)

		for _, v := range searchList {
			chartInfoIds += strconv.Itoa(v.ChartInfoId) + ","
			classifyIdList = append(classifyIdList, v.ChartClassifyId)
			chartInfoIdList = append(chartInfoIdList, v.ChartInfoId)
		}
		if chartInfoIds != "" {
			chartInfoIds = strings.Trim(chartInfoIds, ",")
			//判断是否需要展示英文标识
			edbList, e := models.GetChartEdbMappingListByChartInfoIds(chartInfoIds)
			if e != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取图表,指标信息失败,Err:" + e.Error()
				return
			}
			for _, v := range edbList {
				chartEdbMap[v.ChartInfoId] = append(chartEdbMap[v.ChartInfoId], v)
			}
		}
		// 当前列表中的分类map
		chartClassifyMap := make(map[int]*models.ChartClassify)

		// 图表分类
		{
			chartClassifyList, err := models.GetChartClassifyByIdList(classifyIdList)
			if err != nil {
				br.Msg = "获取失败"
				br.ErrMsg = "获取图表分类失败,Err:" + err.Error()
				return
			}
			for _, v := range chartClassifyList {
				chartClassifyMap[v.ChartClassifyId] = v
			}
		}

		for _, v := range searchList {
			tmp := new(models.ChartInfoMore)
			tmp.ChartInfo = *v
			//判断是否需要展示英文标识
			if edbTmpList, ok := chartEdbMap[v.ChartInfoId]; ok {
				tmp.IsEnChart = services.CheckIsEnChart(v.ChartNameEn, edbTmpList, v.Source, v.ChartType)
			}

			// 图表权限

			finalList = append(finalList, tmp)
		}
	}
	//新增搜索词记录
	{
		searchKeyword := new(models.SearchKeyword)
		searchKeyword.KeyWord = keyword
		searchKeyword.CreateTime = time.Now()
		go models.AddSearchKeyword(searchKeyword)
	}

	page := paging.GetPaging(currentIndex, pageSize, int(total))
	resp := models.ChartInfoListByEsResp{
		Paging: page,
		List:   finalList,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// ChartList
// @Title 根据分类创建人姓名等获取图表列表
// @Description 根据分类创建人姓名等获取图表列表
// @Param   SysUserIds   query   string  true       "根据创建人查询"
// @Param   ChartClassifyIds   query   string  true       "图片分类id"
// @Success 200 {object} models.ChartClassifyListResp
// @router /list [get]
func (this *ChartInfoController) ChartList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()

	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	resp := new(models.ChartClassifyListResp)

	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	chartClassifyIds := this.GetString("ChartClassifyIds")
	sysUserIds := this.GetString("SysUserIds")
	chartName := this.GetString("ChartName")

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

	condition := ""
	pars := make([]interface{}, 0)

	if chartClassifyIds != "" {
		classifyIds := strings.Split(chartClassifyIds, ",")
		if len(classifyIds) == 0 {
			br.Msg = "请选择正确的分类"
			return
		}
		classifyIdSlice := make([]int, 0)
		for _, id := range classifyIds {
			tmp, e := strconv.Atoi(id)
			if e != nil {
				br.Msg = "请选择正确的分类"
				return
			}
			classifyIdSlice = append(classifyIdSlice, tmp)
		}
		condition += "  AND chart_classify_id in (" + utils.GetOrmInReplace(len(classifyIdSlice)) + ") "
		pars = append(pars, classifyIdSlice)
	}

	if sysUserIds != "" {
		adminIds := strings.Split(sysUserIds, ",")
		if len(adminIds) == 0 {
			br.Msg = "请选择正确的创建人"
			return
		}
		adminIdsSlice := make([]int, 0)
		for _, adminId := range adminIds {
			adminIdInt, e := strconv.Atoi(adminId)
			if e != nil {
				br.Msg = "请选择正确的创建人"
				return
			}
			adminIdsSlice = append(adminIdsSlice, adminIdInt)
		}
		condition += "  AND sys_user_id in (" + utils.GetOrmInReplace(len(adminIds)) + ") "
		pars = append(pars, adminIdsSlice)
	}
	if chartName != "" {
		condition += " AND chart_name LIKE ? "
		pars = append(pars, utils.GetLikeKeyword(chartName))
	}
	allChartInfo, err := models.GetChartInfoByConditionPage(utils.CHART_SOURCE_DEFAULT, condition, pars, startSize, pageSize)
	if err != nil && err.Error() != utils.ErrNoRow() {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
		return
	}
	total, err := models.GetChartInfoTotalByCondition(utils.CHART_SOURCE_DEFAULT, condition, pars)
	if err != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取图表总数失败,Err:" + err.Error()
		return
	}

	if len(allChartInfo) > 0 {
		adminIds := make([]int, 0)
		for _, v := range allChartInfo {
			adminIds = append(adminIds, v.SysUserId)
		}
		adminCompanyMap, er := services.GetCompanyNameByAdmins(adminIds)
		if er != nil {
			br.Msg = "获取失败"
			br.ErrMsg = "获取机构失败,Err:" + er.Error()
			return
		}
		for k, v := range allChartInfo {
			v.Children = make([]*models.ChartClassifyItems, 0)
			if n, ok := adminCompanyMap[v.SysUserId]; ok {
				allChartInfo[k].Company = n
			}
		}
	}
	page := paging.GetPaging(currentIndex, pageSize, int(total))
	resp.AllNodes = allChartInfo
	resp.Paging = page
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}