package upload

import (
	"context"
	"mime/multipart"
	"path"

	"github.com/qiniu/go-sdk/v7/auth/qbox"
	"github.com/qiniu/go-sdk/v7/storage"
)

// Qiniu 七牛云
type Qiniu struct {
	Zone          string
	Bucket        string
	ImgPath       string
	AccessKey     string
	SecretKey     string
	UseHTTPS      bool
	UseCdnDomains bool
}

// NewQiniu 创建七牛云
func NewQiniu(zone, bucket, imgPath, accessKey, secretKey string, useHTTPS, useCdnDomains bool) *Qiniu {
	return &Qiniu{
		Zone:          zone,
		Bucket:        bucket,
		ImgPath:       imgPath,
		AccessKey:     accessKey,
		SecretKey:     secretKey,
		UseHTTPS:      useHTTPS,
		UseCdnDomains: useCdnDomains,
	}
}

func (q *Qiniu) getZone() *storage.Region {
	switch q.Zone {
	case "ZoneHuadong":
		return &storage.ZoneHuadong
	case "ZoneHuabei":
		return &storage.ZoneHuabei
	case "ZoneHuanan":
		return &storage.ZoneHuanan
	case "ZoneBeimei":
		return &storage.ZoneBeimei
	case "ZoneXinjiapo":
		return &storage.ZoneXinjiapo
	default:
		return &storage.ZoneHuadong
	}
}

// UploadFile 上传文件
func (q *Qiniu) UploadFile(file *multipart.FileHeader) (string, string, error) {
	mac := qbox.NewMac(q.AccessKey, q.SecretKey)
	putPolicy := storage.PutPolicy{Scope: q.Bucket}
	upToken := putPolicy.UploadToken(mac)

	cfg := storage.Config{
		Zone:          q.getZone(),
		UseHTTPS:      q.UseHTTPS,
		UseCdnDomains: q.UseCdnDomains,
	}
	formUploader := storage.NewFormUploader(&cfg)

	// 生成文件名和路径
	fileName := GenerateFileName(file.Filename)
	filePath := GeneratePath("")
	key := path.Join(filePath, fileName)

	// 打开文件
	src, err := file.Open()
	if err != nil {
		return "", "", err
	}
	defer src.Close()

	// 上传
	ret := storage.PutRet{}
	err = formUploader.Put(context.Background(), &ret, upToken, key, src, file.Size, nil)
	if err != nil {
		return "", "", err
	}

	// 返回访问URL和key
	accessURL := q.ImgPath + "/" + key
	return accessURL, key, nil
}

// DeleteFile 删除文件
func (q *Qiniu) DeleteFile(key string) error {
	mac := qbox.NewMac(q.AccessKey, q.SecretKey)
	cfg := storage.Config{Zone: q.getZone()}
	bucketManager := storage.NewBucketManager(mac, &cfg)
	return bucketManager.Delete(q.Bucket, key)
}
