package oss_core

import (
	"context"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"net/url"
	"path/filepath"
	"strings"
	"time"

	"github.com/tencentyun/cos-go-sdk-v5"
	"sundynix-micro-go/app/file/rpc/file"
	"sundynix-micro-go/common/utils/hash"
)

type TencentUploader struct {
	client *cos.Client
	config *file.StorageConfigInfo
}

func NewTencentUploader(conf *file.StorageConfigInfo) (Uploader, error) {
	// Endpoint should be something like https://bucket-appid.cos.ap-guangzhou.myqcloud.com
	// But usually users just put bucket name and region, here we assume endpoint is full bucket url
	// Or we use bucketUrl as the endpoint for client initialization if endpoint is not formatted well
	u, err := url.Parse(conf.Endpoint)
	if err != nil {
		return nil, fmt.Errorf("解析Endpoint失败: %v", err)
	}

	b := &cos.BaseURL{BucketURL: u}
	client := cos.NewClient(b, &http.Client{
		Transport: &cos.AuthorizationTransport{
			SecretID:  conf.AccessKeyId,
			SecretKey: conf.AccessKeySecret,
		},
	})

	return &TencentUploader{
		client: client,
		config: conf,
	}, nil
}

func (t *TencentUploader) UploadFile(ctx context.Context, file multipart.File, fileHeader *multipart.FileHeader) (string, string, error) {
	ext := filepath.Ext(fileHeader.Filename)
	filename := hash.MD5([]byte(strings.TrimSuffix(fileHeader.Filename, ext))) + ext
	timestr := fmt.Sprintf("%d", time.Now().UnixMicro())
	objectKey := time.Now().Format("2006-01-02") + "/" + timestr + "-" + filename

	_, err := t.client.Object.Put(ctx, objectKey, file, nil)
	if err != nil {
		return "", "", fmt.Errorf("上传腾讯云COS失败: %v", err)
	}

	fileUrl := t.config.BucketUrl + "/" + objectKey
	return fileUrl, objectKey, nil
}

func (t *TencentUploader) DeleteFile(ctx context.Context, key string) error {
	_, err := t.client.Object.Delete(ctx, key)
	return err
}

func (t *TencentUploader) DownloadFile(ctx context.Context, key string) (io.ReadCloser, error) {
	resp, err := t.client.Object.Get(ctx, key, nil)
	if err != nil {
		return nil, err
	}
	return resp.Body, nil
}
