package logic

import (
	"context"
	"errors"
	"fmt"
	"io"
	"log"
	"mime/multipart"
	"os"
	"path/filepath"
	"time"

	"bsm/full/module/base/fts/internal/config"
	"bsm/full/module/base/fts/internal/models"
	"git.apinb.com/bsm-sdk/core/infra"
	"git.apinb.com/bsm-sdk/core/utils"
	"github.com/gin-gonic/gin"
	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
)

// LocalUpload 本地上传
func LocalUpload(fh *multipart.FileHeader, record *models.FtsRecord, ctx *gin.Context, bucket string) (err error) {
	subdirpath := NewSubdir(record.OwnerIdentity)
	saveDir := filepath.Join(config.Spec.Local.UploadDir, bucket, subdirpath)

	// 创建目录并确保权限正确
	if err = os.MkdirAll(saveDir, 0755); err != nil {
		log.Println("目录创建失败:", err)
		infra.Response.Error(ctx, errors.New("目录创建失败"))
		return
	}

	// 保存文件到指定路径
	fileName := utils.ULID() + record.Ext
	savePath := filepath.Join(saveDir, fileName)

	// 使用自定义方式保存文件，确保权限控制
	file, err := os.OpenFile(savePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		log.Println("文件创建失败:", err)
		infra.Response.Error(ctx, err)
		return
	}
	defer file.Close()

	src, err := fh.Open()
	if err != nil {
		log.Println("文件打开失败:", err)
		infra.Response.Error(ctx, err)
		return
	}
	defer src.Close()

	if _, err = io.Copy(file, src); err != nil {
		log.Println("文件保存失败:", err)
		infra.Response.Error(ctx, err)
		return
	}

	// 再次确认文件权限
	if err = os.Chmod(savePath, 0644); err != nil {
		log.Printf("警告: 设置文件权限失败: %v", err)
		infra.Response.Error(ctx, err)
		return
	}

	record.LocalPath = savePath
	record.SaveName = fileName
	record.ResultUrl = config.Spec.Local.Site + "/" + bucket + "/" + subdirpath + "/" + fileName

	return nil
}

// OssUpload 上传文件到指定的MinIO存储桶
func OssUpload(file *multipart.FileHeader, record *models.FtsRecord, c *gin.Context, bucket string) (err error) {
	// Initialize minio client object.
	minioClient, err := minio.New(config.Spec.MinioOss.Endpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(config.Spec.MinioOss.AccessKeyID, config.Spec.MinioOss.AccessKeySecret, ""), // 修正字段名
		Secure: config.Spec.MinioOss.UseSSL,
	})
	if err != nil {
		return err
	}

	// 设置保存格式为: 年/identity/identity后3位+filename
	subdirpath := NewSubdir(record.OwnerIdentity)
	fileName := utils.ULID() + record.Ext
	savePath := filepath.Join(subdirpath, fileName)

	// Open the file
	src, err := file.Open()
	if err != nil {
		return err
	}
	defer src.Close()

	_, err = minioClient.PutObject(context.Background(), bucket, savePath, src, file.Size, minio.PutObjectOptions{ContentType: "application/octet-stream"})

	if err != nil {
		fmt.Println("err = ", err)
		return err
	}

	record.OssPath = savePath
	fmt.Println("savePath = ", savePath)
	record.ResultUrl = config.Spec.MinioOss.Site + "/" + bucket + "/" + savePath
	fmt.Println("record.ResultUrl = ", record.ResultUrl)
	return nil
}

func NewSubdir(identity string) string {
	ym := time.Now().Format("2006-01")
	return ym + "/" + identity[0:2]
}
