package fileManager

import (
	"errors"
	"fmt"
	"github.com/qiniu/api.v7/v7/auth/qbox"
	"github.com/qiniu/api.v7/v7/storage"
	"gorm.io/gorm"
	"log-server/global"
	"log-server/model/fileManager"
	"log-server/model/fileManager/request"
	"log-server/model/fileManager/response"
	"strconv"
	"strings"
	"time"
)

type ServiceFileQiniu struct {
}

// 公司七牛信息
const accessKey = "B81Gsvry2StqKVE3txS-7v9GBBfqykC9zhebmxnW" //七牛云ak,sk,bucket
const secretKey = "YEZJuYcdeF7vRvzffxpopAVR-jMPZg9pZ-4IKTVW"
const bucket0 = "pinaishop"
const CName = "http://cdn.pinaishop.kfzs.com/" //七牛云外链

// QueryVersionByType 查询某一类文件最新的版本号
func (s *ServiceFileQiniu) QueryVersionByType(req request.FileQiniuRequest) (int64, error) {
	file := fileManager.FileQiniu{}
	if errors.Is(global.GVA_DB.Model(&fileManager.FileQiniu{}).Where("task_id = ? and file_type = ?", req.TaskId, req.FileType).Order("file_version desc").First(&file).Error, gorm.ErrRecordNotFound) {
		return 0, nil
	}
	return file.FileVersion, nil
}

// AddQiniuFile 新增文件
func (s *ServiceFileQiniu) AddQiniuFile(requestCoding request.FileQiniuRequest) (err error) {
	//查询真实的父文件夹ID
	parentFolder := fileManager.FileFolder{}
	if errors.Is(global.GVA_DB.Where("task_id = ? and name = ?", requestCoding.TaskId, requestCoding.FileTypeName).First(&parentFolder).Error, gorm.ErrRecordNotFound) {
		return errors.New("父文件夹不存在")
	}
	//==================================
	if !errors.Is(global.GVA_DB.Where("parent_id = ? and file_name = ?", requestCoding.ParentId, requestCoding.FileName).First(&fileManager.FileQiniu{}).Error, gorm.ErrRecordNotFound) {
		return errors.New("该目录下已存在同名文件")
	}
	file := new(fileManager.FileQiniu)
	file.ParentId = parentFolder.Id
	file.TaskId = requestCoding.TaskId
	file.FileName = requestCoding.FileName
	file.FileVersion = requestCoding.FileVersion
	file.QiniuAddress = requestCoding.QiniuAddress
	file.QiniuKey = requestCoding.QiniuKey
	file.QiniuHash = requestCoding.QiniuHash
	file.FileType = requestCoding.FileType
	file.CreateTime = time.Now().Format("2006-01-02 15:04:05")
	file.UpdateTime = time.Now().Format("2006-01-02 15:04:05")
	global.GVA_LOG.Warn(requestCoding.MD5)
	global.GVA_LOG.Warn(strconv.Itoa(requestCoding.PushPolicy))
	global.GVA_LOG.Warn(requestCoding.PushTime)
	file.MD5 = requestCoding.MD5
	file.PushPolicy = requestCoding.PushPolicy
	file.PushTime = requestCoding.PushTime
	return global.GVA_DB.Create(&file).Error
}

// QueryFilesByParentId 查询当前目录下的文件
func (s *ServiceFileQiniu) QueryFilesByParentId(parentId int) (interface{}, error) {
	db := global.GVA_DB.Model(&fileManager.FileQiniu{})
	db = db.Where("parent_id = ?", parentId)
	var fileList []*response.FileQiniuResponse
	err := db.Order("create_time desc").Find(&fileList).Error
	if err != nil {
		return nil, err
	}
	return fileList, err
}

// GetMirrorDownloadByTaskId 根据任务id获取最新镜像下载链接
func (s *ServiceFileQiniu) GetMirrorDownloadByTaskId(taskId string) (interface{}, error) {
	//SELECT * FROM file_qiniu WHERE task_id = 1000605 AND (file_type = 2 OR file_type = 4) AND push_policy = 1 ORDER BY file_version DESC LIMIT 1
	db := global.GVA_DB.Model(&fileManager.FileQiniu{})
	db = db.Where("task_id = ? AND (file_type = 2 OR file_type = 4) AND push_policy = 1", taskId)
	file := fileManager.FileQiniu{}
	err := db.Order("file_version desc").First(&file).Error
	if err != nil {
		return nil, err
	}
	qiniuMirrorMessage := new(response.QiniuMirrorMessage)
	qiniuMirrorMessage.TaskId = file.TaskId
	qiniuMirrorMessage.FileName = file.FileName
	qiniuMirrorMessage.FileVersion = file.FileVersion
	qiniuMirrorMessage.QiniuAddress = file.QiniuAddress
	qiniuMirrorMessage.QiniuHash = file.QiniuHash
	qiniuMirrorMessage.MD5 = file.MD5
	//qiniuMirrorMessage.CreateTime = file.CreateTime
	//qiniuMirrorMessage.PushPolicy = file.PushPolicy
	//qiniuMirrorMessage.PushTime = file.PushTime

	return qiniuMirrorMessage, err
}

// CheckPushTime 定时查看延迟更新的镜像是否到期
func (s *ServiceFileQiniu) CheckPushTime() {
	global.GVA_LOG.Info("定时查看延迟更新的镜像是否到期开始执行:" + time.Now().Format("2006-01-02 15:04:05"))
	db := global.GVA_DB.Model(&fileManager.FileQiniu{})
	db = db.Where("(file_type = 2 OR file_type = 4) AND push_policy = 2")
	db = db.Where("push_time >= ?", time.Now().Format("2006-01-02 15:04:05"))
	db.Update("push_policy", 1)
	global.GVA_LOG.Info("定时查看延迟更新的镜像是否到期执行成功:" + time.Now().Format("2006-01-02 15:04:05"))
	return
}

// GetQiniuToken 获取七牛上传token
func (s *ServiceFileQiniu) GetQiniuToken() interface{} {
	putPolicy := storage.PutPolicy{
		Scope:      bucket0,
		ReturnBody: `{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}`,
	}
	putPolicy.Expires = 3600 * 5 //设置有效期时长为5小时
	mac := qbox.NewMac(accessKey, secretKey)
	uploadToken := putPolicy.UploadToken(mac)
	date := map[string]string{
		"token": uploadToken,
		"cName": CName,
	}
	return date
}

// DeleteQiniuFile 删除单个文件
func (s *ServiceFileQiniu) DeleteQiniuFile(requestCoding request.FileQiniuRequest) (err error) {
	mac := qbox.NewMac(accessKey, secretKey)
	cfg := storage.Config{
		// 是否使用https域名进行资源管理
		UseHTTPS: true,
	}
	// 指定空间所在的区域，如果不指定将自动探测
	// 如果没有特殊需求，默认不需要指定
	//cfg.Region=&storage.ZoneHuabei
	bucketManager := storage.NewBucketManager(mac, &cfg)
	bucket := bucket0
	key := requestCoding.QiniuKey
	//
	err = bucketManager.Delete(bucket, key)
	if err != nil {
		fmt.Println(err)
		return err
	}
	return err
}

// DeleteQiniuFileAndRecord 从七牛云删除文件并且清除数据库记录
func (s *ServiceFileQiniu) DeleteQiniuFileAndRecord(requestCoding request.FileQiniuRequest) (err error) {
	mac := qbox.NewMac(accessKey, secretKey)
	cfg := storage.Config{
		// 是否使用https域名进行资源管理
		UseHTTPS: true,
	}
	// 指定空间所在的区域，如果不指定将自动探测
	// 如果没有特殊需求，默认不需要指定
	//cfg.Region=&storage.ZoneHuabei
	bucketManager := storage.NewBucketManager(mac, &cfg)
	bucket := bucket0
	key := requestCoding.QiniuKey
	//
	err = bucketManager.Delete(bucket, key)
	if err != nil {
		fmt.Println(err)
		return err
	}
	err = global.GVA_DB.Delete(&fileManager.FileQiniu{}, "id = ?", requestCoding.Id).Error
	return err
}

// RenameQiniuFileAndRecord 重命名七牛云文件和数据库记录
func (s *ServiceFileQiniu) RenameQiniuFileAndRecord(requestCoding request.FileQiniuRequest) (err error) {
	file := fileManager.FileQiniu{}
	if errors.Is(global.GVA_DB.Where("id = ?", requestCoding.Id).First(&file).Error, gorm.ErrRecordNotFound) {
		return errors.New("数据库中未找到该记录")
	}
	mac := qbox.NewMac(accessKey, secretKey)
	cfg := storage.Config{
		// 是否使用https域名进行资源管理
		UseHTTPS: true,
	}
	bucketManager := storage.NewBucketManager(mac, &cfg)
	bucket := bucket0
	srcKey := requestCoding.QiniuKey
	//处理字段
	s2 := file.QiniuKey[0:strings.Index(file.QiniuKey, file.FileName)]
	//global.GVA_LOG.Info(s2)
	destKey := s2 + requestCoding.FileNameNew
	//如果目标文件存在，是否强制覆盖，如果不覆盖，默认返回614 file exists
	err = bucketManager.Move(bucket, srcKey, bucket, destKey, false)
	if err != nil {
		return err
	}
	s3 := file.QiniuAddress[0:strings.Index(file.QiniuAddress, file.FileName)]
	file.QiniuAddress = s3 + requestCoding.FileNameNew
	file.FileName = requestCoding.FileNameNew
	file.QiniuKey = destKey
	err = global.GVA_DB.Save(file).Error
	return err
}

// UpdateMirrorPushPolicy 修改镜像更新策略
func (s *ServiceFileQiniu) UpdateMirrorPushPolicy(requestCoding request.FileQiniuRequest) (err error) {
	file := fileManager.FileQiniu{}
	if errors.Is(global.GVA_DB.Where("id = ?", requestCoding.Id).First(&file).Error, gorm.ErrRecordNotFound) {
		return errors.New("数据库中未找到该记录")
	}
	file.PushPolicy = requestCoding.PushPolicy
	file.PushTime = requestCoding.PushTime
	err = global.GVA_DB.Save(file).Error
	return err
}
