package my_chart

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"hongze/hongze_yb/controller/response"
	"hongze/hongze_yb/models/request"
	responseModel "hongze/hongze_yb/models/response"
	chartInfoModel "hongze/hongze_yb/models/tables/chart_info"
	"hongze/hongze_yb/models/tables/company_product"
	"hongze/hongze_yb/models/tables/yb_config"
	"hongze/hongze_yb/models/tables/yb_my_chart"
	"hongze/hongze_yb/models/tables/yb_my_chart_classify"
	"hongze/hongze_yb/services"
	userService "hongze/hongze_yb/services/user"
	"hongze/hongze_yb/utils"
	"strconv"
	"time"
)

// MyChartController 用户-我的图表
type MyChartController struct{}

// List 我的图表列表
func (this *MyChartController) List(c *gin.Context) {
	userInfo := userService.GetInfoByClaims(c)
	userId := int(userInfo.UserID)
	var req request.MyChartCollectListReq
	if c.Bind(&req) != nil {
		response.Fail("参数有误", c)
		return
	}
	cond := `user_id = ?`
	pars := make([]interface{}, 0)
	pars = append(pars, userId)
	if req.Keyword != "" {
		kw := fmt.Sprint("%", req.Keyword, "%")
		cond += ` AND chart_name LIKE ?`
		pars = append(pars, kw)
	}
	if req.ClassifyId > 0 {
		cond += ` AND my_chart_classify_id = ?`
		pars = append(pars, req.ClassifyId)
	}
	// classifyId = -1的时候查询默认分类
	if req.ClassifyId == -1 {
		cond += ` AND my_chart_classify_id = 0`
	}
	pageIndex := services.GetCurrPageByClaims(c)
	pageSize := services.GetPageSizeByClaims(c)

	ob := new(yb_my_chart.YbMyChart)
	chartTotal, e := ob.Count(cond, pars)
	if e != nil {
		response.FailMsg("获取失败", "获取用户图表列表总数失败, Err:"+e.Error(), c)
		return
	}
	total := int(chartTotal)
	list, e := ob.PageList(cond, pars, pageIndex, pageSize)
	if e != nil {
		response.FailMsg("获取失败", "获取用户图表列表失败, Err:"+e.Error(), c)
		return
	}
	respList := make([]*responseModel.MyChartItem, 0)
	for i := range list {
		respList = append(respList, &responseModel.MyChartItem{
			MyChartID:         list[i].MyChartID,
			MyChartClassifyID: list[i].MyChartClassifyID,
			ChartInfoID:       list[i].ChartInfoID,
			ChartName:         list[i].ChartName,
			UniqueCode:        list[i].UniqueCode,
			ChartImage:        list[i].ChartImage,
			UserID:            list[i].UserID,
			ReportID:          list[i].ReportID,
			ReportChapterID:   list[i].ReportChapterID,
			ChartInfoSource:   list[i].Source,
			CreateTime:        utils.TimeTransferString(utils.FormatDateTime, list[i].CreateTime),
		})
	}

	response.OkData("获取成功", &responseModel.MyChartListResp{
		List:   respList,
		Paging: responseModel.GetPaging(pageIndex, pageSize, total),
	}, c)
}

// Collect 收藏图表
func (this *MyChartController) Collect(c *gin.Context) {
	var req request.MyChartCollectReq
	if c.ShouldBind(&req) != nil {
		response.Fail("参数有误", c)
		return
	}
	if req.Authorization == "" {
		response.Fail("用户身份有误", c)
		return
	}
	if req.UniqueCode == "" {
		response.Fail("请选择图表", c)
		return
	}
	if req.ReportId <= 0 {
		response.Fail("请选择报告", c)
		return
	}

	// 获取用户信息
	userInfo, e := userService.GetUserInfoByToken(req.Authorization)
	if e != nil {
		response.FailMsg("操作失败", "Token获取有效用户失败, Err: "+e.Error(), c)
		return
	}
	if userInfo.UserID <= 0 {
		response.FailMsg("操作失败", "Token获取有效用户失败", c)
		return
	}
	userId := int(userInfo.UserID)

	// 获取图表信息
	chartInfo, e := chartInfoModel.GetChartInfoViewByUniqueCode(req.UniqueCode)
	if e != nil {
		response.FailMsg("操作失败", "UniqueCode获取图表信息失败, Err:"+e.Error(), c)
		return
	}
	if chartInfo.ChartInfoId <= 0 {
		response.FailMsg("操作失败", "图表信息有误", c)
		return
	}

	// 图表收藏上限
	ob := new(yb_my_chart.YbMyChart)
	countCond := `user_id = ?`
	countPars := make([]interface{}, 0)
	countPars = append(countPars, userId)
	count, e := ob.Count(countCond, countPars)
	if e != nil {
		response.FailMsg("操作失败", "获取用户图表收藏数量失败, Err: "+e.Error(), c)
		return
	}
	// 获取图表收藏上限配置
	configCond := `config_code = ?`
	configPars := make([]interface{}, 0)
	configPars = append(configPars, yb_config.UserChartCollectMax)
	confOB := new(yb_config.YbConfig)
	conf, e := confOB.Fetch(configCond, configPars)
	if e != nil {
		response.FailMsg("操作失败", "获取图表收藏上限配置失败, Err: "+e.Error(), c)
		return
	}
	max, e := strconv.Atoi(conf.ConfigValue)
	if e != nil {
		response.FailMsg("操作失败", "图表收藏上限配置有误, Err: "+e.Error(), c)
		return
	}
	if int(count) >= max {
		response.Fail(fmt.Sprintf("图表最多可收藏%d张", max), c)
		return
	}

	// 是否已收藏
	cond := `user_id = ? AND chart_info_id = ?`
	pars := make([]interface{}, 0)
	pars = append(pars, userId, chartInfo.ChartInfoId)
	exists, e := ob.FetchByCondition(cond, pars)
	if e != nil && e != utils.ErrNoRow {
		response.FailMsg("操作失败", "获取用户图表失败, Err: "+e.Error(), c)
		return
	}
	nowTime := time.Now().Local()
	collectId := 0
	if exists != nil && exists.MyChartID > 0 {
		// 更新收藏信息
		exists.ChartName = chartInfo.ChartName
		exists.ChartImage = chartInfo.ChartImage
		exists.ReportID = req.ReportId
		exists.ReportChapterID = req.ReportChapterId
		exists.ModifyTime = nowTime
		exists.Source = chartInfo.Source
		updateCols := []string{"ChartName", "ChartImage", "ReportID", "ReportChapterID", "ModifyTime"}
		if e = exists.Update(updateCols); e != nil {
			response.FailMsg("操作失败", "更新收藏失败, Err: "+e.Error(), c)
			return
		}
		collectId = exists.MyChartID
	} else {
		// 查询客户信息
		companyName := "潜在客户"
		companyStatus := "潜在"
		sellerId := 0
		if userInfo.CompanyID > 0 {
			//查询ficc产品信息和ficc销售信息
			companyInfo, e := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)
			if e != nil && e != utils.ErrNoRow {
				response.FailMsg("获取客户信息失败", "获取客户信息失败, Err: "+e.Error(), c)
				return
			}
			if companyInfo != nil && companyInfo.CompanyID > 0 {
				companyStatus = companyInfo.Status
				companyName = companyInfo.CompanyName
				sellerId = companyInfo.SellerID
			}
		}

		// 新增收藏
		ob.ChartInfoID = chartInfo.ChartInfoId
		ob.ChartName = chartInfo.ChartName
		ob.UniqueCode = chartInfo.UniqueCode
		ob.ChartImage = chartInfo.ChartImage
		ob.UserID = userId
		ob.CompanyID = int(userInfo.CompanyID)
		ob.CompanyStatus = companyStatus
		ob.CompanyName = companyName
		ob.RealName = userInfo.RealName
		ob.SellerID = sellerId
		ob.ReportID = req.ReportId
		ob.ReportChapterID = req.ReportChapterId
		ob.CreateTime = nowTime
		ob.ModifyTime = nowTime
		ob.Source = chartInfo.Source
		if e = ob.Create(); e != nil {
			response.FailMsg("操作失败", "新增收藏失败, Err: "+e.Error(), c)
			return
		}
		collectId = ob.MyChartID
	}
	response.OkData("操作成功", collectId, c)
}

// CollectCancel 取消收藏
func (this *MyChartController) CollectCancel(c *gin.Context) {
	var req request.MyChartCollectCancelReq
	if c.ShouldBind(&req) != nil {
		response.Fail("参数有误", c)
		return
	}
	if req.Authorization == "" {
		response.Fail("用户身份有误", c)
		return
	}
	if req.UniqueCode == "" {
		response.Fail("请选择图表", c)
		return
	}

	// 获取用户信息
	userInfo, e := userService.GetUserInfoByToken(req.Authorization)
	if e != nil {
		response.FailMsg("操作失败", "Token获取有效用户失败, Err: "+e.Error(), c)
		return
	}
	if userInfo.UserID <= 0 {
		response.FailMsg("操作失败", "Token获取有效用户失败", c)
		return
	}
	userId := int(userInfo.UserID)

	// 获取图表信息
	//chartInfo, e := chartInfoModel.GetChartInfoViewByUniqueCode(req.UniqueCode)
	//if e != nil {
	//	response.FailMsg("操作失败", "UniqueCode获取图表信息失败, Err:"+e.Error(), c)
	//	return
	//}
	//if chartInfo.ChartInfoId <= 0 {
	//	response.FailMsg("操作失败", "图表信息有误", c)
	//	return
	//}

	cond := `user_id = ? AND unique_code = ?`
	pars := make([]interface{}, 0)
	pars = append(pars, userId, req.UniqueCode)
	ob := new(yb_my_chart.YbMyChart)
	// 此处可能出现同一个报告两个同样的图表均有"取消收藏"按钮，点击第一个取消之后再点击第二个会报错，此时进行一个友好的提示"已取消收藏"
	item, e := ob.FetchByCondition(cond, pars)
	if e != nil {
		response.FailMsg("已取消收藏", "获取用户图表失败, Err: "+e.Error(), c)
		return
	}
	if e = item.Delete(); e != nil {
		response.FailMsg("已取消收藏", "取消用户图表收藏失败, Err: "+e.Error(), c)
		return
	}
	response.Ok("操作成功", c)
}

// RelateClassify 加入分类
func (this *MyChartController) RelateClassify(c *gin.Context) {
	userInfo := userService.GetInfoByClaims(c)
	userId := int(userInfo.UserID)
	if userId <= 0 {
		response.Fail("请登录后操作", c)
		return
	}
	var req request.MyChartRelateClassifyReq
	if c.ShouldBind(&req) != nil {
		response.Fail("参数有误", c)
		return
	}
	if req.MyChartId <= 0 {
		response.Fail("请选择图表", c)
		return
	}
	if req.ClassifyId <= 0 {
		response.Fail("请选择分类", c)
		return
	}

	ob := new(yb_my_chart.YbMyChart)
	item, e := ob.Fetch(req.MyChartId)
	if e != nil {
		response.FailMsg("图表信息有误", "获取用户图表失败, Err: "+e.Error(), c)
		return
	}
	if item.UserID != userId {
		response.Fail("无权操作", c)
		return
	}
	item.MyChartClassifyID = req.ClassifyId
	item.ModifyTime = time.Now().Local()
	if e = item.Update([]string{"MyChartClassifyID", "ModifyTime"}); e != nil {
		response.FailMsg("操作失败", "更新用户图表关联分类失败, Err: "+e.Error(), c)
		return
	}
	response.Ok("操作成功", c)
}

// IsCollect 是否已收藏
func (this *MyChartController) IsCollect(c *gin.Context) {
	var req request.MyChartIsCollectReq
	if c.Bind(&req) != nil {
		response.Fail("参数有误", c)
		return
	}
	if req.Authorization == "" {
		response.Fail("用户身份有误", c)
		return
	}
	if req.UniqueCode == "" {
		response.Fail("请选择图表", c)
		return
	}

	// 获取用户信息
	userInfo, e := userService.GetUserInfoByToken(req.Authorization)
	if e != nil {
		response.FailMsg("获取失败", "Token获取有效用户失败, Err: "+e.Error(), c)
		return
	}
	if userInfo.UserID <= 0 {
		response.FailMsg("获取失败", "Token获取有效用户失败", c)
		return
	}
	userId := int(userInfo.UserID)

	// 获取图表信息
	//chartInfo, e := chartInfoModel.GetChartInfoViewByUniqueCode(req.UniqueCode)
	//if e != nil {
	//	response.FailMsg("操作失败", "UniqueCode获取图表信息失败, Err:"+e.Error(), c)
	//	return
	//}
	//if chartInfo.ChartInfoId <= 0 {
	//	response.FailMsg("操作失败", "图表信息有误", c)
	//	return
	//}

	// 是否已收藏
	ob := new(yb_my_chart.YbMyChart)
	cond := `user_id = ? AND unique_code = ?`
	pars := make([]interface{}, 0)
	pars = append(pars, userId, req.UniqueCode)
	exists, e := ob.FetchByCondition(cond, pars)
	if e != nil && e != utils.ErrNoRow {
		response.FailMsg("获取失败", "获取用户图表失败, Err: "+e.Error(), c)
		return
	}
	isCollect := false
	if exists != nil && exists.MyChartID > 0 {
		isCollect = true
	}
	response.OkData("获取成功", isCollect, c)
}

// Locate 图表在列表中的定位
func (this *MyChartController) Locate(c *gin.Context) {
	userInfo := userService.GetInfoByClaims(c)
	userId := int(userInfo.UserID)
	var req request.MyChartCollectLocateReq
	if c.Bind(&req) != nil {
		response.Fail("参数有误", c)
		return
	}
	cond := `user_id = ?`
	pars := make([]interface{}, 0)
	pars = append(pars, userId)
	ob := new(yb_my_chart.YbMyChart)
	list, e := ob.List(cond, pars)
	if e != nil {
		response.FailMsg("获取失败", "获取用户图表列表失败, Err:"+e.Error(), c)
		return
	}
	charts := make([]*responseModel.MyChartLocateItem, 0)
	if len(list) == 0 {
		response.OkData("获取成功", charts, c)
		return
	}

	// 如果是分类下的图表, 则优先分类排序, 其次分类图表排序
	if req.ClassifyId > 0 || req.ClassifyId == -1 {
		classifyCond := `user_id = ?`
		classifyPars := make([]interface{}, 0)
		classifyPars = append(classifyPars, userId)
		classifyOB := new(yb_my_chart_classify.YbMyChartClassify)
		classies, e := classifyOB.List(classifyCond, classifyPars)
		if e != nil {
			response.FailMsg("获取失败", "获取用户图表分类失败, Err: "+e.Error(), c)
			return
		}
		// 未分类的图表排在前面
		for _, ch := range list {
			if ch.MyChartClassifyID > 0 {
				continue
			}
			v := new(responseModel.MyChartLocateItem)
			v.MyChartID = ch.MyChartID
			v.MyChartClassifyID = -1 // 未分类ID
			v.ChartInfoID = ch.ChartInfoID
			v.ChartName = ch.ChartName
			v.UniqueCode = ch.UniqueCode
			v.ChartInfoSource = ch.Source
			charts = append(charts, v)
		}

		// 已归类的图表
		for _, cl := range classies {
			for _, ch := range list {
				if ch.MyChartClassifyID != cl.MyChartClassifyID {
					continue
				}
				v := new(responseModel.MyChartLocateItem)
				v.MyChartID = ch.MyChartID
				v.MyChartClassifyID = ch.MyChartClassifyID
				v.ChartInfoID = ch.ChartInfoID
				v.ChartName = ch.ChartName
				v.UniqueCode = ch.UniqueCode
				v.ChartInfoSource = ch.Source
				charts = append(charts, v)
			}
		}
		total := len(charts)
		if total > 0 {
			last := total - 1
			for k, v := range charts {
				// 首图-首图无上一张
				if k == 0 {
					if (k + 1) <= last {
						v.NextChartInfoID = charts[k+1].ChartInfoID
					}
					continue
				}
				// 尾图-尾图无下一张
				if k == last {
					if (k - 1) >= 0 {
						v.PrevChartInfoID = charts[k-1].ChartInfoID
					}
					continue
				}
				// 中间
				if (k - 1) >= 0 {
					v.PrevChartInfoID = charts[k-1].ChartInfoID
				}
				if (k + 1) <= last {
					v.NextChartInfoID = charts[k+1].ChartInfoID
				}
			}
		}
		response.OkData("获取成功", charts, c)
		return
	}

	// 非分类列表
	if req.ClassifyId == 0 {
		for _, ch := range list {
			v := new(responseModel.MyChartLocateItem)
			v.MyChartID = ch.MyChartID
			v.MyChartClassifyID = ch.MyChartClassifyID
			v.ChartInfoID = ch.ChartInfoID
			v.ChartName = ch.ChartName
			v.UniqueCode = ch.UniqueCode
			v.ChartInfoSource = ch.Source
			charts = append(charts, v)
		}
		total := len(charts)
		if total > 0 {
			last := total - 1
			for k, v := range charts {
				// 首图-首图的上一张为尾图
				if k == 0 {
					if last > 0 {
						v.PrevChartInfoID = charts[last].ChartInfoID
					}
					if (k + 1) <= last {
						v.NextChartInfoID = charts[k+1].ChartInfoID
					}
					continue
				}
				// 尾图-尾图的下一张为首图
				if k == last {
					if (k - 1) >= 0 {
						v.PrevChartInfoID = charts[k-1].ChartInfoID
					}
					v.NextChartInfoID = charts[0].ChartInfoID
					continue
				}
				// 中间
				if (k - 1) >= 0 {
					v.PrevChartInfoID = charts[k-1].ChartInfoID
				}
				if (k + 1) <= last {
					v.NextChartInfoID = charts[k+1].ChartInfoID
				}
			}
		}
	}
	response.OkData("获取成功", charts, c)
}
