package services

import (
	"eta/eta_api/models"
	"eta/eta_api/models/company"
	"eta/eta_api/utils"
	"fmt"
	"sort"
	"strings"
	"time"
)

// CheckCloudDiskManagerAuth 校验云盘管理员权限
func CheckCloudDiskManagerAuth(roleCode string) (ok bool, err error) {
	confKey := "cloud_disk_manager_role"
	conf, e := company.GetConfigDetailByCode(confKey)
	if e != nil {
		err = fmt.Errorf("获取管理员权限配置失败, Err: %s", e.Error())
		return
	}
	if conf.ConfigValue == "" {
		err = fmt.Errorf("管理员权限配置信息有误")
		return
	}
	authArr := strings.Split(conf.ConfigValue, ",")
	if utils.InArrayByStr(authArr, roleCode) {
		ok = true
	}
	return
}

// GetCloudDiskMenuIdsByParentId 云盘目录-通过父级ID获取所有子ID
func GetCloudDiskMenuIdsByParentId(menuId int) (menuIds []int, err error) {
	menuOB := new(models.CloudDiskMenu)
	menuCond := ``
	menuPars := make([]interface{}, 0)
	menuFields := []string{"menu_id", "parent_id"}
	menus, e := menuOB.GetItemsByCondition(menuCond, menuPars, menuFields, "")
	if e != nil {
		err = fmt.Errorf("获取目录列表失败, Err: %s", e.Error())
		return
	}
	// 若父级ID为0, 取全部
	if menuId == 0 {
		for i := range menus {
			menuIds = append(menuIds, menus[i].MenuId)
		}
		return
	}
	// 父级ID大于0
	menuIds = loadChildrenIds(menuId, menus)
	return
}

// loadChildrenIds 递归遍历出子分类ID
func loadChildrenIds(parentId int, menus []*models.CloudDiskMenu) []int {
	menuIds := make([]int, 0)
	for i := range menus {
		if parentId == menus[i].ParentId {
			childIds := loadChildrenIds(menus[i].MenuId, menus)
			menuIds = append(menuIds, menus[i].MenuId)
			menuIds = append(menuIds, childIds...)
		}
	}
	return menuIds
}

// GetCloudDiskMenuTree 云盘-获取目录分类树
func GetCloudDiskMenuTree() (list []*models.CloudDiskMenuTree, err error) {
	menuOB := new(models.CloudDiskMenu)
	menuCond := ``
	menuPars := make([]interface{}, 0)
	menus, e := menuOB.GetItemsByCondition(menuCond, menuPars, []string{}, "create_time DESC")
	if e != nil {
		err = fmt.Errorf("获取目录列表失败, Err: %s", e.Error())
		return
	}

	list = make([]*models.CloudDiskMenuTree, 0)
	for i := range menus {
		if menus[i].ParentId == 0 {
			v := new(models.CloudDiskMenuTree)
			v.CloudDiskMenu = menus[i]
			v.Children = loadMenuTree(menus[i].MenuId, menus, v)
			list = append(list, v)
		}
	}
	return
}

// loadMenuTree 递归加载分类树
func loadMenuTree(parentId int, menus []*models.CloudDiskMenu, parentItem *models.CloudDiskMenuTree) (children []*models.CloudDiskMenuTree) {
	children = make([]*models.CloudDiskMenuTree, 0)
	for i := range menus {
		if parentId == menus[i].ParentId {
			v := new(models.CloudDiskMenuTree)
			v.CloudDiskMenu = menus[i]
			v.Children = loadMenuTree(menus[i].MenuId, menus, v)
			children = append(children, v)
		}
	}
	parentItem.Children = children
	return
}

// CheckFileNameFormFiles 校验文件名并返回可用名
func CheckFileNameFormFiles(originName, fileName string, fileList []*models.CloudDiskResource, num int) (isRepeat bool, availableName string) {
	if originName == "" || !strings.Contains(originName, ".") {
		return
	}
	// 从原名称中取出文件名和格式
	extIndex := strings.LastIndex(originName, ".")
	name := originName[:extIndex]
	ext := originName[extIndex:]
	if fileName == "" {
		fileName = name
	}
	availableName = fileName + ext
	for i := range fileList {
		if fileName == fileList[i].ResourceName {
			fileName = fmt.Sprintf("%s(%d)", name, num+1)
			isRepeat, availableName = CheckFileNameFormFiles(originName, fileName, fileList, num+1)
			isRepeat = true
		}
	}
	return
}

// GetCloudDiskResourceFileTypeExtMap 常见文件类型图标
func GetCloudDiskResourceFileTypeExtMap() map[string]string {
	return map[string]string{
		".doc":  "https://hzstatic.hzinsights.com/static/icon/file_type_docx.png",
		".docx": "https://hzstatic.hzinsights.com/static/icon/file_type_docx.png",

		".pdf": "https://hzstatic.hzinsights.com/static/icon/file_type_pdf.png",

		".ppt":  "https://hzstatic.hzinsights.com/static/icon/file_type_ppt.png",
		".pptx": "https://hzstatic.hzinsights.com/static/icon/file_type_ppt.png",

		".xls":  "https://hzstatic.hzinsights.com/static/icon/file_type_xlsx.png",
		".xlsx": "https://hzstatic.hzinsights.com/static/icon/file_type_xlsx.png",

		".jpg":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
		".jpeg": "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
		".png":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
		".bmp":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
		".svg":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",
		".gif":  "https://hzstatic.hzinsights.com/static/icon/file_type_pic.png",

		".mp4":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
		".wmv":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
		".mov":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
		".mpeg": "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
		".avi":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
		".flv":  "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
		".rm":   "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",
		".rmvb": "https://hzstatic.hzinsights.com/static/icon/file_type_video.png",

		".mp3": "https://hzstatic.hzinsights.com/static/icon/file_type_audio.png",
		".wma": "https://hzstatic.hzinsights.com/static/icon/file_type_audio.png",
	}
}

// UpdateCloudDiskMenuSize 更新目录大小
func UpdateCloudDiskMenuSize(menuId int) (err error) {
	if menuId <= 0 {
		return
	}
	menuItem := new(models.CloudDiskMenu)
	if e := menuItem.GetItemById(menuId); e != nil {
		err = fmt.Errorf("获取目录失败, Err: %s", e.Error())
		return
	}

	// 获取目录所属文件总大小
	menuIds := make([]int, 0)
	menuIds = append(menuIds, menuId)
	childrenIds, e := GetCloudDiskMenuIdsByParentId(menuId)
	if e != nil {
		err = fmt.Errorf("获取目录子目录IDs失败, Err: %s", e.Error())
		return
	}
	menuIds = append(menuIds, childrenIds...)
	sizeTotal, e := models.GetSizeTotalByMenuIds(menuIds)
	if e != nil {
		err = fmt.Errorf("获取目录所属文件大小失败失败, Err: %s", e.Error())
		return
	}

	// 更新
	menuItem.Size = sizeTotal
	menuItem.ModifyTime = time.Now().Local()
	if e = menuItem.Update([]string{"Size", "ModifyTime"}); e != nil {
		err = fmt.Errorf("更新目录大小失败, Err: %s", e.Error())
		return
	}
	if menuItem.ParentId > 0 {
		err = UpdateCloudDiskMenuSize(menuItem.ParentId)
	}
	return
}

// GetCloudDiskMenuOrResourcePath 获取目录/文件面包屑
func GetCloudDiskMenuOrResourcePath(menuId, level int, menuMap map[int]*models.CloudDiskMenu, originMenu *models.CloudDiskMenu, pathArr []*models.CloudDiskMenuResourcePath) []*models.CloudDiskMenuResourcePath {
	if menuId == 0 || len(menuMap) == 0 || originMenu == nil {
		return nil
	}
	if level == 0 {
		level = 99
	}
	menuItem := menuMap[menuId]
	if menuItem.ParentId > 0 {
		parentItem := menuMap[menuItem.ParentId]
		if parentItem != nil {
			level -= 1
			pathArr = append(pathArr, &models.CloudDiskMenuResourcePath{
				MenuId:   parentItem.MenuId,
				MenuName: parentItem.MenuName,
				ParentId: parentItem.ParentId,
				Sort:     level,
				Selected: false,
			})
			if parentItem.ParentId > 0 {
				pathArr = GetCloudDiskMenuOrResourcePath(parentItem.MenuId, level-1, menuMap, originMenu, pathArr)
			} else {
				pathArr = append(pathArr, &models.CloudDiskMenuResourcePath{
					MenuId:   originMenu.MenuId,
					MenuName: originMenu.MenuName,
					ParentId: originMenu.ParentId,
					Sort:     99,
					Selected: true,
				})
			}
		}
	} else {
		pathArr = append(pathArr, &models.CloudDiskMenuResourcePath{
			MenuId:   originMenu.MenuId,
			MenuName: originMenu.MenuName,
			ParentId: originMenu.ParentId,
			Sort:     99,
			Selected: true,
		})
	}
	sort.Slice(pathArr, func(k, j int) bool {
		return pathArr[k].Sort < pathArr[j].Sort
	})
	return pathArr
}

// FillMenuPath2File 完善文件的完整路径
func FillMenuPath2File(originMenuId, menuId int, resourcePath string, menuMap map[int]*models.CloudDiskMenu) string {
	if menuId == 0 {
		return resourcePath
	}
	menuItem := menuMap[menuId]
	if menuItem == nil {
		return resourcePath
	}
	// 若文件就在当前目录是不需要加目录路径的, 仅多级才需要加
	if menuItem.ParentId > 0 {
		resourcePath = fmt.Sprintf("%s/%s", menuItem.MenuName, resourcePath)
		resourcePath = FillMenuPath2File(originMenuId, menuItem.ParentId, resourcePath, menuMap)
	}
	return resourcePath
}
