package minio

import (
	"bytes"
	"context"
	"crypto/md5"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"gitee.ltd/lxh/wechat-robot/internal/config"
	"github.com/gofiber/fiber/v2/log"
	"github.com/minio/minio-go/v7"
	"net/http"
	"strings"
	"time"
)

// SaveBytes
// @description: 保存文件到OSS
// @param b
// @param md5
// @param suffix
// @return url
// @return err
func SaveBytes(b []byte, md5 string, suffix ...string) (url string, err error) {
	cfg, err := config.Load()
	if err != nil {
		log.Errorf("加载配置失败: %s", err.Error())
		return
	}

	ctx := context.Background()
	contentType := http.DetectContentType(b)
	if strings.Contains(contentType, ";") {
		contentType = contentType[:strings.Index(contentType, ";")]
	}
	// 重新设置文件名
	suf := ""
	if len(suffix) == 0 {
		suf = contentType[strings.Index(contentType, "/")+1:]
	} else {
		suf = suffix[0]
	}
	today := time.Now().Local().Format("2006/01/02")
	fileName := fmt.Sprintf("%s/%s/%s", contentType, today, md5)
	if suf != "" {
		fileName = fmt.Sprintf("%s.%s", fileName, suf)
	}
	log.Debugf("开始上传文件: %v", fileName)
	reader := bytes.NewBuffer(b)
	_, err = minioClient.PutObject(ctx, cfg.Minio.BucketName, fileName, reader, -1, minio.PutObjectOptions{ContentType: contentType})
	if err != nil {
		log.Errorf("文件上传错误: %v", err)
		return "", err
	}
	log.Debugf("文件上传完毕: %v", fileName)
	protocol := "http"
	if cfg.Minio.UseSsl {
		protocol = "https"
	}
	url = fmt.Sprintf("%s://%s/%s/%s", protocol, cfg.Minio.Host, cfg.Minio.BucketName, fileName)
	// 异步数据入库
	//go func() {
	//	wf := db.WeChatFileEntity{Url: fileUrl, HashCode: md5, FileType: contentType}
	//	if err = wf.Save(); err != nil {
	//		log.Errorf("文件资源信息保存入库失败: %v", err)
	//	}
	//}()
	return
}

// SaveBase64
// @description: 保存Base64字符串到OSS
// @param bs53Str
// @param md5Str
// @param suffix
// @return url
// @return err
func SaveBase64(bs64Str string, md5Str string, suffix ...string) (url string, err error) {
	bs64Bytes, err := base64.StdEncoding.DecodeString(bs64Str) // 解密base64字符串
	if err != nil {
		log.Errorf("解密失败: %v", err)
		return
	}

	// 如果md5为空，计算一下
	if md5Str == "" {
		hasher := md5.New()
		if _, err = hasher.Write(bs64Bytes); err != nil {
			log.Errorf("计算md5失败: %v", err)
			return
		}
		md5Str = hex.EncodeToString(hasher.Sum(nil))
		//log.Debugf("计算出的md5: %v", md5Str)
	}

	return SaveBytes(bs64Bytes, md5Str, suffix...)
}
