package file

import (
	"bytes"
	"encoding/hex"
	"io"
	"log"
	"mini_server/internal/dao"
	"mini_server/internal/server/help"
	"mini_server/internal/server/httpreply"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/sirupsen/logrus"
)

type UploadReply struct {
	FileId string `json:"file_id"` // 文件uuid，返回file_uuid
}

// 文件上传接口

func Upload(c *gin.Context) {
	reply := httpreply.NewDefaultReplyData()
	defer httpreply.Reply(c, reply)

	userId, ok := help.GetUserId(c)
	if !ok {
		reply.Status = http.StatusNotFound
		reply.Message = "无法获取用户信息"
		return
	}

	file, err := c.FormFile("file")
	if err != nil {
		reply.Status = http.StatusBadRequest
		reply.Message = "无法获取文件信息"
		return
	}

	// 读取文件中的数据，并写入到数据库中
	reader, _ := file.Open()
	defer reader.Close()

	// 添加文件大小限制，目前使用mediumblob，有16M存储限制
	if file.Size >= int64(1024*1024*16) {
		reply.Status = http.StatusRequestEntityTooLarge
		reply.Message = "上传文件超过限制，目前最多支持16M文件上传"
		return
	}

	// 拷贝数据
	buf := bytes.NewBuffer(nil)
	if _, err := io.Copy(buf, reader); err != nil {
		reply.Status = http.StatusInternalServerError
		reply.Message = "copy file failed"
		return
	}
	fileType := http.DetectContentType(buf.Bytes())
	log.Printf("文件上传请求，文件名:%v, 文件大小:%d, 文件类型:%v", file.Filename, file.Size, fileType)

	// 将数据写入数据库中
	bytesUUID, _ := uuid.NewUUID()
	uuid := hex.EncodeToString(bytesUUID[:])
	data := &dao.File{
		UUID:        uuid, // 作为唯一标识
		UserId:      userId,
		FileType:    fileType,
		FileName:    file.Filename,
		FileSize:    uint32(file.Size),
		FileContent: buf.Bytes(),
	}

	if _, err = dao.File_Insert(data); err != nil {
		logrus.Errorf("dao.File_Insert failed,err:%v", err)
		reply.Status = http.StatusInternalServerError
		reply.Message = "文件上传保存失败"
		return
	}

	reply.Data = &UploadReply{FileId: uuid}
}
