package fileLocal

import (
	"bytes"
	"encoding/json"
	"epur-pay/pkg/logger"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"reflect"
	"time"
)

type Local struct {
	AccessKeyId     string
	AccessKeySecret string
	BucketName      string
	EndPoint        string
	Access          string
	RegionId        string
}

type ReturnUpload struct {
	Code    int64  `json:"code"`
	Message string `json:"message"`
	Data    struct {
		FileUrl string `json:"fileUrl"`
	} `json:"data"`
}

func New(accessKeyId, accessKeySecret, bucketName, endPoint string, access string, regionId string) (*Local, error) {
	instance := &Local{
		AccessKeyId:     accessKeyId,
		AccessKeySecret: accessKeySecret,
		BucketName:      bucketName,
		EndPoint:        endPoint,
		Access:          access,
		RegionId:        regionId,
	}
	return instance, nil
}

func (this *Local) ReadUrl(filePath string) string {
	return this.url(filePath)
}

func (this *Local) url(fileName string) string {
	return fmt.Sprintf("http://%s/%s", this.Access, fileName)
}

func (this *Local) Put(fileName string, contentType string, data interface{}) string {
	var ossData io.Reader
	typeOf := reflect.TypeOf(data).Kind()
	switch typeOf {
	case reflect.Slice:
		ossData = bytes.NewBuffer(data.([]byte))
	case reflect.Struct:
		ossData = data.(io.Reader)
	case reflect.Ptr:
		a1 := reflect.ValueOf(data).Interface()
		d := a1.([]uint8)
		ossData = bytes.NewBuffer(d)
	default:
		panic("数据不合法--!")
	}

	var buffer bytes.Buffer
	writer := multipart.NewWriter(&buffer)
	writer.WriteField("path", "test/file")
	// 创建一个新的表单文件字段,并将文件内容的io.Reader传递给它
	fileField, err := writer.CreateFormFile("file", fileName)
	if err != nil {
		fmt.Println("创建表单文件字段时出错:", err)
		return ""
	}
	// 将文件内容的io.Reader复制到表单文件字段中
	_, err = io.Copy(fileField, ossData)
	if err != nil {
		fmt.Println("复制文件内容时出错:", err)
		return ""
	}
	// 关闭multipart写入器以完成请求
	writer.Close()

	request, err := http.NewRequest(http.MethodPost, fmt.Sprintf("http://%s", this.EndPoint), &buffer)
	if err != nil {
		logger.AccessLogger.Errorf("---> local upload request fail. %s", err.Error())
		return ""
	}
	request.Header.Set("Content-Type", writer.FormDataContentType())

	client := http.Client{Timeout: 5 * time.Second}
	response, errs := client.Do(request)
	if errs != nil {
		logger.AccessLogger.Errorf("---> local upload fail. %s", errs.Error())
		return ""
	}

	if response.StatusCode == 200 {
		result := ReturnUpload{}
		bodyBuffer := new(bytes.Buffer)
		_, err = bodyBuffer.ReadFrom(response.Body)

		logger.AccessLogger.Errorf("----> %s", bodyBuffer.String())
		if err != nil {
			logger.AccessLogger.Errorf("---> local upload fail. %s", errs.Error())
			return ""
		}

		if err1 := json.Unmarshal([]byte(bodyBuffer.String()), &result); err1 != nil {
			panic(result.Message)
		}

		if result.Code == 200 {
			return result.Data.FileUrl
		}
	}
	defer response.Body.Close()

	return ""
}

// 获取直传token
func (this *Local) Token(key string, contentType string) (map[string]interface{}, error) {
	token := make(map[string]interface{})
	token["host"] = fmt.Sprintf("http://%s", this.EndPoint)
	token["directory"] = "pic"

	return token, nil
}