package models

import (
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"eta/eta_api/utils"
	"strings"
	"time"
)

// 文件格式图标
const (
	CloudDiskResourceFileTypeIconMenu    = "https://hzstatic.hzinsights.com/static/icon/file_type_menu.png"
	CloudDiskResourceFileTypeIconUnknown = "https://hzstatic.hzinsights.com/static/icon/file_type_unknown.png"
)

type CloudDiskResource struct {
	ResourceId     int       `orm:"column(resource_id);pk" description:"资源ID"`
	MenuId         int       `description:"目录ID"`
	ResourceName   string    `description:"文件名"`
	ResourceSuffix string    `description:"文件后缀名"`
	ResourceUrl    string    `description:"文件地址"`
	ResourceIcon   string    `description:"文件类型图标"`
	AdminId        int       `description:"创建人ID"`
	AdminName      string    `description:"创建人名称"`
	Size           int64     `description:"目录大小"`
	CreateTime     time.Time `description:"创建时间"`
	ModifyTime     time.Time `description:"修改时间"`
}

func (m *CloudDiskResource) TableName() string {
	return "cloud_disk_resource"
}

func (m *CloudDiskResource) Create() (err error) {
	o := orm.NewOrm()
	id, err := o.Insert(m)
	if err != nil {
		return
	}
	m.ResourceId = int(id)
	return
}

func (m *CloudDiskResource) Update(cols []string) (err error) {
	o := orm.NewOrm()
	_, err = o.Update(m, cols...)
	return
}

func (m *CloudDiskResource) Delete() (err error) {
	o := orm.NewOrm()
	sql := `DELETE FROM cloud_disk_resource WHERE resource_id = ? LIMIT 1`
	_, err = o.Raw(sql, m.ResourceId).Exec()
	return
}

func (m *CloudDiskResource) GetItemById(id int) (err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE resource_id = ? LIMIT 1`, m.TableName())
	err = o.Raw(sql, id).QueryRow(&m)
	return
}

func (m *CloudDiskResource) GetItemByCondition(condition string, pars []interface{}) (err error) {
	o := orm.NewOrm()
	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s LIMIT 1`, m.TableName(), condition)
	err = o.Raw(sql, pars).QueryRow(&m)
	return
}

func (m *CloudDiskResource) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*CloudDiskResource, err error) {
	o := orm.NewOrm()
	fields := strings.Join(fieldArr, ",")
	if len(fieldArr) == 0 {
		fields = `*`
	}
	order := ``
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
	_, err = o.Raw(sql, pars).QueryRows(&items)
	return
}

// CloudDiskCheckResourceRepeatReq 校验文件重名请求体
type CloudDiskCheckResourceRepeatReq struct {
	MenuId    int      `description:"目录ID"`
	FileNames []string `description:"文件名"`
}

// CloudDiskCheckResourceRepeatResp 校验文件重名响应体
type CloudDiskCheckResourceRepeatResp struct {
	OriginName    string `description:"原文件名(包含后缀名)"`
	IsRepeat      bool   `description:"是否重复"`
	AvailableName string `description:"可用名"`
}

// CloudDiskResourceRenameReq 重命名文件请求体
type CloudDiskResourceRenameReq struct {
	ResourceId   int    `description:"文件ID"`
	ResourceName string `description:"文件名称"`
}

// CloudDiskResourceDeleteReq 删除文件请求体
type CloudDiskResourceDeleteReq struct {
	ResourceId int `description:"文件ID"`
}

// CloudDiskListResp 云盘列表响应体
type CloudDiskListResp struct {
	List               []*CloudDiskListItem         `description:"列表数据"`
	CreateMenuAuth     bool                         `description:"新建文件夹权限"`
	UploadResourceAuth bool                         `description:"上传文件的权限"`
	BatchDelAuth       bool                         `description:"批量删除目录/文件的权限(仅管理员有)"`
	ListPath           []*CloudDiskMenuResourcePath `description:"面包屑"`
}

// CloudDiskListItem 云盘列表数据
type CloudDiskListItem struct {
	ItemId      int                  `description:"ID"`
	ItemName    string               `description:"名称"`
	ItemType    int                  `description:"类型: 1-目录; 2-文件"`
	ParentId    int                  `description:"父级目录ID"`
	ParentName  string               `description:"父级目录文件名"`
	Size        int64                `description:"大小"`
	SizeName    string               `description:"目录/文件大小(格式化)"`
	ResourceUrl string               `description:"文件地址"`
	ItemIcon    string               `description:"图标"`
	AdminId     int                  `description:"创建人ID"`
	AdminName   string               `description:"创建人"`
	CreateTime  string               `description:"创建时间"`
	ButtonAuth  *CloudDiskListButton `description:"按钮权限"`
}

// CloudDiskListButton 云盘列表按钮权限
type CloudDiskListButton struct {
	RenameAuth bool `description:"重命名文件夹的权限"`
	DelAuth    bool `description:"删除文件夹的权限"`
}

// CloudDiskMenuResourcePath 云盘目录/文件面包屑
type CloudDiskMenuResourcePath struct {
	MenuId   int    `description:"目录ID"`
	MenuName string `description:"目录名称"`
	ParentId int    `description:"父级目录ID"`
	Sort     int    `description:"排序"`
	Selected bool   `description:"是否选中"`
}

// GetCloudDiskMenuAndResourceList UNION获取云盘列表数据
func GetCloudDiskMenuAndResourceList(menuCond, resourceCond string, menuPars, resourcePars []interface{}, orderRule string) (items []*CloudDiskListItem, err error) {
	o := orm.NewOrm()
	base := `SELECT menu_id AS item_id, menu_name AS item_name, 1 AS item_type, parent_id, size, "" AS resource_url, "" AS item_icon, admin_id, admin_name, create_time FROM cloud_disk_menu
			WHERE 1=1 %s
			UNION
			SELECT resource_id, CONCAT(resource_name,resource_suffix), 2, menu_id, size, resource_url, resource_icon, admin_id, admin_name, create_time FROM cloud_disk_resource
			WHERE 1=1 %s %s`
	order := ` ORDER BY item_type ASC `
	if orderRule != "" {
		order = ` ORDER BY ` + orderRule
	}
	sql := fmt.Sprintf(base, menuCond, resourceCond, order)
	_, err = o.Raw(sql, menuPars, resourcePars).QueryRows(&items)
	return
}

// GetSizeTotalByMenuIds 获取目录所属文件总大小
func GetSizeTotalByMenuIds(menuIds []int) (sizeTotal int64, err error) {
	if len(menuIds) == 0 {
		return
	}
	o := orm.NewOrm()
	sql := `SELECT SUM(size) FROM cloud_disk_resource WHERE menu_id IN (` + utils.GetOrmInReplace(len(menuIds)) + `)`
	err = o.Raw(sql, menuIds).QueryRow(&sizeTotal)
	return
}

// CloudDiskBatchDeleteReq 批量删除请求体
type CloudDiskBatchDeleteReq struct {
	MenuId      int    `description:"当前目录ID"`
	MenuIds     string `description:"目录IDs"`
	ResourceIds string `description:"文件IDs"`
}

// BatchDeleteCloudDiskMenuAndResource 批量删除目录及文件
func BatchDeleteCloudDiskMenuAndResource(menuIds, resourceIds []int) (err error) {
	menuLens := len(menuIds)
	resourceLens := len(resourceIds)
	if menuLens == 0 && resourceLens == 0 {
		return
	}

	o := orm.NewOrm()
	tx, err := o.Begin()
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
		} else {
			_ = tx.Commit()
		}
	}()

	if menuLens > 0 {
		sql := `DELETE FROM cloud_disk_menu WHERE menu_id IN (` + utils.GetOrmInReplace(menuLens) + `)`
		if _, err = tx.Raw(sql, menuIds).Exec(); err != nil {
			return
		}
		sql = `DELETE FROM cloud_disk_resource WHERE menu_id IN (` + utils.GetOrmInReplace(menuLens) + `)`
		if _, err = tx.Raw(sql, menuIds).Exec(); err != nil {
			return
		}
	}
	if resourceLens > 0 {
		sql := `DELETE FROM cloud_disk_resource WHERE resource_id IN (` + utils.GetOrmInReplace(resourceLens) + `)`
		if _, err = tx.Raw(sql, resourceIds).Exec(); err != nil {
			return
		}
	}
	return
}