package logic

import (
	"context"
	"encoding/json"
	"fusenapi/model/gmodel"
	"fusenapi/utils/auth"
	"fusenapi/utils/basic"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"

	"fusenapi/server/map-library/internal/svc"
	"fusenapi/server/map-library/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type SaveMapLibraryLogic struct {
	logx.Logger
	ctx      context.Context
	svcCtx   *svc.ServiceContext
	bodyData []byte
}

func NewSaveMapLibraryLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SaveMapLibraryLogic {
	return &SaveMapLibraryLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

// 处理进入前逻辑w,r
func (l *SaveMapLibraryLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) {
	bodyData, err := ioutil.ReadAll(r.Body)
	defer r.Body.Close()
	if err != nil {
		logx.Error(err)
		return
	}

	l.bodyData = bodyData
}

func (l *SaveMapLibraryLogic) SaveMapLibrary(req *types.Request, userinfo *auth.UserInfo) (resp *basic.Response) {
	if userinfo.GetIdType() != auth.IDTYPE_User {
		return resp.SetStatusWithMessage(basic.CodeServiceErr, "please sign in first")
	}

	if len(l.bodyData) == 0 {
		return resp.SetStatus(basic.CodeApiErr, http.ErrBodyReadAfterClose.Error())
	}

	var err error

	var postData []types.SaveMapLibraryData
	if err = json.Unmarshal(l.bodyData, &postData); err != nil {
		logx.Error(err)
		return resp.SetStatusWithMessage(basic.CodeSaveErr, "param err")
	}
	sort := int64(0)
	status := int64(1)
	now := time.Now().UTC().Unix()
	createList := make([]gmodel.FsMapLibrary, 0, len(postData))
	updateList := make([]gmodel.FsMapLibrary, 0, len(postData))
	//开启事务
	for _, v := range postData {
		postDataVal := v
		infoByte, _ := json.Marshal(postDataVal.Info)
		infoJsonStr := string(infoByte)
		switch postDataVal.Mid {
		case "": //新增
			createList = append(createList, gmodel.FsMapLibrary{
				Title:  &postDataVal.Info.Title,
				Info:   &infoJsonStr,
				Sort:   &sort,
				Status: &status,
				Ctime:  &now,
				TagId:  &postDataVal.Tag.Id,
			})
		default: //修改
			midInt, err := strconv.ParseInt(postDataVal.Mid, 10, 64)
			if err != nil {
				logx.Error(err)
				return resp.SetStatusWithMessage(basic.CodeServiceErr, "mid is not a number")
			}
			updateList = append(updateList, gmodel.FsMapLibrary{
				Id:    midInt,
				Title: &postDataVal.Info.Title,
				Info:  &infoJsonStr,
				TagId: &postDataVal.Tag.Id,
			})
		}
	}
	err = l.svcCtx.AllModels.FsMapLibrary.SaveMapLibraryWithTransaction(l.ctx, createList, updateList)
	if err != nil {
		logx.Error(err)
		return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to save map library")
	}
	return resp.SetStatusWithMessage(basic.CodeOK, "success")
}