package ai_recognition

import (
	"bytes"
	"encoding/base64"
	"goskeleton/app/global/consts"
	"goskeleton/app/http/controller/web"
	"goskeleton/app/http/validator/core/data_transfer"
	"goskeleton/app/utils/response"
	"image"
	_ "image/jpeg"
	"math"
	"github.com/gin-gonic/gin"
)

type PicRecognition struct {
	Pic string `form:"pic" json:"pic"  binding:"required"` // 必填、对于文本,表示它的长度>=1
}

func (p PicRecognition) CheckParams(context *gin.Context) {
	if err := context.ShouldBind(&p); err != nil {
		// 将表单参数验证器出现的错误直接交给错误翻译器统一处理即可
		response.ValidatorError(context, err)
		return
	}
	//  该函数主要是将本结构体的字段（成员）按照 consts.ValidatorPrefix+ json标签对应的 键 => 值 形式绑定在上下文，便于下一步（控制器）可以直接通过 context.Get(键) 获取相关值
	extraAddBindDataContext := data_transfer.DataAddContext(p, consts.ValidatorPrefix, context)
	if extraAddBindDataContext == nil {
		response.ErrorSystem(context, "PicRecognition表单参数验证器json化失败", "")
		return
	}
	pic := p.Pic
	// 先进行 URL 解码
	// decodedPic, err := url.QueryUnescape(pic)
	// if err != nil {
	// 	response.ErrorSystem(context, "PicRecognition表单参数验证器URL解码失败", "")
	// 	return
	// }
	// 再进行 Base64 解码
	decodedData, err := base64.StdEncoding.DecodeString(pic)
	if err != nil {
		response.ErrorSystem(context, "PicRecognition表单参数验证器Base64解码失败", "")
		return
	}
	// 检查大小不超过 10M（10 * 1024 * 1024 字节）
	if len(decodedData) > 10*1024*1024 {
		response.ErrorSystem(context, "PicRecognition表单参数验证器图片大小超过 10M", "")
		return
	}
	// 将字节数据转换为图像以检查格式和尺寸
	img, _, err := image.Decode(bytes.NewReader(decodedData))
	if err != nil {
		response.ErrorSystem(context, "PicRecognition表单参数验证器图片格式不正确", "")
		return
	}
	bounds := img.Bounds()
	minSide := math.Min(float64(bounds.Dx()), float64(bounds.Dy()))
	maxSide := math.Max(float64(bounds.Dx()), float64(bounds.Dy()))
	// 最短边至少 15px，最长边最大 8192px
	if minSide < 15 || maxSide > 8192 {
		response.ErrorSystem(context, "PicRecognition表单参数验证器图片尺寸过大或过小", "")
		return
	}
	(&web.AiRecognition{}).PicRecognition(extraAddBindDataContext)
}
