package yb

import (
	"errors"
	"fmt"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/company"
	"hongze/hz_crm_api/models/yb"
	"hongze/hz_crm_api/models/yb/request"
	"hongze/hz_crm_api/models/yb/response"
	"hongze/hz_crm_api/services"
	"hongze/hz_crm_api/utils"
	"strconv"
	"strings"
	"time"
)

// GetPriceDrivenDetail 获取价格驱动详情
func GetPriceDrivenDetail(varietyTagId int) (detail *response.PriceDrivenDetail, errMsg string, err error) {
	detail = new(response.PriceDrivenDetail)
	if varietyTagId <= 0 {
		return
	}
	item, e := yb.GetPriceDrivenByVarietyTagId(varietyTagId)
	if e != nil && e.Error() != utils.ErrNoRow() {
		errMsg = "获取价格驱动失败"
		err = errors.New("获取价格驱动详情失败, Err:" + e.Error())
		return
	}
	if item != nil {
		// 查询草稿
		draft, e := yb.GetPriceDrivenSaveLogByPriceDrivenId(item.PriceDrivenId)
		if e != nil && e.Error() != utils.ErrNoRow() {
			errMsg = "获取价格驱动草稿失败"
			err = errors.New("获取价格驱动草稿失败, Err:" + e.Error())
			return
		}
		if draft != nil && draft.CreateTime.After(item.ModifyTime) {
			item.MainVariable = draft.MainVariable
			item.CoreDrivenType = draft.CoreDrivenType
			item.CoreDrivenContent = draft.CoreDrivenContent
			item.CoreContent = draft.CoreContent
			item.LastUpdateAdminId = draft.AdminId
			item.LastUpdateAdminName = draft.AdminName
		}
		detail = formatPriceDrivenItemToDetail(item)
	}
	return
}

// UpdatePriceDriven 更新价格驱动
func UpdatePriceDriven(req request.UpdatePriceDrivenReq) (detail *response.PriceDrivenDetail, errMsg string, err error) {
	detail = new(response.PriceDrivenDetail)
	if req.VarietyTagId <= 0 {
		errMsg = "标签有误"
		err = errors.New("UpdatePriceDriven 标签有误")
		return
	}
	// 非自动保存校验品种是否开启
	priceTag, e := yb.GetPriceDrivenTagByTagId(req.VarietyTagId)
	if e != nil {
		errMsg = "获取价格驱动标签信息失败"
		err = errors.New("UpdatePriceDriven 获取价格驱动标签信息失败, Err:" + e.Error())
		return
	}
	if req.AutoSave == 0 {
		if priceTag.State != 1 {
			errMsg = "请开启品种后重试"
			err = errors.New("UpdatePriceDriven 品种未开启")
			return
		}
	}
	// 最近的一条数据
	item, e := yb.GetPriceDrivenByVarietyTagId(req.VarietyTagId)
	if e != nil && e.Error() != utils.ErrNoRow() {
		errMsg = "获取价格驱动失败"
		err = errors.New("UpdatePriceDriven 获取价格驱动详情失败, Err:" + e.Error())
		return
	}
	nowTime := time.Now().Local()
	// 最新的一条数据为今日的则更新
	if item != nil {
		todayStart := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local)
		todayEnd := time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 23, 59, 59, 0, time.Local)
		if item.CreateTime.After(todayStart) && item.CreateTime.Before(todayEnd) {
			item.MainVariable = req.MainVariable
			item.CoreDrivenType = req.CoreDrivenType
			item.CoreDrivenContent = req.CoreDrivenContent
			item.CoreContent = req.CoreContent
			item.LastUpdateAdminId = req.LastUpdateAdminId
			item.LastUpdateAdminName = req.LastUpdateAdminName
			if req.AutoSave == 0 {
				// 发布更新
				updateCols := make([]string, 0)
				updateCols = append(updateCols, "MainVariable", "CoreDrivenType", "CoreDrivenContent", "CoreContent",
					"LastUpdateAdminId", "LastUpdateAdminName", "ModifyTime", "PublishState")
				item.ModifyTime = nowTime
				item.PublishState = 1
				if e := item.Update(updateCols); e != nil {
					errMsg = "更新价格驱动失败"
					err = errors.New("UpdatePriceDriven 更新价格驱动失败, Err:" + e.Error())
					return
				}
			} else {
				// 存草稿
				go func() {
					if e = savePriceDrivenDraft(item.PriceDrivenId, req.VarietyTagId, req.CoreDrivenType, req.LastUpdateAdminId, req.MainVariable, req.CoreDrivenContent, req.CoreContent, req.LastUpdateAdminName); e != nil {
						utils.FileLog.Info("%s", "记录价格驱动草稿失败, Err: "+e.Error())
					}
				}()
			}
			detail = formatPriceDrivenItemToDetail(item)
			return
		}
	}
	// 否则新增, 不记录草稿
	publishState := 0
	if req.AutoSave == 0 {
		publishState = 1
	}
	newPriceDriven := &yb.PriceDriven{
		VarietyTagId:        req.VarietyTagId,
		VarietyTagName:      priceTag.VarietyTagName,
		MainVariable:        req.MainVariable,
		CoreDrivenType:      req.CoreDrivenType,
		CoreDrivenContent:   req.CoreDrivenContent,
		CoreContent:         req.CoreContent,
		LastUpdateAdminId:   req.LastUpdateAdminId,
		LastUpdateAdminName: req.LastUpdateAdminName,
		PublishState:        publishState,
		CreateTime:          nowTime,
		ModifyTime:          nowTime,
	}
	if e := newPriceDriven.Add(); e != nil {
		errMsg = "新增价格驱动失败"
		err = errors.New("UpdatePriceDriven 新增价格驱动失败, Err:" + e.Error())
	}
	detail = formatPriceDrivenItemToDetail(newPriceDriven)
	return
}

// savePriceDrivenDraft 保存草稿
func savePriceDrivenDraft(priceDrivenId, varietyTagId, coreDrivenType, adminId int, mainVariable, coreDrivenContent, coreContent, adminName string) (err error) {
	draft := &yb.PriceDrivenSaveLog{
		PriceDrivenId:     priceDrivenId,
		VarietyTagId:      varietyTagId,
		MainVariable:      mainVariable,
		CoreDrivenType:    coreDrivenType,
		CoreDrivenContent: coreDrivenContent,
		CoreContent:       coreContent,
		AdminId:           adminId,
		AdminName:         adminName,
		CreateTime:        time.Now().Local(),
	}
	if e := draft.Add(); e != nil {
		err = errors.New("savePriceDrivenDraft 新增价格驱动草稿失败, Err:" + e.Error())
	}
	return
}

// formatPriceDrivenItemToDetail 格式化详情
func formatPriceDrivenItemToDetail(item *yb.PriceDriven) (detail *response.PriceDrivenDetail) {
	if item == nil {
		return
	}
	detail = &response.PriceDrivenDetail{
		PriceDrivenId:       item.PriceDrivenId,
		VarietyTagId:        item.VarietyTagId,
		VarietyTagName:      item.VarietyTagName,
		MainVariable:        item.MainVariable,
		CoreDrivenType:      item.CoreDrivenType,
		CoreDrivenContent:   item.CoreDrivenContent,
		CoreContent:         item.CoreContent,
		LastUpdateAdminId:   item.LastUpdateAdminId,
		LastUpdateAdminName: item.LastUpdateAdminName,
		SendThsMsgTime:      item.SendThsMsgTime.Format(utils.FormatDateTime),
		SendTemplateMsgTime: item.SendTemplateMsgTime.Format(utils.FormatDateTime),
		ThsMsgState:         item.ThsMsgState,
		TemplateMsgState:    item.TemplateMsgState,
		PublishState:        item.PublishState,
		CreateTime:          item.CreateTime.Format(utils.FormatDateTime),
		ModifyTime:          item.ModifyTime.Format(utils.FormatDateTime),
	}
	return
}

// GetPriceDrivenPermissionTree 获取价格驱动品种列表
func GetPriceDrivenPermissionTree() (list []*response.ChartPermissionTree, err error) {
	firstList, e := models.GetYbChartPermissionFirst()
	if e != nil {
		return
	}
	list = make([]*response.ChartPermissionTree, 0)
	if len(firstList) > 0 {
		productId := 1
		for _, v := range firstList {
			classify := new(response.ChartPermissionTree)
			classify.ClassifyName = v.YbIndexName
			children, e := models.GetPermissionByProductIdAndClassifyName(productId, v.ClassifyName)
			if e != nil {
				return
			}
			items := make([]*response.PermissionItem, 0)
			for _, iv := range children {
				items = append(items, &response.PermissionItem{
					PermissionId:     iv.ChartPermissionId,
					PermissionName:   iv.PermissionName,
					PriceDrivenState: iv.PriceDrivenState,
				})
			}
			classify.Items = items
			list = append(list, classify)
		}
	}
	return
}

// SwitchPriceDrivenPermissionState 切换价格驱动分类状态
func SwitchPriceDrivenPermissionState(varietyTagId int, priceDrivenState int) (errMsg string, err error) {
	priceTag, e := yb.GetPriceDrivenTagByTagId(varietyTagId)
	if e != nil {
		errMsg = "获取价格驱动标签信息失败"
		err = errors.New("UpdatePriceDriven 获取价格驱动标签信息失败, Err:" + e.Error())
		return
	}
	if priceTag.State == priceDrivenState {
		return
	}
	updateCols := make([]string, 0)
	updateCols = append(updateCols, "State")
	priceTag.State = priceDrivenState
	if e := priceTag.Update(updateCols); e != nil {
		err = errors.New("SwitchPriceDrivenPermissionState 更新价格驱动分类状态失败, Err:" + e.Error())
	}
	return
}

// SendPriceDrivenTemplateMsg 推送价格驱动模板消息
func SendPriceDrivenTemplateMsg(priceDrivenId int) (errMsg string, err error) {
	item, e := yb.GetPriceDrivenById(priceDrivenId)
	if e != nil {
		errMsg = "获取价格驱动失败"
		err = errors.New("SendPriceDrivenTemplateMsg 获取价格驱动详情失败, Err:" + e.Error())
		return
	}
	if item.CoreContent == "" {
		errMsg = "核心内容不能为空"
		err = errors.New("SendPriceDrivenTemplateMsg 核心内容不能为空")
		return
	}
	if item.TemplateMsgState == 1 {
		errMsg = "未更新品种或今日推送次数已达上限"
		err = errors.New("SendPriceDrivenTemplateMsg 今日推送次数已达上限")
		return
	}
	// 推送消息
	go func() {
		_ = services.SendYbPriceDrivenWxMsg(item.VarietyTagId, item.CoreDrivenContent, time.Now().Format(utils.FormatDateTime))
	}()
	// 更新推送信息
	updateCols := make([]string, 0)
	updateCols = append(updateCols, "SendTemplateMsgTime", "TemplateMsgState")
	item.SendTemplateMsgTime = time.Now().Local()
	item.TemplateMsgState = 1
	if e := item.Update(updateCols); e != nil {
		errMsg = "更新模板消息信息失败"
		err = errors.New("SendPriceDrivenTemplateMsg 更新模板消息信息失败, Err:" + e.Error())
	}
	return
}

// SendPriceDrivenThsMsg 推送价格驱动同花顺客群消息
func SendPriceDrivenThsMsg(priceDrivenId int) (errMsg string, err error) {
	item, e := yb.GetPriceDrivenById(priceDrivenId)
	if e != nil {
		errMsg = "获取价格驱动失败"
		err = errors.New("SendPriceDrivenThsMsg 获取价格驱动详情失败, Err:" + e.Error())
		return
	}
	if item.CoreContent == "" {
		errMsg = "核心内容不能为空"
		err = errors.New("SendPriceDrivenThsMsg 核心内容不能为空")
		return
	}
	if item.ThsMsgState == 1 {
		errMsg = "未更新品种或今日推送次数已达上限"
		err = errors.New("SendPriceDrivenThsMsg 今日推送次数已达上限")
		return
	}
	// 推送客群消息
	//go func() {
	//	_ = services.SendYbPriceDrivenToThs(priceDrivenId, item.VarietyTagId)
	//}()
	// 更新推送信息
	updateCols := make([]string, 0)
	updateCols = append(updateCols, "SendThsMsgTime", "ThsMsgState")
	item.SendThsMsgTime = time.Now().Local()
	item.ThsMsgState = 1
	if e := item.Update(updateCols); e != nil {
		errMsg = "更新客群消息信息失败"
		err = errors.New("SendPriceDrivenThsMsg 更新客群消息信息失败, Err:" + e.Error())
	}
	return
}

// GetPriceDrivenClickCensusList 获取价格驱动统计列表
func GetPriceDrivenClickCensusList(startSize, pageSize, sortField, sortRule int) (total int, list []*response.PriceDrivenClickCensusItem, err error) {
	list = make([]*response.PriceDrivenClickCensusItem, 0)
	// 获取每个品种的最新的价格驱动信息
	priceDrivenList, e := yb.GetRecentPriceDrivenList()
	if e != nil {
		err = errors.New("获取最新的价格驱动信息失败, Err: " + e.Error())
		return
	}
	priceDrivenMap := make(map[int]*yb.PriceDriven, 0)
	for _, p := range priceDrivenList {
		priceDrivenMap[p.VarietyTagId] = p
	}
	total = len(priceDrivenList)
	// 获取标签累计点击量
	priceDrivenIds := ""
	totalClickList, e := yb.GetPriceDrivenClick(priceDrivenIds)
	if e != nil {
		err = errors.New("获取价格驱动标签累计点击量失败, Err: " + e.Error())
		return
	}
	totalClickMap := make(map[int]int)
	recentClickTimeMap := make(map[int]string)
	for _, t := range totalClickList {
		totalClickMap[t.VarietyTagId] = t.CountNum
		recentClickTimeMap[t.VarietyTagId] = t.RecentClickTime
	}
	// 获取标签最近点击量
	priceDrivenIdArr := make([]string, 0)
	priceDrivenLen := len(priceDrivenList)
	for i := 0; i < priceDrivenLen; i++ {
		priceDrivenIdArr = append(priceDrivenIdArr, strconv.Itoa(priceDrivenList[i].PriceDrivenId))
	}
	priceDrivenIds = strings.Join(priceDrivenIdArr, ",")
	recentClickList, e := yb.GetPriceDrivenClick(priceDrivenIds)
	if e != nil {
		err = errors.New("获取价格驱动标签最近点击量失败, Err: " + e.Error())
		return
	}
	recentClickMap := make(map[int]int)
	for _, r := range recentClickList {
		recentClickMap[r.VarietyTagId] = r.CountNum
	}
	// 根据排序规则确定分页列表
	pageList := make([]*yb.PriceDrivenVarietyTagClick, 0)
	if sortField == 0 {
		// 默认排序-价格驱动更新时间降序
		pageList, e = yb.GetDefaultPriceDrivenPageClick(startSize, pageSize, priceDrivenIds)
		if e != nil {
			err = errors.New("获取价格驱动统计默认分页列表失败, Err: " + e.Error())
			return
		}
	} else {
		// sortField排序字段:1-按照累计点击量排序 2-按照最近点击量排序
		groupRule := "pd.price_driven_id"
		joinRule := "pd.variety_tag_id = vl.variety_tag_id"
		if sortField == 2 {
			joinRule = "pd.price_driven_id = vl.price_driven_id"
			groupRule = "pd.variety_tag_id "
		}
		// sortRule排序规则:1-升序 2-降序
		orderRule := "count_num DESC"
		if sortRule == 1 {
			orderRule = "count_num ASC"
		}
		pageList, e = yb.GetPriceDrivenPageClick(startSize, pageSize, priceDrivenIds, joinRule, groupRule, orderRule)
		if e != nil {
			err = errors.New("获取价格驱动统计分页列表失败, Err: " + e.Error())
			return
		}
	}
	// 获取标签列表
	tagList, e := models.GetVarietyTagList()
	if e != nil {
		err = errors.New("获取标签列表失败, Err: " + e.Error())
		return
	}
	tagMap := make(map[int]*models.VarietyTag, 0)
	for _, t := range tagList {
		tagMap[t.VarietyTagId] = t
	}
	// 遍历组合信息
	for _, v := range pageList {
		fmt.Println(v.VarietyTagId)
		item := new(response.PriceDrivenClickCensusItem)
		pd := priceDrivenMap[v.VarietyTagId]
		if pd == nil {
			continue
		}
		tag := tagMap[v.VarietyTagId]
		if tag != nil {
			item.ClassifyId = tag.VarietyClassifyId
			item.ClassifyName = tag.VarietyClassifyName
		}
		item.PriceDrivenId = pd.PriceDrivenId
		item.VarietyTagId = pd.VarietyTagId
		item.VarietyTagName = pd.VarietyTagName
		item.MainVariable = pd.MainVariable
		item.CoreDrivenType = pd.CoreDrivenType
		item.CoreDrivenContent = pd.CoreDrivenContent
		item.LastModifyTime = pd.ModifyTime.Format(utils.FormatDateTime)
		item.TotalClickNum = totalClickMap[v.VarietyTagId]
		item.RecentClickNum = recentClickMap[v.VarietyTagId]
		item.RecentClickTime = recentClickTimeMap[v.VarietyTagId]
		list = append(list, item)
	}
	return
}

// GetPriceDrivenClickCensusList 获取价格驱动统计详情
func GetPriceDrivenClickCensusDetail(startSize, pageSize, varietyTagId, priceDrivenId int) (total, pageTotal int, list []*response.PriceDrivenClickCensusDetailItem, err error) {
	list = make([]*response.PriceDrivenClickCensusDetailItem, 0)
	total, detailList, e := yb.GetPriceDrivenPageClickDetail(startSize, pageSize, varietyTagId, priceDrivenId)
	if e != nil {
		err = errors.New("获取价格驱动统计详情列表失败, Err: " + e.Error())
		return
	}
	// 查询用户相关的客户信息
	detailLen := len(detailList)
	userIdArr := make([]string, 0)
	for i := 0; i < detailLen; i++ {
		userIdArr = append(userIdArr, strconv.Itoa(detailList[i].UserId))
	}
	userIds := strings.Join(userIdArr, ",")
	userCompanyMap := make(map[int]*company.CompanyUser)
	if userIds != "" {
		companyUserList, e := company.GetFiccCompanyUserByUserIds(userIds)
		if e != nil {
			err = errors.New("获取客户信息失败 Err:" + e.Error())
			return
		}
		for _, v := range companyUserList {
			userCompanyMap[int(v.UserId)] = v
		}
	}
	for _, v := range detailList {
		pageTotal += v.CountNum
		item := new(response.PriceDrivenClickCensusDetailItem)
		if u, ok := userCompanyMap[v.UserId]; ok {
			item.RealName = u.RealName
			item.CompanyName = u.CompanyName
			item.CompanyStatus = u.Status
		}
		item.CountNum = v.CountNum
		item.SourceAgent = v.NewSourceAgent
		item.RecentClickTime = v.RecentClickTime
		list = append(list, item)
	}
	return
}