package data_manage

import (
	"encoding/json"
	"eta/eta_api/models/data_manage/line_equation/request"
	"eta/eta_api/services/alarm_msg"
	"eta/eta_api/utils"
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"strconv"
	"strings"
	"time"
)

// MultipleGraphConfig 多图配置表
type MultipleGraphConfig struct {
	MultipleGraphConfigId int       `orm:"column(multiple_graph_config_id);pk"`
	EdbInfoIdA            int       `description:"指标A"`
	EdbInfoIdB            int       `description:"指标B"`
	Curve                 string    `description:"曲线图配置"`
	Correlation           string    `description:"相关性配置"`
	RollingCorrelation    string    `description:"滚动相关性配置"`
	SysUserId             int       `description:"操作人id"`
	SysUserRealName       string    `description:"操作人真实姓名"`
	ModifyTime            time.Time `description:"最近一次修改时间"`
	CreateTime            time.Time `description:"添加时间"`
}

// AddMultipleGraphConfig 新增多图配置
func AddMultipleGraphConfig(item *MultipleGraphConfig) (err error) {
	o := orm.NewOrmUsingDB("data")
	// 表格信息入库
	lastId, err := o.Insert(item)
	if err != nil {
		return
	}
	item.MultipleGraphConfigId = int(lastId)
	return
}

// Update 更新 基础信息
func (item *MultipleGraphConfig) Update(cols []string) (err error) {
	o := orm.NewOrmUsingDB("data")
	_, err = o.Update(item, cols...)
	return
}

// GetMultipleGraphConfigById 根据配置id获取配置
func GetMultipleGraphConfigById(id int) (item *MultipleGraphConfig, err error) {
	o := orm.NewOrmUsingDB("data")
	sql := `SELECT * FROM multiple_graph_config WHERE multiple_graph_config_id = ? `
	// 表格信息入库
	err = o.Raw(sql, id).QueryRow(&item)
	return
}

// CurveConfig 曲线图配置
type CurveConfig struct {
	DateType    int     `description:"日期类型:1:00年至今,2:10年至今,3:15年至今，4：年初至今，5:自定义时间"`
	StartDate   string  `description:"自定义开始日期"`
	EndDate     string  `description:"自定义结束日期"`
	LeftMin     float64 `description:"图表左侧最小值"`
	LeftMax     float64 `description:"图表左侧最大值"`
	RightMin    float64 `description:"图表右侧最小值"`
	RightMax    float64 `description:"图表右侧最大值"`
	Right2Min   float64 `description:"图表右侧最小值"`
	Right2Max   float64 `description:"图表右侧最大值"`
	IsOrder     bool    `description:"true:正序,false:逆序"`
	EdbInfoType bool    `description:"true:标准指标,false:领先指标"`
	LeadValue   int     `description:"领先值"`
	LeadUnit    string  `description:"领先单位"`
	StartYear   int     `description:"最近N年"`
}

// CorrelationConfig 相关性配置
type CorrelationConfig struct {
	LeadValue      int    `description:"领先期数"`
	LeadUnit       string `description:"频度"`
	CalculateValue int    `description:"计算窗口"`
	CalculateUnit  string `description:"计算频度"`
}

// RollingCorrelationConfig 滚动相关性配置
type RollingCorrelationConfig struct {
	LeadValue      int    `description:"领先期数"`
	LeadUnit       string `description:"频度"`
	CalculateValue int    `description:"计算窗口"`
	CalculateUnit  string `description:"计算频度"`
}

// ReplaceEdbInfoInLineEquationMultipleGraphConfig 获取拟合方程配置
func ReplaceEdbInfoInLineEquationMultipleGraphConfig(oldEdbInfo, newEdbInfo *EdbInfo) (replaceConfigTotal int, err error) {
	var errmsg string
	logMsg := `` // 记录替换的日志

	o := orm.NewOrmUsingDB("data")
	to, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			_ = to.Rollback()
		} else {
			_ = to.Commit()
			if logMsg != `` {
				utils.FileLog.Info(fmt.Sprintf("替换拟合方程中的指标记录 替换总数%d,旧的指标id:%d，新的指标id:%d;%s", replaceConfigTotal, oldEdbInfo.EdbInfoId, newEdbInfo.EdbInfoId, logMsg))
			}
		}
		if errmsg != "" {
			fmt.Println("errmsg:" + errmsg)
		}
		if err != nil && errmsg != "" {
			go alarm_msg.SendAlarmMsg("替换拟合方程中的指标记录失败提醒,errmsg："+errmsg, 3)
		}
	}()
	//替换multiple_graph_config中的指标
	{
		multipleGraphConfigList := make([]*MultipleGraphConfig, 0)
		csql := `SELECT * FROM multiple_graph_config WHERE edb_info_id_a=0 AND edb_info_id_b=0 AND curve !=""`
		_, err = to.Raw(csql).QueryRows(&multipleGraphConfigList)
		if err != nil {
			errmsg = "获取指标关联图表配置信息失败：Err:" + err.Error()
			return
		}
		if len(multipleGraphConfigList) == 0 {
			return
		}
		updateList := make([]*MultipleGraphConfig, 0)
		configIds := make([]int, 0)
		configIdStr := make([]string, 0)
		for _, mv := range multipleGraphConfigList {
			if !strings.Contains(mv.Curve, strconv.Itoa(oldEdbInfo.EdbInfoId)) {
				continue
			}
			//解析curve内容
			var lineChartInfoConfig request.LineChartInfoReq
			if err = json.Unmarshal([]byte(mv.Curve), &lineChartInfoConfig); err != nil {
				errmsg = "获取跨品种分析配置信息失败：Err:" + err.Error()
				return
			}
			updateFlag := false
			// 遍历跨品种配置里的指标列表
			for k, edbInfoId := range lineChartInfoConfig.XEdbInfoIdList {
				if edbInfoId == oldEdbInfo.EdbInfoId {
					updateFlag = true
					lineChartInfoConfig.XEdbInfoIdList[k] = newEdbInfo.EdbInfoId
				}
			}
			for k, edbInfoId := range lineChartInfoConfig.YEdbInfoIdList {
				if edbInfoId == oldEdbInfo.EdbInfoId {
					updateFlag = true
					lineChartInfoConfig.YEdbInfoIdList[k] = newEdbInfo.EdbInfoId
				}
			}
			if !updateFlag {
				continue
			}
			newCurve, _ := json.Marshal(lineChartInfoConfig)
			mv.Curve = string(newCurve)
			//判断如果达到1000个数，则执行更新语句
			updateList = append(updateList, mv)
			configIds = append(configIds, mv.MultipleGraphConfigId)
			configIdStr = append(configIdStr, strconv.Itoa(mv.MultipleGraphConfigId))
			if len(configIds) >= 10 {
				numStr := utils.GetOrmInReplace(len(configIds))
				// 准备批量更新的 SQL 语句
				updateSQL := `UPDATE multiple_graph_config SET   
    curve = CASE multiple_graph_config_id  `
				for _, updateItem := range updateList {
					updateSQL += `WHEN ` + strconv.Itoa(updateItem.MultipleGraphConfigId) + ` THEN '` + updateItem.Curve + `' `
				}
				updateSQL += `END, modify_time = ? WHERE multiple_graph_config_id IN (` + numStr + `)`
				_, err = to.Raw(updateSQL, time.Now(), configIds).Exec()
				if err != nil {
					errmsg = "更新指标A关联图表配置信息失败：Err:" + err.Error()
					return
				}
				logMsg += `涉及到的配置id：` + strings.Join(configIdStr, ",") + ";"
				replaceConfigTotal += len(configIds)
				configIds = make([]int, 0)
				updateList = make([]*MultipleGraphConfig, 0)
				configIdStr = make([]string, 0)
			}
		}
		if len(configIds) > 0 {
			numStr := utils.GetOrmInReplace(len(configIds))
			// 准备批量更新的 SQL 语句
			updateSQL := `UPDATE multiple_graph_config SET   
    curve = CASE multiple_graph_config_id  `
			for _, updateItem := range updateList {
				updateSQL += `WHEN ` + strconv.Itoa(updateItem.MultipleGraphConfigId) + ` THEN '` + updateItem.Curve + `' `
			}
			updateSQL += `END, modify_time = ? WHERE multiple_graph_config_id IN (` + numStr + `)`
			_, err = to.Raw(updateSQL, time.Now(), configIds).Exec()
			if err != nil {
				errmsg = "更新指标A关联图表配置信息失败：Err:" + err.Error()
				return
			}
			logMsg += `涉及到的配置id：` + strings.Join(configIdStr, ",") + ";"
			replaceConfigTotal += len(configIds)
			configIds = make([]int, 0)
			updateList = make([]*MultipleGraphConfig, 0)
			configIdStr = make([]string, 0)
		}
	}
	return
}
