package upload

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

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/credentials"
	"github.com/aws/aws-sdk-go-v2/service/s3"
)

// CloudflareR2 Cloudflare R2存储
type CloudflareR2 struct {
	Bucket          string
	BaseURL         string
	Path            string
	AccountID       string
	AccessKeyID     string
	SecretAccessKey string
}

// NewCloudflareR2 创建Cloudflare R2
func NewCloudflareR2(bucket, baseURL, r2Path, accountID, accessKeyID, secretAccessKey string) *CloudflareR2 {
	return &CloudflareR2{
		Bucket:          bucket,
		BaseURL:         baseURL,
		Path:            r2Path,
		AccountID:       accountID,
		AccessKeyID:     accessKeyID,
		SecretAccessKey: secretAccessKey,
	}
}

func (c *CloudflareR2) getClient(ctx context.Context) (*s3.Client, error) {
	endpoint := fmt.Sprintf("https://%s.r2.cloudflarestorage.com", c.AccountID)

	cfg, err := config.LoadDefaultConfig(ctx,
		config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(c.AccessKeyID, c.SecretAccessKey, "")),
		config.WithRegion("auto"),
	)
	if err != nil {
		return nil, err
	}

	client := s3.NewFromConfig(cfg, func(o *s3.Options) {
		o.BaseEndpoint = aws.String(endpoint)
	})
	return client, nil
}

// UploadFile 上传文件
func (c *CloudflareR2) UploadFile(file *multipart.FileHeader) (string, string, error) {
	ctx := context.Background()
	client, err := c.getClient(ctx)
	if err != nil {
		return "", "", err
	}

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

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

	// 上传
	contentType := file.Header.Get("Content-Type")
	_, err = client.PutObject(ctx, &s3.PutObjectInput{
		Bucket:      aws.String(c.Bucket),
		Key:         aws.String(key),
		Body:        src,
		ContentType: aws.String(contentType),
	})
	if err != nil {
		return "", "", err
	}

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

// DeleteFile 删除文件
func (c *CloudflareR2) DeleteFile(key string) error {
	ctx := context.Background()
	client, err := c.getClient(ctx)
	if err != nil {
		return err
	}
	_, err = client.DeleteObject(ctx, &s3.DeleteObjectInput{
		Bucket: aws.String(c.Bucket),
		Key:    aws.String(key),
	})
	return err
}
