package services

import (
	"errors"
	"fmt"
	"hongze/hz_eta_api/models"
	"hongze/hz_eta_api/services/alarm_msg"
	"hongze/hz_eta_api/utils"
	"html"
	"regexp"
	"strconv"
	"strings"
	"time"
)

func AutoSyncOldReport() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("[AutoSyncOldReport]", err)
		}
	}()
	for {
		utils.Rc.Brpop(utils.CACHE_KEY_OLD_REPORT_PUBLISH, func(b []byte) {
			reportId, _ := strconv.Atoi(string(b))
			if reportId > 0 {
				if err := SyncOldReport(reportId); err != nil {
					fmt.Println("AutoSyncOldReport: ", err.Error(), "reportId: ", reportId)
				}
			}
		})
	}
}

// SyncOldReport 同步老后台报告
func SyncOldReport(reportId int) (err error) {
	defer func() {
		if err != nil {
			utils.FileLog.Error("SyncOldReport, reportId:%s, Err:%s", strconv.Itoa(reportId), err.Error())
			go alarm_msg.SendAlarmMsg("同步老后台报告失败, 报告ID: "+strconv.Itoa(reportId)+", Err: "+err.Error(), 3)
		}
	}()
	// 查询报告信息
	if reportId <= 0 {
		return
	}
	reportInfo, e := models.GetResearchReportById(reportId)
	if e != nil {
		err = errors.New("报告信息有误" + e.Error())
		return
	}
	if reportInfo.Status != "report" {
		return
	}
	// 20220615-周报不做同步了
	if reportInfo.Type == utils.REPORT_TYPE_WEEK {
		return
	}
	// 若已存在报告，则后续更新报告信息
	existReport, e := models.GetNewReportExist(reportId)
	if e != nil && e.Error() != utils.ErrNoRow() {
		err = errors.New("获取报告是否已同步失败" + e.Error())
		return
	}
	// 报告分类
	classifyList, e := models.GetAllClassify()
	if e != nil {
		err = errors.New("获取报告分类失败" + e.Error())
		return
	}
	classifyIdName := make(map[int]string, 0)
	classifyNameId := make(map[string]int, 0)
	classifyIdParentId := make(map[int]int, 0)
	classifyLen := len(classifyList)
	for i := 0; i < classifyLen; i++ {
		classifyIdName[classifyList[i].Id] = classifyList[i].ClassifyName
		classifyNameId[classifyList[i].ClassifyName] = classifyList[i].Id
		classifyIdParentId[classifyList[i].Id] = classifyList[i].ParentId
	}
	// 获取报告章节
	reportTypeList, e := models.GetResearchReportTypeListByReportId(reportId)
	if e != nil {
		err = errors.New("获取报告章节失败" + e.Error())
		return
	}
	reportTypeListLen := len(reportTypeList)
	if reportTypeListLen == 0 {
		return
	}
	// 获取章节内容
	typeIdArr := make([]string, 0)
	for i := 0; i < reportTypeListLen; i++ {
		typeIdArr = append(typeIdArr, strconv.Itoa(reportTypeList[i].ResearchReportTypeId))
	}
	typeIdStr := strings.Join(typeIdArr, ",")
	reportContentList, e := models.GetResearchReportTypeContentListByReportTypeIds(typeIdStr)
	if e != nil {
		err = errors.New("获取章节内容失败" + e.Error())
		return
	}
	reportContentListLen := len(reportContentList)
	if reportContentListLen == 0 {
		return
	}
	// 报告章节内容map
	reportContentListMap := make(map[int][]*models.ResearchReportTypeContent, 0)
	for i := 0; i < reportTypeListLen; i++ {
		rtid := reportTypeList[i].ResearchReportTypeId
		reportContentMap := make([]*models.ResearchReportTypeContent, 0)
		for ii := 0; ii < reportContentListLen; ii++ {
			if rtid == reportContentList[ii].ResearchReportTypeId {
				reportContentMap = append(reportContentMap, reportContentList[ii])
			}
		}
		reportContentListMap[rtid] = reportContentMap
	}

	frequencyMap := map[string]string{
		"day":      "日度",
		"week":     "周度",
		"two_week": "双周度",
		"month":    "月度",
		"other":    "不定时",
	}
	newReport := new(models.Report)
	newReport.AddType = 1
	// 标题去掉【】
	re, _ := regexp.Compile("^【[^】]*】")
	newTitle := re.ReplaceAllString(reportInfo.ResearchReportName, "")
	newReport.Title = newTitle
	newReport.Author = reportInfo.Author
	newReport.Frequency = frequencyMap[reportInfo.Type]
	newReport.CreateTime = reportInfo.CreatedTime
	modifyTime, _ := time.ParseInLocation(utils.FormatDateTime, reportInfo.CreatedTime, time.Local)
	newReport.ModifyTime = modifyTime
	newReport.State = 2
	newReport.PublishTime = reportInfo.ResearchReportDate
	newReport.Stage = reportInfo.Periods
	//newReport.MsgIsSend = 1
	//newReport.ThsMsgIsSend = 1
	newReport.ReportVersion = 1
	newReport.OldReportId = reportInfo.ResearchReportId
	// 判断报告类型
	newReportId := 0
	if reportInfo.Type == utils.REPORT_TYPE_DAY || reportInfo.Type == utils.REPORT_TYPE_WEEK {
		// 晨周报
		newReport.HasChapter = 1
		newReport.ChapterType = reportInfo.Type
		// 章节类型
		typeList, tmpErr := models.GetReportChapterTypeList()
		if tmpErr != nil {
			err = errors.New("获取晨周报章节类型失败" + tmpErr.Error())
			return
		}
		typeIdName := make(map[int]string, 0)
		typeIdSort := make(map[int]int, 0)
		for i := 0; i < len(typeList); i++ {
			typeIdName[typeList[i].ReportChapterTypeId] = typeList[i].ReportChapterTypeName
			typeIdSort[typeList[i].ReportChapterTypeId] = typeList[i].Sort
		}
		// 分类
		classifyIdFirst := 0
		classifyNameFirst := ""
		if reportInfo.Type == utils.REPORT_TYPE_DAY {
			newReport.ClassifyIdFirst = classifyNameId["晨报"]
			newReport.ClassifyNameFirst = "晨报"
			classifyIdFirst = classifyNameId["晨报"]
			classifyNameFirst = "晨报"
		} else {
			newReport.ClassifyIdFirst = classifyNameId["周报"]
			newReport.ClassifyNameFirst = "周报"
			classifyIdFirst = classifyNameId["周报"]
			classifyNameFirst = "周报"
		}

		// 报告已存在时的更新报告及章节，否则新增
		if existReport != nil {
			// 更新报告
			existReport.Title = newTitle
			existReport.Author = reportInfo.Author
			existReport.PublishTime = reportInfo.ResearchReportDate
			existReport.ModifyTime = time.Now()
			var updateReportCol, updateChapterCol []string
			updateReportCol = append(updateReportCol, "Title", "Author", "PublishTime", "ModifyTime")
			if tmpErr = existReport.UpdateReport(updateReportCol); tmpErr != nil {
				err = errors.New("更新已存在的报告失败" + tmpErr.Error())
				return
			}
			// 章节
			existChapterList, tmpErr := models.GetChapterListByReportId(existReport.Id)
			if tmpErr != nil {
				err = errors.New("获取已存在的报告章节失败" + tmpErr.Error())
				return
			}
			typeChapterMap := make(map[int]*models.ResearchReportType, 0)
			for i := 0; i < reportTypeListLen; i++ {
				typeChapterMap[reportTypeList[i].TypeId] = reportTypeList[i]
			}
			for _, exChapter := range existChapterList {
				chapter := typeChapterMap[exChapter.TypeId]
				if chapter == nil {
					continue
				}
				// 章节内容
				chapterContents := ""
				contentList := reportContentListMap[chapter.ResearchReportTypeId]
				for _, contents := range contentList {
					// 2022-08-09加上段落标题
					if contents.ContentType != "" {
						chapterContents += `<p><br></p><p style="font-size: 16px; text-align: left;"><strong>`
						chapterContents += contents.ContentType
						chapterContents += `</strong></p><p><br></p>`
					}
					chapterContents += contents.Content
				}
				chapterContents, tmpErr := replaceReportBase64ToImg(chapterContents)
				if tmpErr != nil {
					err = errors.New("章节存在base64图片转换失败" + tmpErr.Error())
					return
				}
				contentClean, e := FilterReportContentBr(chapterContents)
				if e != nil {
					err = errors.New("内容去除前后空格失败, Err: " + e.Error())
					return
				}
				chapterContents = contentClean

				contentSub, tmpErr := GetReportContentSub(chapterContents)
				if tmpErr != nil {
					err = errors.New("解析章节ContentSub失败" + tmpErr.Error())
					return
				}
				exChapter.Title = chapter.ResearchReportTypeTitle
				exChapter.Content = html.EscapeString(chapterContents)
				exChapter.ContentSub = html.EscapeString(contentSub)
				exChapter.ModifyTime = time.Now()
				updateChapterCol = append(updateChapterCol, "Title", "Content", "ContentSub", "ModifyTime")
				updateTickerList := make([]*models.ReportChapterTicker, 0)
				// 晨报数据指标
				if reportInfo.Type == utils.REPORT_TYPE_DAY {
					// 获取章节ticker
					reportTickerList, tmpErr := models.GetResearchReportTypeTickerListByReportTypeIds(typeIdStr)
					if tmpErr != nil {
						err = errors.New("获取报告Ticker失败" + tmpErr.Error())
						return
					}
					reportTickerListMap := make(map[int][]*models.ResearchReportTypeTicker, 0)
					for i := 0; i < len(reportTypeList); i++ {
						// 报告Ticker
						tid := reportTypeList[i].ResearchReportTypeId
						reportTickerMap := make([]*models.ResearchReportTypeTicker, 0)
						for iii := 0; iii < len(reportTickerList); iii++ {
							if tid == reportTickerList[iii].ResearchReportTypeId {
								reportTickerMap = append(reportTickerMap, reportTickerList[iii])
							}
						}
						reportTickerListMap[tid] = reportTickerMap
					}

					tickerList := reportTickerListMap[chapter.ResearchReportTypeId]
					for _, ticker := range tickerList {
						updateTickerList = append(updateTickerList, &models.ReportChapterTicker{
							Sort:       ticker.Sort,
							Ticker:     ticker.Ticker,
							CreateTime: ticker.CreatedTime,
							UpdateTime: ticker.LastUpdatedTime,
						})
					}
				}
				// 更新章节
				if tmpErr = models.UpdateChapterAndTicker(exChapter, updateChapterCol, updateTickerList); tmpErr != nil {
					err = errors.New("UpdateChapterAndTicker更新已存在的章节失败" + tmpErr.Error())
					return
				}
			}
		} else {
			newDayWeekReport := new(models.CreateDayWeekReport)
			newChapterList := make([]*models.CreateDayWeekReportChapter, 0)
			for _, chapter := range reportTypeList {
				chapterAndTicker := new(models.CreateDayWeekReportChapter)
				tmpTickerList := make([]*models.ReportChapterTicker, 0)
				chapterContents := ""
				// 章节内容列表
				contentList := reportContentListMap[chapter.ResearchReportTypeId]
				for _, contents := range contentList {
					// 2022-08-09加上段落标题
					if contents.ContentType != "" {
						chapterContents += `<p><br></p><p style="font-size: 16px; text-align: left;"><strong>`
						chapterContents += contents.ContentType
						chapterContents += `</strong></p><p><br></p>`
					}
					chapterContents += contents.Content
				}
				chapterContents, tmpErr := replaceReportBase64ToImg(chapterContents)
				if tmpErr != nil {
					err = errors.New("章节存在base64图片转换失败" + tmpErr.Error())
					return
				}
				state := 2
				if chapterContents == "" {
					state = 1
				}

				contentClean, e := FilterReportContentBr(chapterContents)
				if e != nil {
					err = errors.New("内容去除前后空格失败, Err: " + e.Error())
					return
				}
				chapterContents = contentClean

				contentSub, tmpErr := GetReportContentSub(chapterContents)
				if tmpErr != nil {
					err = errors.New("解析章节ContentSub失败" + tmpErr.Error())
					return
				}
				chapterContents = html.EscapeString(chapterContents)
				contentSub = html.EscapeString(contentSub)

				chapterAndTicker.Chapter = &models.ReportChapter{
					ReportType:        reportInfo.Type,
					ClassifyIdFirst:   classifyIdFirst,
					ClassifyNameFirst: classifyNameFirst,
					TypeId:            chapter.TypeId,
					TypeName:          typeIdName[chapter.TypeId],
					Sort:              typeIdSort[chapter.TypeId],
					Title:             chapter.ResearchReportTypeTitle,
					AddType:           1,
					Author:            reportInfo.Author,
					Content:           chapterContents,
					ContentSub:        contentSub,
					Stage:             reportInfo.Periods,
					Trend:             chapter.Trend,
					IsEdit:            1,
					PublishState:      state,
					PublishTime:       chapter.LastUpdatedTime,
					CreateTime:        chapter.CreatedTime,
					ModifyTime:        chapter.LastUpdatedTime,
				}
				// 晨报数据指标
				if reportInfo.Type == utils.REPORT_TYPE_DAY {
					// 获取章节ticker
					reportTickerList, tmpErr := models.GetResearchReportTypeTickerListByReportTypeIds(typeIdStr)
					if tmpErr != nil {
						err = errors.New("获取报告Ticker失败" + tmpErr.Error())
						return
					}
					reportTickerListMap := make(map[int][]*models.ResearchReportTypeTicker, 0)
					for i := 0; i < len(reportTypeList); i++ {
						// 报告Ticker
						tid := reportTypeList[i].ResearchReportTypeId
						reportTickerMap := make([]*models.ResearchReportTypeTicker, 0)
						for iii := 0; iii < len(reportTickerList); iii++ {
							if tid == reportTickerList[iii].ResearchReportTypeId {
								reportTickerMap = append(reportTickerMap, reportTickerList[iii])
							}
						}
						reportTickerListMap[tid] = reportTickerMap
					}

					tickerList := reportTickerListMap[chapter.ResearchReportTypeId]
					for _, ticker := range tickerList {
						tmpTickerList = append(tmpTickerList, &models.ReportChapterTicker{
							Sort:       ticker.Sort,
							Ticker:     ticker.Ticker,
							CreateTime: ticker.CreatedTime,
							UpdateTime: ticker.LastUpdatedTime,
						})
					}
				}
				chapterAndTicker.TickerList = tmpTickerList
				newChapterList = append(newChapterList, chapterAndTicker)
			}
			newDayWeekReport.Report = newReport
			newDayWeekReport.ChapterList = newChapterList
			// 新增晨周报
			newReportId, tmpErr = models.CreateMigrateNewDayWeekReport(newDayWeekReport)
			if tmpErr != nil {
				err = errors.New("新增晨周报失败" + tmpErr.Error())
				return
			}
		}
	} else {
		// 非晨周报
		if reportInfo.ReportVariety == "铁矿库存点评" {
			reportInfo.ReportVariety = "铁矿库存数据点评"
		}
		//newReport.Abstract = newTitle
		newReport.ClassifyIdSecond = classifyNameId[reportInfo.ReportVariety]
		newReport.ClassifyNameSecond = reportInfo.ReportVariety
		newReport.ClassifyIdFirst = classifyIdParentId[newReport.ClassifyIdSecond]
		newReport.ClassifyNameFirst = classifyIdName[newReport.ClassifyIdFirst]
		// 忽略分类匹配不上的
		if newReport.ClassifyIdFirst == 0 || newReport.ClassifyIdSecond == 0 || newReport.ClassifyNameFirst == "" || newReport.ClassifyNameSecond == "" {
			fmt.Printf("分类匹配不上，忽略报告, FirstClassify:%s, SecondClassify:%s", newReport.ClassifyNameFirst, newReport.ClassifyNameSecond)
			return
		}
		reportContents := ""
		for _, chapter := range reportTypeList {
			// 章节内容列表
			contentList := reportContentListMap[chapter.ResearchReportTypeId]
			for _, contents := range contentList {
				// 2022-08-09加上段落标题
				if contents.ContentType != "" {
					reportContents += `<p><br></p><p style="font-size: 16px; text-align: left;"><strong>`
					reportContents += contents.ContentType
					reportContents += `</strong></p><p><br></p>`
				}
				reportContents += contents.Content
			}
		}
		reportContents, tmpErr := replaceReportBase64ToImg(reportContents)
		if tmpErr != nil {
			err = errors.New("报告存在base64图片转换失败" + tmpErr.Error())
			return
		}
		newReport.State = 2
		if reportContents == "" {
			newReport.State = 1
		}

		contentClean, e := FilterReportContentBr(reportContents)
		if e != nil {
			err = errors.New("内容去除前后空格失败, Err: " + e.Error())
			return
		}
		reportContents = contentClean

		reportContentSub, tmpErr := GetReportContentSub(reportContents)
		if tmpErr != nil {
			err = errors.New("解析ContentSub失败" + tmpErr.Error())
			return
		}
		newReport.Content = html.EscapeString(reportContents)
		newReport.ContentSub = html.EscapeString(reportContentSub)
		// 报告已存在则更新部分字段
		if existReport != nil {
			existReport.Title = newTitle
			existReport.Abstract = newReport.Abstract
			existReport.Author = newReport.Author
			existReport.Content = newReport.Content
			existReport.ContentSub = newReport.ContentSub
			existReport.PublishTime = reportInfo.ResearchReportDate
			existReport.ModifyTime = time.Now()
			existReport.ClassifyIdFirst = newReport.ClassifyIdFirst
			existReport.ClassifyNameFirst = newReport.ClassifyNameFirst
			existReport.ClassifyIdSecond = newReport.ClassifyIdSecond
			existReport.ClassifyNameSecond = newReport.ClassifyNameSecond
			updateCol := make([]string, 0)
			updateCol = append(updateCol, "Title", "Abstract", "Author", "Content", "ContentSub", "PublishTime", "ModifyTime", "ClassifyIdFirst", "ClassifyNameFirst", "ClassifyIdSecond", "ClassifyNameSecond")
			tmpErr = existReport.UpdateReport(updateCol)
			if tmpErr != nil {
				err = errors.New("更新报告失败" + tmpErr.Error())
				return
			}
		} else {
			// 获取非晨周报权限mapping
			reportPermissionList, tmpErr := models.GetChapterPermissionMappingByResearchReportIds(strconv.Itoa(reportId))
			if tmpErr != nil {
				err = errors.New("获取报告权限mapping失败" + tmpErr.Error())
				return
			}
			// 新增非晨周报
			newReportId, tmpErr = models.CreateMigrateNewOtherReport(newReport, reportPermissionList)
			if tmpErr != nil {
				err = errors.New("新增非晨周报失败" + tmpErr.Error())
				return
			}
		}
	}
	if existReport != nil {
		newReportId = existReport.Id
	}
	if newReportId == 0 {
		err = errors.New("同步报告失败")
		return
	}
	if existReport == nil {
		// 更新音频
		if e = UpdateReportVideo(newReportId); e != nil {
			err = errors.New("更新音频失败" + e.Error())
			return
		}
	}
	// 更新ES
	if e = UpdateReportEs(newReportId, 2); e != nil {
		err = errors.New("更新报告ES失败" + e.Error())
		return
	}
	return
}

// UpdateSyncReport (一次性)更新已同步的报告
func UpdateSyncReport() (err error) {
	defer func() {
		if err != nil {
			fmt.Println(err.Error())
		}
	}()
	reportList, e := models.GetMigrateReportList()
	if e != nil {
		err = errors.New("获取今年报告失败, Err: " + e.Error())
		return
	}
	lenReport := len(reportList)
	for i := 0; i < lenReport; i++ {
		if e = SyncOldReport(reportList[i].ResearchReportId); e != nil {
			err = errors.New("同步报告失败, ResearchReportId: " + strconv.Itoa(reportList[i].ResearchReportId) + ", Err: " + e.Error())
			return
		}
	}
	return
}
