package controller

import (
	"bytes"
	"context"
	"file_upload/app/e"
	"file_upload/global"
	"file_upload/simple_zap"
	"file_upload/utils"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.uber.org/zap"
	"io/ioutil"
	"net/http"
	"path"
)

type Template struct {
	Name     string `json:"name" validate:"required"`
	Data     any    `json:"data" validate:"required"`
	Type     int    `json:"type" validate:"required"`
	ImageUrl string `json:"imageUrl" validate:"required"`
}

// SaveTemplate 保存文件到MongoDB
// 参数:
// - c *gin.Context: Gin框架的上下文对象，用于处理HTTP请求和响应
// 无返回值
func SaveTemplate(c *gin.Context) {
	// 解析请求体中的文件信息
	file := Template{}
	err := c.BindJSON(&file)
	if err != nil {
		// 日志记录参数解析失败
		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取参数失败")
		// 返回参数解析失败的响应
		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
		return
	}
	// 检查文件是否已存在
	filter := bson.M{"name": file.Name}
	count, err := global.MongoCon.CountDocuments(context.TODO(), filter)
	if err != nil {
		// 日志记录查询失败
		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "查询文件是否存在失败")
		// 返回错误响应
		e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
		return
	}
	if count > 0 {
		// 返回文件已存在的响应
		e.ResponseWithMsg(c, e.AlreadyExists, e.AlreadyExists.GetMsg())
		return
	}
	err = utils.ParseBase64ImageString(file.ImageUrl, file.Name)
	if err != nil {
		simple_zap.WithCtx(context.TODO()).Sugar().Warn(err, "base64解码失败")
		e.ResponseWithMsg(c, e.ERROR, "图片转换失败")
		return
	}
	var url = global.DownloadSetting.Path + file.Name + ".png"
	doc := bson.M{
		"name": file.Name,
		"type": file.Type,
		"data": file.Data,
		"url":  url,
	}
	// 保存文件到MongoDB
	_, err = global.MongoCon.InsertOne(context.TODO(), doc)
	if err != nil {
		// 日志记录保存文件失败
		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "保存文件失败")
		// 返回保存文件失败的响应
		e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
		return
	}
	// 返回文件保存成功的响应
	e.ResponseSuccess(c, e.SUCCESS)
}

//func SaveFile(c *gin.Context) {
//	// 解析请求体中的文件信息
//	file := Template{}
//	err := c.BindJSON(&file)
//	if err != nil {
//		// 日志记录参数解析失败
//		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取参数失败")
//		// 返回参数解析失败的响应
//		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
//		return
//	}
//	// 检查文件是否已存在
//	filter := bson.M{"name": file.Name}
//	count, err := global.MongoCon.CountDocuments(context.TODO(), filter)
//	if err != nil {
//		// 日志记录查询失败
//		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "查询文件是否存在失败")
//		// 返回错误响应
//		e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
//		return
//	}
//	if count > 0 {
//		// 返回文件已存在的响应
//		e.ResponseWithMsg(c, e.AlreadyExists, e.AlreadyExists.GetMsg())
//		return
//	}
//	var url string = "https://erp.baozhida.cn/assets/icon-91f5d92f.png"
//	m, ok := file.Data.(map[string]any)
//	if ok {
//		elements := m["elements"].([]any)
//		for _, v := range elements {
//			imageurl := v.(map[string]any)["url"]
//			if imageurl != nil {
//				_, data := utils.ParseBase64ImageString(imageurl.(string))
//				decodeString, err := base64.StdEncoding.DecodeString(data)
//				if err != nil {
//					simple_zap.WithCtx(context.TODO()).Sugar().Warn(err, "base64解码失败")
//					e.ResponseWithMsg(c, e.ERROR, "图片转换失败")
//					return
//				}
//				// 连接提取出的值
//				optputpath := "./upload" + "/" + file.Name + ".png"
//				create, err := os.Create(optputpath)
//				if err != nil {
//					simple_zap.WithCtx(context.TODO()).Sugar().Warn(err, "创建文件失败")
//					e.ResponseWithMsg(c, e.ERROR, "创建文件失败")
//					return
//				}
//				defer create.Close()
//				_, err = create.Write(decodeString)
//				if err != nil {
//					simple_zap.WithCtx(context.TODO()).Sugar().Warn(err, "写入文件失败")
//					e.ResponseWithMsg(c, e.ERROR, "写入文件失败")
//					return
//				}
//				// 提取所需字段值
//				url = "http://localhost:8080/download/" + file.Name + ".png"
//			}
//		}
//	}
//	doc := bson.M{
//		"name": file.Name,
//		"type": file.Type,
//		"data": file.Data,
//		"url":  url,
//	}
//	// 保存文件到MongoDB
//	_, err = global.MongoCon.InsertOne(context.TODO(), doc)
//	if err != nil {
//		// 日志记录保存文件失败
//		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "保存文件失败")
//		// 返回保存文件失败的响应
//		e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
//		return
//	}
//	// 返回文件保存成功的响应
//	e.ResponseWithMsg(c, e.SUCCESS, url)
//}

// TemplateItem 获取所有模板
func TemplateItem(c *gin.Context) {
	type Types struct {
		Type int `json:"type"`
	}
	t := &Types{}
	c.BindJSON(&t)
	filter := bson.M{
		"type": t.Type,
	}
	var result []bson.M
	opts := options.Find()
	opts.SetProjection(bson.M{
		"_id":  0,
		"data": 0,
	})
	cur, err := global.MongoCon.Find(context.Background(), filter, opts)
	if err != nil {
		// 记录日志并返回错误信息
		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取模板失败")
		e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
		return
	}
	err = cur.All(context.Background(), &result)
	if err != nil {
		// 记录日志并返回错误信息
		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取模板失败")
		e.ResponseWithMsg(c, e.ERROR, e.ERROR.GetMsg())
		return
	}
	e.ResponseSuccess(c, result)
}

// GetTemplate 获取模板
func GetTemplate(c *gin.Context) {
	name := c.Query("name")
	if name == "" {
		e.ResponseWithMsg(c, e.ERROR, "参数错误")
		return
	}
	var result map[string]interface{}
	err := global.MongoCon.FindOne(context.Background(), bson.M{"name": name}).Decode(&result)
	if err != nil {
		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取文件失败")
		e.ResponseWithMsg(c, e.ERROR, "获取文件失败")
		return
	}
	e.ResponseSuccess(c, result)
}

// DeleteTemplate 删除模板
func DeleteTemplate(c *gin.Context) {
	name := c.Query("name")
	if name == "" {
		e.ResponseWithMsg(c, e.ERROR, "参数错误")
		return
	}
	one, err := global.MongoCon.DeleteOne(context.Background(), bson.M{"name": name})
	//err := global.Rdb.Del(context.Background(), name).Err()
	if err != nil {
		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "删除文件失败")
		e.ResponseWithMsg(c, e.ERROR, "删除文件失败")
		return
	}
	if one.DeletedCount > 0 {
		e.ResponseSuccess(c, one)
		return
	}
	e.ResponseWithMsg(c, e.ERROR, "删除文件失败")
}

func SearchTemplate(c *gin.Context) {
	query := c.Query("name")
	validate := validator.New()
	validate.Var("name", "required")
	if query == "" {
		e.ResponseWithMsg(c, e.ERROR, "参数不弄为空")
		return
	}
	//result, err := global.Rdb.Keys(context.Background(), "*"+query+"*").Result()
	fileter := bson.M{"name": bson.M{"$regex": query}}
	var result []bson.M
	find := options.Find()
	find.SetProjection(bson.M{
		"_id":  0,
		"data": 0,
	})
	cursor, err := global.MongoCon.Find(context.Background(), fileter, find)
	if err != nil {
		simple_zap.Logger.Error("查询失败", zap.Error(err))
		e.ResponseWithMsg(c, e.ERROR, "查询失败")
		return
	}
	err = cursor.All(context.Background(), &result)
	e.ResponseSuccess(c, result)
}
func GetImage(c *gin.Context) {
	name := c.Query("name")
	if name == "" {
		e.ResponseWithMsg(c, e.ERROR, "参数错误")
		return
	}
	// 指定图片所在目录的路径
	imageDirPath := "./upload"

	// 构建图片文件的完整路径
	imageFilePath := fmt.Sprintf("%s/%s", imageDirPath, name)

	file, err := ioutil.ReadFile(imageFilePath)
	if err != nil {
		simple_zap.WithCtx(context.Background()).Sugar().Warn(err, "获取图片失败")
		e.ResponseWithMsg(c, e.ERROR, "获取图片失败")
		return
	}
	// 根据文件扩展名确定 Content-Type
	ext := path.Ext(name)
	contentType := ""
	switch ext {
	case ".jpg", ".jpeg":
		contentType = "image/jpeg"
	case ".png":
		contentType = "image/png"
	// 添加更多类型...
	default:
		c.AbortWithStatus(http.StatusUnsupportedMediaType)
		return
	}
	c.DataFromReader(http.StatusOK, int64(len(file)), contentType, bytes.NewReader(file), nil)
}
