package autocode

import (
	global "github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/autocode"
	autocodeReq "github.com/flipped-aurora/gin-vue-admin/server/model/autocode/request"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
	"github.com/flipped-aurora/gin-vue-admin/server/model/system"
	"github.com/flipped-aurora/gin-vue-admin/server/service"
	"github.com/flipped-aurora/gin-vue-admin/server/utils"
	"github.com/gin-gonic/gin"
	"github.com/silenceper/wechat/v2/officialaccount/message"
	"go.uber.org/zap"
	"strconv"
	"strings"
	"time"
)

type ProblemInfoApi struct {
}

var problemInfoService = service.ServiceGroupApp.AutoCodeServiceGroup.ProblemInfoService

// CreateProblemInfo 创建ProblemInfo
// @Tags ProblemInfo
// @Summary 创建ProblemInfo
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body autocode.ProblemInfo true "创建ProblemInfo"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /problemInfo/createProblemInfo [post]
func (problemInfoApi *ProblemInfoApi) CreateProblemInfo(c *gin.Context) {
	userId := utils.GetUserID(c)
	var problemInfo autocode.ProblemInfo
	_ = c.ShouldBindJSON(&problemInfo)
	problemInfo.Status = "Untreated"
	if err, place := service.ServiceGroupApp.AutoCodeServiceGroup.PlaceService.GetPlace(problemInfo.SiteId); err != nil {
		response.FailWithMessage("创建失败,选择站点错误", c)
	} else {
		problemInfo.Oper = userId
		problemInfo.SiteType = place.Type
		problemInfo.Position = place.Position
		problemInfo.SiteName = place.Name
		problemInfo.Region = place.Region
	}

	if problemInfo.Department != "" {
		probleTypeIds := strings.Split(problemInfo.Matter, "|")
		//计算分值
		if len(probleTypeIds) > 0 {
			_, proTypes := problemTypeService.GetProblemTypeIds(probleTypeIds)
			var integral int
			for _, proType := range proTypes {
				inter := *proType.Integral
				integral = integral + inter
			}
			problemInfo.Integral = &integral
		}
		// 发送问题到负责人
		departmentIds := strings.Split(problemInfo.Department, "|")
		for _, unitId := range departmentIds {
			id, _ := strconv.Atoi(unitId)
			if err, unitPlaces := unitPlaceService.GetUnitPlaces(&id); err != nil {
				unitPlaceService.CreateUnitPlace(autocode.UnitPlace{UnitId: &id, PlaceId: strconv.Itoa(int(problemInfo.SiteId))})
				ids := []string{unitId}
				sum := placeService.FindPlaceSum(ids)
				unitService.UpdateUnitMaxIntegral(&id, sum)
			} else {
				isA := true
				for _, unitPlace := range unitPlaces {
					if unitPlace.PlaceId == strconv.Itoa(int(problemInfo.SiteId)) {
						isA = false
					}
				}
				if isA {
					placeIds := make([]string, 0)
					for _, places := range unitPlaces {
						placeIds = append(placeIds, places.PlaceId)
					}
					placeIds = append(placeIds, strconv.Itoa(int(problemInfo.SiteId)))
					sum := placeService.FindPlaceSum(placeIds)
					unitService.UpdateUnitMaxIntegral(&id, sum)
					unitPlaceService.CreateUnitPlace(autocode.UnitPlace{UnitId: &id, PlaceId: strconv.Itoa(int(problemInfo.SiteId))})
				}
			}

			if err, unituser := unitUserService.GetUnitUsers(&id); err != nil {
				source := make([]string, 0)
				for _, item := range unituser {
					source = append(source, item.UUID)
				}
				SendMsg(autocodeReq.SendUser{ProblemID: problemInfo.ID, ID: source}, true)
			}
		}

	}
	if err := problemInfoService.CreateProblemInfo(problemInfo); err != nil {
		global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
		response.FailWithMessage("发布失败", c)
	} else {
		response.OkWithMessage("发布成功", c)
	}
}

func (problemInfoApi *ProblemInfoApi) ExportExcel(c *gin.Context) {
	var problemInfo autocodeReq.ProblemInfoSearch
	_ = c.ShouldBindJSON(&problemInfo)
	filePath := global.GVA_CONFIG.Excel.Dir + strconv.FormatInt(time.Now().Unix(), 10) + ".xlsx"
	if err, list, _ := problemInfoService.GetProblemInfoInfoList(problemInfo); err != nil {
		global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
		response.FailWithMessage("获取失败", c)
	} else {
		_, siteType := service.ServiceGroupApp.SystemServiceGroup.DictionaryService.GetSysDictionary("site_type", 0)
		_, proList := problemTypeService.GetProblemTypeInfoListAll()
		err := service.ServiceGroupApp.ExampleServiceGroup.ExcelService.ProblemInfoList2Excel(list, filePath, siteType, proList)
		if err != nil {
			global.GVA_LOG.Error("转换Excel失败!", zap.Any("err", err))
			response.FailWithMessage("转换Excel失败", c)
			return
		}
		c.Writer.Header().Add("success", "true")
		c.File(filePath)
	}
}

func (problemInfoApi *ProblemInfoApi) SendUser(c *gin.Context) {
	var sendUser autocodeReq.SendUser
	_ = c.ShouldBindJSON(&sendUser)
	SendMsg(sendUser, false)
	response.OkWithMessage("发送成功", c)
}

func SendMsg(sendUser autocodeReq.SendUser, isUuid bool) {
	_, problem := problemInfoService.GetProblemInfo(sendUser.ProblemID)
	_, opera := service.ServiceGroupApp.SystemServiceGroup.FindUserById(int(problem.Oper))
	appid := global.GVA_CONFIG.Wxxcx.Appid
	for _, id := range sendUser.ID {
		var user *system.SysUser
		if isUuid {
			_, user = service.ServiceGroupApp.SystemServiceGroup.FindUserByUuid(id)
		} else {
			userId, _ := strconv.Atoi(id)
			_, user = service.ServiceGroupApp.SystemServiceGroup.FindUserById(userId)
		}
		if user.WechatId == "" {
			continue
		}
		msg := &message.TemplateMessage{
			ToUser:     user.WechatId,
			TemplateID: global.GVA_CONFIG.Wxxcx.Msgid,
			Data: map[string]*message.TemplateDataItem{
				"first":    {Value: "有新的站点问题"},
				"keyword1": {Value: opera.Username},
				"keyword2": {Value: problem.SiteName},
				"keyword3": {Value: problem.Department},
				"keyword4": {Value: problem.CreatedAt.Format("2006-01-02 15:04:05")},
				"remark":   {Value: "点击查看问题"},
			},
			MiniProgram: struct {
				AppID    string `json:"appid"`
				PagePath string `json:"pagepath"`
			}{AppID: appid, PagePath: "/pages/public-details?id=" + strconv.Itoa(int(sendUser.ProblemID))},
		}
		if _, err := global.GVA_WECHAT.GetTemplate().Send(msg); err != nil {
			global.GVA_LOG.Error("微信模板通知失败!", zap.Any("err", err))
		}
	}
}

// DeleteProblemInfo 删除ProblemInfo
// @Tags ProblemInfo
// @Summary 删除ProblemInfo
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body autocode.ProblemInfo true "删除ProblemInfo"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /problemInfo/deleteProblemInfo [delete]
func (problemInfoApi *ProblemInfoApi) DeleteProblemInfo(c *gin.Context) {
	var problemInfo autocode.ProblemInfo
	_ = c.ShouldBindJSON(&problemInfo)
	if err := problemInfoService.DeleteProblemInfo(problemInfo); err != nil {
		global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
		response.FailWithMessage("删除失败", c)
	} else {
		response.OkWithMessage("删除成功", c)
	}
}

// DeleteProblemInfoByIds 批量删除ProblemInfo
// @Tags ProblemInfo
// @Summary 批量删除ProblemInfo
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除ProblemInfo"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /problemInfo/deleteProblemInfoByIds [delete]
func (problemInfoApi *ProblemInfoApi) DeleteProblemInfoByIds(c *gin.Context) {
	var IDS request.IdsReq
	_ = c.ShouldBindJSON(&IDS)
	if err := problemInfoService.DeleteProblemInfoByIds(IDS); err != nil {
		global.GVA_LOG.Error("批量删除失败!", zap.Any("err", err))
		response.FailWithMessage("批量删除失败", c)
	} else {
		response.OkWithMessage("批量删除成功", c)
	}
}

// UpdateProblemInfo 更新ProblemInfo
// @Tags ProblemInfo
// @Summary 更新ProblemInfo
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body autocode.ProblemInfo true "更新ProblemInfo"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /problemInfo/updateProblemInfo [put]
func (problemInfoApi *ProblemInfoApi) UpdateProblemInfo(c *gin.Context) {
	var problemInfo autocode.ProblemInfo
	_ = c.ShouldBindJSON(&problemInfo)
	_, problemInfoNow := problemInfoService.GetProblemInfo(problemInfo.ID)
	problemInfoNow.Handler = problemInfo.Handler
	problemInfoNow.HandImgs = problemInfo.HandImgs
	problemInfoNow.HandText = problemInfo.HandText
	problemInfoNow.Status = "Processed"
	if err := problemInfoService.UpdateProblemInfo(problemInfoNow); err != nil {
		global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
		response.FailWithMessage("更新失败", c)
	} else {
		response.OkWithMessage("更新成功", c)
	}
}

func (problemInfoApi *ProblemInfoApi) UpdateProblemInfoStatus(c *gin.Context) {
	var problemInfo autocode.ProblemInfo
	_ = c.ShouldBindJSON(&problemInfo)
	_, problemInfoNow := problemInfoService.GetProblemInfo(problemInfo.ID)
	problemInfoNow.Status = problemInfo.Status
	problemInfoNow.Audit = problemInfo.Audit
	if problemInfo.Status == "Success" {
		if time.Now().Unix() > problemInfoNow.HandAt.Unix() {
			//超时扣分
			probIds := strings.Split(problemInfoNow.Matter, "|")
			//问题关联的部门
			unitIds := strings.Split(problemInfoNow.Department, "|")
			if err, probTypes := problemTypeService.GetProblemTypeIds(probIds); err == nil {
				//扣部门分数
				for _, unitId := range unitIds {
					if unitId == "" {
						continue
					}
					integral := 0
					for _, probType := range probTypes {
						if strings.Index(probType.UnitIds, unitId) != -1 {
							integral = integral + *probType.Integral
						}
					}
					if integral != 0 {
						id, _ := strconv.Atoi(unitId)
						global.GVA_LOG.Error("id!", zap.Any("unitId", unitId), zap.Any("id", id))
						_, unit := unitService.GetUnit(uint(id))
						oldIntegral := *unit.UnitIntegral
						nowIntegral := oldIntegral + integral
						unit.UnitIntegral = &nowIntegral
						unitService.UpdateUnitA(unit)
					}
				}
			}
		} else {
			temp := 0
			problemInfo.Integral = &temp
			// 未超时，不处理
		}
	}

	if err := problemInfoService.UpdateProblemInfo(problemInfoNow); err != nil {
		global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
		response.FailWithMessage("更新失败", c)
	} else {
		response.OkWithMessage("更新成功", c)
	}
}

// FindProblemInfo 用id查询ProblemInfo
// @Tags ProblemInfo
// @Summary 用id查询ProblemInfo
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query autocode.ProblemInfo true "用id查询ProblemInfo"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /problemInfo/findProblemInfo [get]
func (problemInfoApi *ProblemInfoApi) FindProblemInfo(c *gin.Context) {
	var problemInfo autocode.ProblemInfo
	_ = c.ShouldBindQuery(&problemInfo)
	if err, reproblemInfo := problemInfoService.GetProblemInfo(problemInfo.ID); err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Any("err", err))
		response.FailWithMessage("查询失败", c)
	} else {
		//param := reqMode.SysDictionarySearch{, request.PageInfo{PageSize: 9999, Page: 0}}
		_, reproblemInfo.MatterList, _ = service.ServiceGroupApp.AutoCodeServiceGroup.GetProblemTypeInfoListBySiteType(reproblemInfo.SiteType)
		response.OkWithData(gin.H{"reproblemInfo": reproblemInfo}, c)
	}
}

func (problemInfoApi *ProblemInfoApi) FindProblemPInfo(c *gin.Context) {
	var problemInfo autocode.ProblemInfo
	_ = c.ShouldBindQuery(&problemInfo)
	if err, reproblemInfo := problemInfoService.GetProblemInfo(problemInfo.ID); err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Any("err", err))
		response.FailWithMessage("查询失败", c)
	} else {
		userId := utils.GetUserID(c)
		//记录查看记录
		if err, readCount := service.ServiceGroupApp.AutoCodeServiceGroup.ReadCountService.GetReadCountByUserId(int(userId), int(problemInfo.ID)); err != nil {
			//新增
			service.ServiceGroupApp.AutoCodeServiceGroup.ReadCountService.CreateReadCount(autocode.ReadCount{ProblemId: problemInfo.ID, UserId: userId, UserName: utils.GetUserInfo(c).Username})
		} else {
			service.ServiceGroupApp.AutoCodeServiceGroup.ReadCountService.UpdateReadCountBy(readCount.ID)
		}

		//累加总阅读量
		problemInfoService.UpdateProblemInfoCount(problemInfo.ID)
		//param := reqMode.SysDictionarySearch{, request.PageInfo{PageSize: 9999, Page: 0}}
		_, reproblemInfo.MatterList, _ = service.ServiceGroupApp.AutoCodeServiceGroup.GetProblemTypeInfoListBySiteType(reproblemInfo.SiteType)
		response.OkWithData(gin.H{"reproblemInfo": reproblemInfo}, c)
	}
}

// GetProblemInfoList 分页获取ProblemInfo列表
// @Tags ProblemInfo
// @Summary 分页获取ProblemInfo列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query autocodeReq.ProblemInfoSearch true "分页获取ProblemInfo列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /problemInfo/getProblemInfoList [get]
func (problemInfoApi *ProblemInfoApi) GetProblemInfoList(c *gin.Context) {
	var pageInfo autocodeReq.ProblemInfoSearch
	_ = c.ShouldBindQuery(&pageInfo)
	if err, list, total := problemInfoService.GetProblemInfoInfoList(pageInfo); err != nil {
		global.GVA_LOG.Error("获取失败!", zap.Any("err", err))
		response.FailWithMessage("获取失败", c)
	} else {
		response.OkWithDetailed(response.PageResult{
			List:     list,
			Total:    total,
			Page:     pageInfo.Page,
			PageSize: pageInfo.PageSize,
		}, "获取成功", c)
	}
}
