package keyword

import (
	"fmt"
	"net/http"
	"strconv"
	"time"

	"mini-chat/internal/code"
	"mini-chat/internal/pkg/core"
	"mini-chat/internal/pkg/validation"
	"mini-chat/internal/repository/mysql/model"

	"gorm.io/gorm"
)

type keywordMaterial struct {
	Type            int32  `json:"type" binding:"required"`             // 素材类型(1:文本 2:图片)
	Content         string `json:"content" binding:"required"`          // 素材内容
	IntervalSeconds int32  `json:"interval_seconds" binding:"required"` // 发送间隔时间(单位:秒)
}

type createKeywordMaterialRequest struct {
	MaterialList []keywordMaterial `json:"material_list" binding:"required"` // 素材列表
}

type createKeywordMaterialResponse struct {
	Message string `json:"message"` // 提示信息
}

// CreateKeywordMaterial 配置意图关键字素材
// @Summary 配置意图关键字素材
// @Description 配置意图关键字素材
// @Tags 管理端.意图关键字
// @Accept json
// @Produce json
// @Param id path string true "编号ID"
// @Param RequestBody body createKeywordMaterialRequest true "请求参数"
// @Success 200 {object} createKeywordMaterialResponse
// @Failure 400 {object} code.Failure
// @Router /api/admin/app/keyword/material/{id} [post]
// @Security LoginVerifyToken
func (h *handler) CreateKeywordMaterial() core.HandlerFunc {
	return func(ctx core.Context) {
		req := new(createKeywordMaterialRequest)
		res := new(createKeywordMaterialResponse)
		if err := ctx.ShouldBindJSON(req); err != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.ParamBindError,
				validation.Error(err)),
			)
			return
		}

		ID, err := strconv.Atoi(ctx.Param("id"))
		if err != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.ParamBindError,
				"未传递编号ID。"),
			)
			return
		}

		if len(req.MaterialList) == 0 {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.CreateKeywordMaterialError,
				fmt.Sprintf("%s: 未配置素材", code.Text(code.CreateKeywordMaterialError))),
			)
			return
		}

		info, err := h.readDB.AppKeyword.WithContext(ctx.RequestContext()).
			Where(h.readDB.AppKeyword.ID.Eq(int32(ID))).
			First()
		if err != nil && err != gorm.ErrRecordNotFound {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.CreateKeywordMaterialError,
				fmt.Sprintf("%s: %s", code.Text(code.CreateKeywordMaterialError), err.Error())),
			)
			return
		}

		if info == nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.CreateKeywordMaterialError,
				fmt.Sprintf("%s: 意图关键字编号(%d)不存在。", code.Text(code.CreateKeywordMaterialError), ID)),
			)
			return
		}

		// 先删除旧数据
		if _, err := h.writeDB.AppKeywordReply.WithContext(ctx.RequestContext()).
			Where(h.writeDB.AppKeywordReply.KeywordID.Eq(int32(ID))).
			Delete(); err != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.CreateKeywordMaterialError,
				fmt.Sprintf("%s: %s", code.Text(code.CreateKeywordMaterialError), err.Error())),
			)
			return
		}

		var keywordMaterials []*model.AppKeywordReply
		for i := 0; i < len(req.MaterialList); i++ {
			if req.MaterialList[i].Type == 0 || req.MaterialList[i].Content == "" || req.MaterialList[i].IntervalSeconds == 0 {
				ctx.AbortWithError(core.Error(
					http.StatusBadRequest,
					code.CreateKeywordMaterialError,
					fmt.Sprintf("%s: 配置素材数据不完整，请检查。", code.Text(code.CreateKeywordMaterialError))),
				)
				return
			}

			keywordMaterials = append(keywordMaterials, &model.AppKeywordReply{
				KeywordID:       int32(ID),
				AppID:           info.AppID,
				Type:            req.MaterialList[i].Type,
				Content:         req.MaterialList[i].Content,
				IntervalSeconds: req.MaterialList[i].IntervalSeconds,
				CreatedUser:     ctx.SessionUserInfo().UserName,
				CreatedAt:       time.Now(),
			})
		}

		// 批量插入
		if err := h.writeDB.AppKeywordReply.WithContext(ctx.RequestContext()).CreateInBatches(keywordMaterials, len(req.MaterialList)); err != nil {
			ctx.AbortWithError(core.Error(
				http.StatusBadRequest,
				code.CreateKeywordMaterialError,
				fmt.Sprintf("%s: %s", code.Text(code.CreateKeywordMaterialError), err.Error())),
			)
			return
		}

		res.Message = "操作成功"
		ctx.Payload(res)
	}
}
