package utils

import (
	"bytes"
	"encoding/base64"
	"net/http"
	"strings"
	"time"

	"github.com/yl10/kit/guid"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

// GetOssClient 获取 OSS 客户端
func GetOssClient(endpoint, accessKeyID, accessKeySecret string) (*oss.Client, error) {
	return oss.New(endpoint, accessKeyID, accessKeySecret)
}

// UploadFileToBucket 简单上传文件
func UploadFileToBucket(cli *oss.Client, req *http.Request, bucket, fromFront string, nameSuffix ...string) (string, error) {
	bkt, err := cli.Bucket(bucket)
	if err != nil {
		return "", err
	}

	file, fh, err := req.FormFile(fromFront)
	if err != nil {
		return "", err
	}
	defer file.Close()

	fname := fh.Filename
	if len(nameSuffix) > 0 && nameSuffix[0] != "" {
		fArr := strings.Split(fname, ".")
		fArr[0] = fArr[0] + nameSuffix[0]
		fname = strings.Join(fArr, ".")
	}

	err = bkt.PutObject(fname, file)
	if err != nil {
		return "", err
	}

	return strings.Join([]string{
		"http://",
		bucket + ".",
		cli.Config.Endpoint + "/",
		fname,
	}, ""), nil
}

// UploadStringToBucket 上传base64图片
func UploadStringToBucket(cli *oss.Client, bucket, fromStr string) (string, error) {
	bkt, err := cli.Bucket(bucket)
	if err != nil {
		return "", err
	}

	imgName := guid.NewGUIDString() + "-" + time.Now().Local().Format("20060102150405")
	imgExt := ".jpg"
	switch getMIMEFromBase64(fromStr) {
	case "image/gif":
		imgExt = ".gif"
	case "image/bmp":
		imgExt = ".bmp"
	case "image/png", "image/x-png":
		imgExt = ".png"
	case "image/pipeg":
		imgExt = ".jfif"
	case "image/webp":
		imgExt = ".webp"
	}

	fName := imgName + imgExt

	imgData, err := base64.StdEncoding.DecodeString(strings.Split(fromStr, "base64,")[1])
	if err != nil {
		return "", err
	}

	err = bkt.PutObject(fName, bytes.NewBuffer(imgData))
	if err != nil {
		return "", err
	}

	return strings.Join([]string{
		"http://",
		bucket + ".",
		cli.Config.Endpoint + "/",
		fName,
	}, ""), nil
}

// utils
// getMIMEFromBase64 获取 base64 字串中的 mime
func getMIMEFromBase64(str string) string {
	g := strings.Split(str, ";")
	if len(g) < 2 {
		return ""
	}

	return strings.ToLower(strings.TrimLeft(g[0], "data:"))
}
