package front

import (
	"fmt"
	"github.com/tealeg/xlsx"
	"mongodb"
	"os"
	qu "qfw/util"
	"strconv"
	"strings"
	"time"
	"util"
)

// GroupTaskListByGroup 用户组权限用户组任务列表
func (f *Front) GroupTaskListByGroup() {
	defer qu.Catch()
	if f.Method() == "POST" {
		user := f.GetSession("user").(map[string]interface{})
		role := qu.ObjToString(user["i_role"])
		start, _ := f.GetInteger("start")
		limit, _ := f.GetInteger("length")
		draw, _ := f.GetInteger("draw")
		status := f.GetString("s_status")
		searchStr := f.GetString("search[value]")
		search := strings.TrimSpace(searchStr)
		groupId := qu.ObjToString(user["s_groupid"])
		query := map[string]interface{}{
			"s_stype": "group", //检索用户组任务
		}
		if role != "0" {
			query["s_groupid"] = groupId
		}
		if status != "-1" { //任务状态
			query["s_status"] = status
		}
		if search != "" {
			query["$or"] = []interface{}{
				map[string]interface{}{"s_projectname": map[string]interface{}{"$regex": search}},
			}
		}
		qu.Debug("Query：", query)
		list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, map[string]interface{}{"_id": -1}, nil, false, start, limit)
		count := util.Mgo.Count(util.TASKCOLLNAME, query)
		for _, l := range *list {
			if status := qu.ObjToString(l["s_status"]); status == "进行中" { //更新任务进度
				//groupId := qu.ObjToString(l["s_groupid"])
				groupTaskId := mongodb.BsonIdToSId(l["_id"])
				giveNum := qu.IntAll(l["i_givenum"])
				sourceinfo := qu.ObjToString(l["s_sourceinfo"])
				//tagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"b_isgivegroup": true, "s_grouptaskid": groupTaskId, "b_istag": true})
				tagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": groupTaskId, "b_istag": true})
				progressFloat := float64(tagNum) / float64(giveNum)
				value, _ := strconv.ParseFloat(fmt.Sprintf("%.4f", progressFloat), 64)
				progress := fmt.Sprint(value*100) + "%"
				l["s_progress"] = progress
				//同步数据库
				util.Mgo.UpdateById(util.TASKCOLLNAME, l["_id"], map[string]interface{}{"$set": map[string]interface{}{"s_progress": progress}})
			}
		}
		f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
	} else {
		_ = f.Render("project/task_group_list.html")
	}
}

// GroupTaskListByAdmin 系统管理员权限用户组任务列表
func (f *Front) GroupTaskListByAdmin() {
	defer qu.Catch()
	if f.Method() == "POST" {
		start, _ := f.GetInteger("start")
		limit, _ := f.GetInteger("length")
		draw, _ := f.GetInteger("draw")
		status := f.GetString("s_status")
		searchStr := f.GetString("search[value]")
		search := strings.TrimSpace(searchStr)
		starttime, _ := f.GetInt("starttime")
		endtime, _ := f.GetInt("endtime")
		query := map[string]interface{}{
			"s_stype": "group", //检索用户组任务
		}
		if starttime > 0 {
			query["i_starttime"] = map[string]interface{}{
				"$gte": starttime,
			}
		}
		if endtime > 0 {
			query["i_completetime"] = map[string]interface{}{
				"$lte": endtime,
			}
		}
		if status != "-1" { //任务状态
			query["s_status"] = status
		}
		if search != "" {
			query["$or"] = []interface{}{
				map[string]interface{}{"s_projectname": map[string]interface{}{"$regex": search}},
				map[string]interface{}{"s_entname": map[string]interface{}{"$regex": search}},
				map[string]interface{}{"s_rulename": map[string]interface{}{"$regex": search}},
				map[string]interface{}{"s_departname": map[string]interface{}{"$regex": search}},
			}
		}
		qu.Debug("Query：", query)
		count := util.Mgo.Count(util.TASKCOLLNAME, query)
		list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, map[string]interface{}{"_id": -1}, nil, false, start, limit)
		for _, l := range *list {
			if status := qu.ObjToString(l["s_status"]); status == "进行中" { //更新任务进度
				//groupId := qu.ObjToString(l["s_groupid"])
				groupTaskId := mongodb.BsonIdToSId(l["_id"])
				giveNum := qu.IntAll(l["i_givenum"])
				sourceinfo := qu.ObjToString(l["s_sourceinfo"])
				//tagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"b_isgivegroup": true, "s_grouptaskid": groupTaskId, "b_istag": true})
				tagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": groupTaskId, "b_istag": true})
				progressFloat := float64(tagNum) / float64(giveNum)
				value, _ := strconv.ParseFloat(fmt.Sprintf("%.4f", progressFloat), 64)
				progress := fmt.Sprint(value*100) + "%"
				l["s_progress"] = progress
				//同步数据库
				util.Mgo.UpdateById(util.TASKCOLLNAME, l["_id"], map[string]interface{}{"$set": map[string]interface{}{"s_progress": progress}})
			}
		}

		f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
	} else {
		_ = f.Render("project/task_list.html")
	}
}

// GroupUserTaskList 用户任务分发列表
func (f *Front) GroupUserTaskList() {
	defer qu.Catch()
	//groupId := f.GetString("s_groupid") //用户组id
	pid := f.GetString("pid")
	groupTaskId := f.GetString("grouptaskid") //用户组任务id
	qu.Debug("groupTaskId：", groupTaskId)
	if f.Method() == "POST" {
		start, _ := f.GetInteger("start")
		limit, _ := f.GetInteger("length")
		draw, _ := f.GetInteger("draw")
		status := f.GetString("s_status")
		login := f.GetString("s_login")
		searchStr := f.GetString("search[value]")
		search := strings.TrimSpace(searchStr)
		query := map[string]interface{}{
			"s_stype":    "user",
			"s_parentid": groupTaskId,
		}
		if status != "-1" { //任务状态
			query["s_status"] = status
		}
		if login != "-1" { //用户账号
			query["s_login"] = login
		}
		if search != "" {
			query["$or"] = []interface{}{
				map[string]interface{}{"s_projectname": map[string]interface{}{"$regex": search}},
			}
		}
		qu.Debug("Query：", query)
		count := util.Mgo.Count(util.TASKCOLLNAME, query)
		list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, map[string]interface{}{"_id": -1}, nil, false, start, limit)
		for _, l := range *list {
			if status := qu.ObjToString(l["s_status"]); status == "进行中" { //更新任务进度
				giveNum := qu.IntAll(l["i_givenum"])
				sourceinfo := qu.ObjToString(l["s_sourceinfo"])
				tagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_usertaskid": mongodb.BsonIdToSId(l["_id"]), "b_istag": true})
				progressFloat := float64(tagNum) / float64(giveNum)
				value, _ := strconv.ParseFloat(fmt.Sprintf("%.4f", progressFloat), 64)
				progress := fmt.Sprint(value*100) + "%"
				l["s_progress"] = progress
				//同步数据库
				util.Mgo.UpdateById(util.TASKCOLLNAME, l["_id"], map[string]interface{}{"$set": map[string]interface{}{"s_progress": progress}})
			}
		}
		f.ServeJson(map[string]interface{}{"draw": draw, "data": *list, "recordsFiltered": count, "recordsTotal": count})
	} else {
		sourceinfo := f.GetString("s_sourceinfo")
		qu.Debug(sourceinfo)
		//统计数据量
		isGiveNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": groupTaskId, "b_isgiveuser": true})     //已分发量
		isNotGiveNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": groupTaskId, "b_isgiveuser": false}) //待分发量
		isTagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": groupTaskId, "b_istag": true})           //已标注数量
		isNotTagNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": groupTaskId, "b_istag": false})       //未标注数量
		allNum := util.Mgo.Count(sourceinfo, map[string]interface{}{"s_grouptaskid": groupTaskId})                              //数据总量
		qu.Debug("数据总量：", allNum, "已分发量：", isGiveNum, "待分发量：", isNotGiveNum, "已标注量：", isTagNum, "未标注量：", isNotTagNum)
		f.T["pid"] = pid
		f.T["grouptaskid"] = groupTaskId
		f.T["allNum"] = allNum
		f.T["isGiveNum"] = isGiveNum
		f.T["isNotGiveNum"] = isNotGiveNum
		f.T["isTagNum"] = isTagNum
		f.T["isNotTagNum"] = isNotTagNum
		_ = f.Render("project/task_detail.html", &f.T)
	}
}

// GroupTaskDeliver 用户组任务交付
func (f *Front) GroupTaskDeliver() {
	defer qu.Catch()
	user := f.GetSession("user").(map[string]interface{})
	username := qu.ObjToString(user["s_login"]) //当前登录用户
	success := false
	msg := ""
	groupTaskId := f.GetString("taskid") //用户组任务id
	qu.Debug("Group Task ID：", groupTaskId)
	groupTask, _ := util.Mgo.FindById(util.TASKCOLLNAME, groupTaskId, map[string]interface{}{"v_sonids": 1, "s_sourceinfo": 1})
	if groupTask != nil && len(*groupTask) > 0 {
		sonUserIds := (*groupTask)["v_sonids"].([]interface{})
		if len(sonUserIds) > 0 {
			sourceInfo := qu.ObjToString((*groupTask)["s_sourceinfo"])
			dataCount := util.Mgo.Count(sourceInfo, map[string]interface{}{"s_grouptaskid": groupTaskId, "b_istag": false})
			taskCount := util.Mgo.Count(util.TASKCOLLNAME, map[string]interface{}{"s_parentid": groupTaskId, "s_status": map[string]interface{}{"$in": []string{"未开始", "进行中"}}})
			if dataCount == 0 && taskCount == 0 {
				success = util.Mgo.UpdateById(util.TASKCOLLNAME, groupTaskId, map[string]interface{}{
					"$set": map[string]interface{}{
						"i_completetime": time.Now().Unix(),
						"s_updateperson": username,
						"i_updatetime":   time.Now().Unix(),
						"s_status":       "已完成",
						"s_progress":     "100%",
					},
				})
				if !success {
					msg = "更新任务信息失败"
				}
			} else {
				if taskCount != 0 {
					msg += "用户任务未全部完成;"
				}
				if dataCount != 0 {
					msg += "数据未全部标注;"
				}
			}
		} else {
			msg = "任务暂未分配"
		}
	} else {
		msg = "查询任务失败"
	}
	f.ServeJson(map[string]interface{}{"success": success, "msg": msg})
}

var modelpath string = "web/model/任务详情%d.xlsx"

// GroupTaskExport 用户组任务导出
func (f *Front) GroupTaskExport() {
	defer qu.Catch()
	starttime, _ := f.GetInt("i_starttime")
	completetime, _ := f.GetInt("i_completetime")
	status := f.GetString("s_status")
	searchStr := f.GetString("s_search")
	search := strings.TrimSpace(searchStr)
	query := map[string]interface{}{
		"s_stype": "group",
	}
	if status != "-1" { //任务状态
		query["s_status"] = status
	}
	if search != "" {
		query["$or"] = []interface{}{
			map[string]interface{}{"s_entname": map[string]interface{}{"$regex": search}},
		}
	}
	if starttime > 0 {
		query["i_starttime"] = map[string]interface{}{
			"$gte": starttime,
		}
	}
	if completetime > 0 {
		query["i_completetime"] = map[string]interface{}{
			"$lte": completetime,
		}
	}
	qu.Debug("Query：", query)
	count := util.Mgo.Count(util.TASKCOLLNAME, query)
	if count > 0 {
		file, err := xlsx.OpenFile("web/model/taskexportmodel.xlsx")
		if err != nil {
			qu.Debug("Load Excel Model Error")
			f.ServeJson("加载脚本失败")
			return
		}
		sheet := file.Sheets[0]
		fields := map[string]interface{}{
			"s_entname":      1,
			"s_departname":   1,
			"s_rulename":     1,
			"s_projectname":  1,
			"s_groupname":    1,
			"s_personname":   1,
			"i_givenum":      1,
			"s_status":       1,
			"i_starttime":    1,
			"i_completetime": 1,
		}
		list, _ := util.Mgo.Find(util.TASKCOLLNAME, query, nil, fields, false, -1, -1)
		for _, l := range *list {
			row := sheet.AddRow()
			entname := qu.ObjToString(l["s_entname"])
			departname := qu.ObjToString(l["s_departname"])
			rulename := qu.ObjToString(l["s_rulename"])
			projectname := qu.ObjToString(l["s_projectname"])
			groupname := qu.ObjToString(l["s_groupname"])
			personname := qu.ObjToString(l["s_personname"])
			givenum := qu.IntAll(l["i_givenum"])
			status := qu.ObjToString(l["s_status"])
			starttimestr := ""
			if starttime := qu.Int64All(l["i_starttime"]); starttime != 0 {
				starttimestr = qu.FormatDateByInt64(&starttime, qu.Date_Full_Layout)
			}
			completetimestr := ""
			if completetime := qu.Int64All(l["i_completetime"]); completetime != 0 {
				completetimestr = qu.FormatDateByInt64(&completetime, qu.Date_Full_Layout)
			}
			row.AddCell().SetValue(entname)
			row.AddCell().SetValue(departname)
			row.AddCell().SetValue(rulename)
			row.AddCell().SetValue(projectname)
			row.AddCell().SetValue(groupname)
			row.AddCell().SetValue(personname)
			row.AddCell().SetValue(givenum)
			row.AddCell().SetValue(status)
			row.AddCell().SetValue(starttimestr)
			row.AddCell().SetValue(completetimestr)
		}
		fname := fmt.Sprintf(modelpath, time.Now().Unix())
		qu.Debug("File Name：", fname)
		err = file.Save(fname)
		if err != nil {
			qu.Debug("Save Excel" + fname + "Error")
			f.ServeJson("导出失败")
			return
		}
		arr := strings.Split(fname, "/")
		f.ResponseWriter.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", arr[len(arr)-1]))
		f.ServeFile(fname)
		go func(path string) {
			time.Sleep(time.Second * 30)
			os.Remove(path)
		}(fname)
	} else {
		f.ServeJson("没有数据")
	}
}
