// user
package admin

import (
	"encoding/json"
	"jy/front"
	. "jy/mongodbutil"
	. "jy/util"
	"net/http"
	qu "qfw/util"
	"time"

	"fmt"

	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"gopkg.in/mgo.v2/bson"
)

func init() {
	Admin.GET("/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", nil)
	})
	Admin.GET("/user", func(c *gin.Context) {
		c.HTML(http.StatusOK, "user.html", gin.H{})
	})
	Admin.GET("/menu", func(c *gin.Context) {
		c.HTML(http.StatusOK, "menu.html", gin.H{})
	})
	Admin.GET("/infotype", func(c *gin.Context) {
		c.HTML(http.StatusOK, "class.html", gin.H{})
	})
	Admin.GET("/role", func(c *gin.Context) {
		c.HTML(http.StatusOK, "role.html", gin.H{})
	})
	Admin.GET("/role/menu", func(c *gin.Context) {
		role := c.Query("role")
		c.HTML(http.StatusOK, "rolemenu.html", gin.H{"role": role})
	})
	Admin.GET("/role/secondmenu", func(c *gin.Context) {
		role := c.Query("role")
		_id := c.Query("_id")
		c.HTML(http.StatusOK, "rolesecondmenu.html", gin.H{"role": role, "_id": _id})
	})
	Admin.GET("/secondmenu", func(c *gin.Context) {
		_id := c.Query("id")
		c.HTML(http.StatusOK, "secondmenu.html", gin.H{"_id": _id})
	})

	Admin.POST("/menu", Menu) //左侧菜单栏
	//一级菜单
	Admin.POST("/menu/save", MenuSave)             //保存一级菜单
	Admin.POST("/menu/data", MenuData)             //查询一级菜单
	Admin.POST("/menu/searchbyid", MenuSearchById) //编辑一级菜单
	Admin.POST("/menu/del", MenuDel)               //删除一级菜单
	//二级菜单
	Admin.POST("/secondmenu/data", SecondMenuData)             //查询二级菜单
	Admin.POST("/secondmenu/save", SecondMenuSave)             //保存二级菜单
	Admin.POST("/secondmenu/searchbyid", SecondMenuSearchById) //编辑二级菜单
	Admin.POST("/secondmenu/del", SecondMenuDel)               //删除二级菜单
	//分类抽取
	Admin.POST("/infotype/data", InfotypeData)     //查询分类信息
	Admin.POST("/fields/data", FieldsData)         //查询所有属性
	Admin.POST("/topclass/data", TopclassData)     //查询所有一级分类
	Admin.POST("/subclass/data", SubclassData)     //查询二级分类
	Admin.POST("/infotype/save", InfotypeSave)     //保存分类信息
	Admin.POST("/infotype/select", InfotypeSelect) //编辑分类信息
	Admin.POST("/infotype/del", InfotypeDel)       //删除分类信息
	//角色
	Admin.POST("/role/menu/data", RoleMenuData) //查询角色的所有菜单
	Admin.POST("/role/menu/save", RoleMenuSave) //保存角色的所有菜单
	Admin.POST("/role/select", RoleSelect)      //编辑一级菜单下的二级菜单
	//Admin.POST("/role/secondmenu/data", RoleSecondMenuData) //查询一级菜单下的二级菜单
	Admin.POST("/role/menu/del", RoleMenuDel) //删除一级菜单
	//Admin.POST("/role/secondmenu/del", RoleSecondMenuDel)   //

	Admin.POST("/user/data", User)
	Admin.POST("/user/save", UserSave)
	Admin.POST("/user/searchbyid", UserSearchById)
	Admin.POST("/user/del", UserDel)
	Admin.POST("/user/uppwd", UserUppwd)
}

func User(c *gin.Context) {
	maps := map[string]interface{}{
		"role": map[string]interface{}{
			"$ne": "3",
		},
	}
	data, _ := Mgo.Find("user", maps, nil, nil, false, -1, -1)
	c.JSON(200, gin.H{"data": data})
}
func MenuData(c *gin.Context) {
	data, _ := Mgo.Find("menu", `{}`, nil, nil, false, -1, -1)
	c.JSON(200, gin.H{"data": data})
}
func SecondMenuData(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	maps := map[string]interface{}{
		"menuid": _id,
	}
	data, _ := Mgo.Find("menusecond", maps, nil, nil, false, -1, -1)
	c.JSON(200, gin.H{"data": data})
}
func InfotypeData(c *gin.Context) {
	datas, _ := Mgo.Find("infotype", `{}`, nil, nil, false, -1, -1)
	list := []map[string]interface{}{}
	for _, data := range *datas {
		if data["subclass"] == nil {
			data["subclass"] = ""
			list = append(list, data)
		} else {
			for k, _ := range data["subclass"].(map[string]interface{}) {
				value := map[string]interface{}{
					"_id":      data["_id"],
					"topclass": data["topclass"],
					"subclass": k,
				}
				list = append(list, value)
			}
		}
	}
	c.JSON(200, gin.H{"data": list})
}
func FieldsData(c *gin.Context) {
	datas, _ := Mgo.Find("fields", `{}`, nil, nil, false, -1, -1)
	c.JSON(200, gin.H{"data": datas})
}
func TopclassData(c *gin.Context) {
	datas, _ := Mgo.Find("infoclass", `{}`, nil, nil, false, -1, -1)
	c.JSON(200, gin.H{"data": datas})
}
func SubclassData(c *gin.Context) {
	topclass, _ := c.GetPostForm("top")
	datas, _ := Mgo.FindOneByField("infoclass", `{"topclass":"`+topclass+`"}`, `{"subclass":"1"}`)
	data := *datas
	if data["subclass"] != nil {
		c.JSON(200, gin.H{"data": datas})
	}
}
func InfotypeSave(c *gin.Context) {
	topclass, _ := c.GetPostForm("topclass")
	subclass, _ := c.GetPostForm("subclass")
	fieldsStr, _ := c.GetPostForm("fields")
	fieldsStr2, _ := c.GetPostForm("fields2")
	_id, _ := c.GetPostForm("_id")
	fields := make([]string, 0)
	err := json.Unmarshal([]byte(fieldsStr), &fields)
	fields2 := make([]string, 0)
	err2 := json.Unmarshal([]byte(fieldsStr2), &fields2)
	if _id == "" {
		b := Mgo.Count("infotype", map[string]interface{}{
			"topclass": topclass,
		})
		b2 := 0
		if subclass != "" {
			b2 = Mgo.Count("infotype", map[string]interface{}{
				"subclass." + subclass: map[string]interface{}{
					"$exists": true,
				},
			})
		}
		if (b == 0) || (b != 0 && b2 == 0 && subclass != "") {
			if err == nil {
				if subclass == "" {
					maps := map[string]interface{}{
						"topclass": topclass,
						"fields":   map[string]interface{}{},
					}
					for _, field := range fields {
						maps["fields"].(map[string]interface{})[field] = true
					}
					Mgo.Save("infotype", maps)
				} else {
					maps := map[string]interface{}{}
					for _, field := range fields {
						maps = map[string]interface{}{
							"subclass." + subclass + "." + field: true,
						}
						maps2 := map[string]interface{}{
							"$set": maps,
						}
						set := map[string]interface{}{
							"topclass": topclass,
						}
						Mgo.Update("infotype", set, maps2, true, false)
					}
				}
				c.JSON(200, gin.H{"rep": true})
			}
		}
	} else {
		if err == nil && err2 == nil {
			set := map[string]interface{}{
				"_id": bson.ObjectIdHex(_id),
			}
			if subclass == "" {
				maps := map[string]interface{}{
					"fields": map[string]interface{}{},
				}
				for _, field := range fields {
					maps["fields"].(map[string]interface{})[field] = true
				}
				maps2 := map[string]interface{}{
					"$set": maps,
				}
				Mgo.Update("infotype", set, maps2, false, false)
			} else {
				maps := map[string]interface{}{
					"subclass." + subclass: map[string]interface{}{},
				}
				for _, field := range fields {
					maps["subclass."+subclass].(map[string]interface{})[field] = true
					maps2 := map[string]interface{}{
						"$set": maps,
					}
					Mgo.Update("infotype", set, maps2, false, false)
				}
			}
			c.JSON(200, gin.H{"rep": true})
		}
	}

}
func InfotypeSelect(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	subclass, _ := c.GetPostForm("subclass")
	one1, _ := Mgo.FindById("infotype", _id, `{}`)
	one := *one1
	datas, _ := Mgo.Find("fields", `{}`, nil, nil, false, -1, -1)
	datas2 := *datas
	//list2:=[]map[string]interface{}{}
	if one["subclass"] == nil {
		list := []interface{}{}
		for k, v := range one["fields"].(map[string]interface{}) {
			if v == true {
				s_name1, _ := Mgo.FindOneByField("fields", map[string]interface{}{"s_field": k}, `{}`)
				s_name := *s_name1
				//已存在属性
				list = append(list, s_name)
				for key, value := range datas2 {
					if value["s_field"] == k {
						datas2 = append(datas2[:key], datas2[key+1:]...)
					}
				}
			}
		}
		fmt.Println(one["topclass"].(string), list)
		c.JSON(200, gin.H{"topclass": one["topclass"].(string), "subclass": "", "fields2": datas2, "fields": list})
	} else {
		maps := one["subclass"].(map[string]interface{})[subclass]
		list := []interface{}{}
		for k, v := range maps.(map[string]interface{}) {
			if v == true {
				s_name1, _ := Mgo.FindOneByField("fields", map[string]interface{}{"s_field": k}, `{}`)
				s_name := *s_name1
				list = append(list, s_name)
				for key, value := range datas2 {
					if value["s_field"] == k {
						datas2 = append(datas2[:key], datas2[key+1:]...)
					}
				}
			}
		}
		fmt.Println(one["topclass"].(string), subclass, list)
		c.JSON(200, gin.H{"topclass": one["topclass"].(string), "subclass": subclass, "fields2": datas2, "fields": list})
	}

}
func InfotypeDel(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	subclass, _ := c.GetPostForm("subclass")
	set := map[string]interface{}{
		"_id": bson.ObjectIdHex(_id),
	}
	if subclass == "" {
		b := Mgo.Del("infotype", set)
		c.JSON(200, gin.H{"rep": b})
	} else {
		info1, _ := Mgo.FindById("infotype", _id, `{}`)
		info := *info1
		maps := info["subclass"].(map[string]interface{})
		delete(maps, subclass)
		if len(maps) == 0 {
			b := Mgo.Del("infotype", set)
			c.JSON(200, gin.H{"rep": b})
		} else {
			maps2 := map[string]interface{}{
				"subclass": maps,
			}
			maps3 := map[string]interface{}{
				"$set": maps2,
			}
			b := Mgo.Update("infotype", set, maps3, false, false)
			c.JSON(200, gin.H{"rep": b})
		}
	}
}
func RoleMenuData(c *gin.Context) {
	role, _ := c.GetPostForm("role")
	maps := map[string]interface{}{
		"role." + role: true,
	}
	datas, _ := Mgo.Find("menu", maps, nil, nil, false, -1, -1)
	list := []map[string]interface{}{}
	for _, value := range *datas {
		_id := qu.BsonIdToSId(value["_id"])
		maps := map[string]interface{}{
			"menuid": _id,
		}
		count, _ := Mgo.Find("menusecond", maps, nil, nil, false, -1, -1)
		if len(*count) != 0 {
			value["secondmenu"] = true
		} else {
			value["secondmenu"] = false
		}
		list = append(list, value)
	}
	c.JSON(200, gin.H{"data": list})
}
func RoleMenuSave(c *gin.Context) {
	menu, _ := c.GetPostForm("menu")
	secondmenuStr, _ := c.GetPostForm("secondmenuStr")
	secondmenuStr2, _ := c.GetPostForm("secondmenuStr2")
	role, _ := c.GetPostForm("role")
	secondmenus := make([]string, 0)
	secondmenus2 := make([]string, 0)
	err := json.Unmarshal([]byte(secondmenuStr), &secondmenus)
	err2 := json.Unmarshal([]byte(secondmenuStr2), &secondmenus2)
	if err == nil && err2 == nil {
		for _, v := range secondmenus {
			maps := map[string]interface{}{
				"_id": bson.ObjectIdHex(v),
			}
			data := map[string]interface{}{
				"role." + role: true,
			}
			data2 := map[string]interface{}{
				"$set": data,
			}
			Mgo.Update("menusecond", maps, data2, true, false)
		}
		for _, v := range secondmenus2 {
			maps := map[string]interface{}{
				"_id": bson.ObjectIdHex(v),
			}
			data := map[string]interface{}{
				"role." + role: false,
			}
			data2 := map[string]interface{}{
				"$set": data,
			}
			Mgo.Update("menusecond", maps, data2, true, false)
		}
	}
	b := false
	if (len(secondmenus) == 0 && len(secondmenus2) == 0) || (len(secondmenus) > 0) {
		maps := map[string]interface{}{
			"_id": bson.ObjectIdHex(menu),
		}
		data := map[string]interface{}{
			"role." + role: true,
		}
		data2 := map[string]interface{}{
			"$set": data,
		}
		b = Mgo.Update("menu", maps, data2, true, false)
	}
	if len(secondmenus) == 0 && len(secondmenus2) > 0 {
		maps := map[string]interface{}{
			"_id": bson.ObjectIdHex(menu),
		}
		data := map[string]interface{}{
			"role." + role: false,
		}
		data2 := map[string]interface{}{
			"$set": data,
		}
		b = Mgo.Update("menu", maps, data2, true, false)
	}

	c.JSON(200, gin.H{"rep": b})
}
func RoleSelect(c *gin.Context) {
	menuid, _ := c.GetPostForm("_id")
	mark, _ := c.GetPostForm("mark")
	role, _ := c.GetPostForm("role")
	if mark == "" {
		maps := map[string]interface{}{
			"menuid": menuid,
		}
		datas, _ := Mgo.Find("menusecond", maps, nil, nil, false, -1, -1)
		c.JSON(200, gin.H{"data": datas})
	} else {
		maps := map[string]interface{}{
			"menuid":       menuid,
			"role." + role: true,
		}
		data, _ := Mgo.Find("menusecond", maps, nil, nil, false, -1, -1)
		maps2 := map[string]interface{}{
			"menuid":       menuid,
			"role." + role: false,
		}
		names, _ := Mgo.FindById("menu", menuid, `{name:1}`)
		name := *names
		name1 := name["name"]
		data2, _ := Mgo.Find("menusecond", maps2, nil, nil, false, -1, -1)
		c.JSON(200, gin.H{"name": name1, "data": data, "data2": data2})
	}

}

//func RoleSecondMenuData(c *gin.Context) {
//	role, _ := c.GetPostForm("role")
//	_id, _ := c.GetPostForm("_id")
//	maps := map[string]interface{}{
//		"menuid":       _id,
//		"role." + role: true,
//	}
//	datas, _ := Mgo.Find("menusecond", maps, nil, nil, false, -1, -1)

//	c.JSON(200, gin.H{"data": datas})
//}
func Menu(c *gin.Context) {
	session := sessions.Default(c)
	u := session.Get("user").(*map[string]interface{})
	list := front.UserMenu[qu.ObjToString((*u)["email"])]
	c.JSON(200, gin.H{"data": list})
}
func MenuSave(c *gin.Context) {
	name, _ := c.GetPostForm("name")
	href, _ := c.GetPostForm("href")
	pic, _ := c.GetPostForm("pic")
	_id, _ := c.GetPostForm("_id")
	data := map[string]interface{}{}
	if _id == "" {
		data = map[string]interface{}{
			"name": name,
			"href": href,
			"pic":  pic,
			"role": map[string]interface{}{
				"0": false,
				"1": false,
				"2": false,
			},
		}
		b := Mgo.Save("menu", data)
		c.JSON(200, gin.H{"rep": b})
	} else {
		data = map[string]interface{}{
			"name": name,
			"href": href,
			"pic":  pic,
		}
		data2 := map[string]interface{}{
			"$set": data,
		}
		maps := map[string]interface{}{
			"_id": bson.ObjectIdHex(_id),
		}
		b := Mgo.Update("menu", maps, data2, true, false)
		c.JSON(200, gin.H{"rep": b})
	}

}
func SecondMenuSave(c *gin.Context) {
	name, _ := c.GetPostForm("name")
	href, _ := c.GetPostForm("href")
	pic, _ := c.GetPostForm("pic")
	_id, _ := c.GetPostForm("_id")
	menuid, _ := c.GetPostForm("menuid")
	data := map[string]interface{}{}
	if _id == "" {
		data = map[string]interface{}{
			"name":   name,
			"href":   href,
			"pic":    pic,
			"menuid": menuid,
			"role": map[string]interface{}{
				"0": false,
				"1": false,
				"2": false,
			},
		}
		b := Mgo.Save("menusecond", data)
		c.JSON(200, gin.H{"rep": b})
	} else {
		data = map[string]interface{}{
			"name": name,
			"href": href,
			"pic":  pic,
		}
		data2 := map[string]interface{}{
			"$set": data,
		}
		maps := map[string]interface{}{
			"_id": bson.ObjectIdHex(_id),
		}
		b := Mgo.Update("menusecond", maps, data2, true, false)
		c.JSON(200, gin.H{"rep": b})
	}

}
func UserSave(c *gin.Context) {
	email, _ := c.GetPostForm("email")
	pwd, _ := c.GetPostForm("pwd")
	name, _ := c.GetPostForm("name")
	role, _ := c.GetPostForm("role")
	data := map[string]interface{}{
		"email": email,
		"pwd":   Se.EncodeString(pwd),
		"name":  name,
		"role":  role,
		"mtime": time.Now().Unix(),
	}
	b := Mgo.Update("user", `{"email":"`+email+`"}`, data, true, false)
	c.JSON(200, gin.H{"rep": b})
}

func UserSearchById(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	data, _ := Mgo.FindById("user", _id, nil)
	(*data)["pwd"] = Se.DecodeString((*data)["pwd"].(string))
	c.JSON(200, gin.H{"rep": data})
}
func MenuSearchById(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	data, _ := Mgo.FindById("menu", _id, nil)
	c.JSON(200, gin.H{"rep": data})
}
func SecondMenuSearchById(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	data, _ := Mgo.FindById("menusecond", _id, nil)
	c.JSON(200, gin.H{"rep": data})
}

func UserDel(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	b := Mgo.Del("user", `{"_id":"`+_id+`"}`)
	c.JSON(200, gin.H{"rep": b})
}
func MenuDel(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	b := Mgo.Del("menu", `{"_id":"`+_id+`"}`)
	c.JSON(200, gin.H{"rep": b})
}
func SecondMenuDel(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	b := Mgo.Del("menusecond", `{"_id":"`+_id+`"}`)
	c.JSON(200, gin.H{"rep": b})
}
func RoleMenuDel(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	role, _ := c.GetPostForm("role")
	maps := map[string]interface{}{
		"_id": bson.ObjectIdHex(_id),
	}
	data := map[string]interface{}{
		"role." + role: false,
	}
	data2 := map[string]interface{}{
		"$set": data,
	}
	b := Mgo.Update("menu", maps, data2, true, false)
	maps = map[string]interface{}{
		"menuid": _id,
	}
	count, _ := Mgo.Find("menusecond", maps, nil, nil, false, -1, -1)
	if len(*count) != 0 {
		for _, c := range *count {
			maps = map[string]interface{}{
				"_id": c["_id"],
			}
			Mgo.Update("menusecond", maps, data2, true, false)
		}

	}
	c.JSON(200, gin.H{"rep": b})
}

//func RoleSecondMenuDel(c *gin.Context) {
//	_id, _ := c.GetPostForm("_id")
//	role, _ := c.GetPostForm("role")
//	maps := map[string]interface{}{
//		"_id": bson.ObjectIdHex(_id),
//	}
//	data := map[string]interface{}{
//		"role." + role: false,
//	}
//	data2 := map[string]interface{}{
//		"$set": data,
//	}
//	b := Mgo.Update("menusecond", maps, data2, true, false)
//	c.JSON(200, gin.H{"rep": b})
//}
func UserUppwd(c *gin.Context) {
	_id, _ := c.GetPostForm("_id")
	pwd, _ := c.GetPostForm("pwd")
	b := Mgo.UpdateById("user", _id, `{"$set":{"pwd":"`+Se.EncodeString(pwd)+`"}}`)
	c.JSON(200, gin.H{"rep": b})
}
