package logic

import (
	"context"
	"encoding/json"
	"fusenapi/constants"
	"fusenapi/model/gmodel"
	"fusenapi/utils/auth"
	"fusenapi/utils/basic"

	"fusenapi/server/product-model/internal/svc"
	"fusenapi/server/product-model/internal/types"

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

type GetModelOtherInfoLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

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

func (l *GetModelOtherInfoLogic) GetModelOtherInfo(req *types.GetModelOtherInfoReq, userInfo *auth.BackendUserInfo) (resp *basic.Response) {
	//获取所有灯光列表
	modelLightList, err := l.svcCtx.AllModels.FsProductModel3dLight.GetAll(l.ctx)
	if err != nil {
		logx.Error(err)
		return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get model light list")
	}
	//获取配件列表
	Get3dModelsByParamReq := gmodel.Get3dModelsByParamReq{
		Tag: constants.TAG_PARTS,
	}
	if req.ProductId > 0 {
		Get3dModelsByParamReq.ProductId = req.ProductId
	}
	model3dList, err := l.svcCtx.AllModels.FsProductModel3d.Get3dModelsByParam(l.ctx, Get3dModelsByParamReq)
	if err != nil {
		logx.Error(err)
		return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get 3d model list")
	}
	//组装灯光列表
	lightListRsp := make([]types.LightListItem, 0, len(modelLightList))
	for _, v := range modelLightList {
		var info interface{}
		if v.Info != nil && *v.Info != "" {
			if err = json.Unmarshal([]byte(*v.Info), &info); err != nil {
				logx.Error(err)
				return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse light info")
			}
		}
		lightListRsp = append(lightListRsp, types.LightListItem{
			Id:   v.Id,
			Name: *v.Name,
			Info: info,
		})
	}
	modelIds := make([]int64, 0, len(model3dList))
	map3dModel := make(map[int64]int)
	for k, v := range model3dList {
		modelIds = append(modelIds, v.Id)
		map3dModel[v.Id] = k
	}
	//根据模型ids获取产品模板
	productTemplateV2List, err := l.svcCtx.AllModels.FsProductTemplateV2.FindAllByModelIds(l.ctx, modelIds, "")
	if err != nil {
		logx.Error(err)
		return resp.SetStatusWithMessage(basic.CodeDbSqlErr, "failed to get product v2 template list")
	}
	mapProductTemplate := make(map[int64]int)
	for k, v := range productTemplateV2List {
		mapProductTemplate[v.Id] = k
	}
	//组装配件数据
	partListRsp := make([]types.PartListItem, 0, len(model3dList))
	for _, v := range model3dList {
		materialImg := ""
		if templateIndex, ok := mapProductTemplate[*v.OptionTemplate]; ok {
			materialImg = *productTemplateV2List[templateIndex].MaterialImg
		}
		var info interface{}
		if v.ModelInfo != nil && *v.ModelInfo != "" {
			if err = json.Unmarshal([]byte(*v.ModelInfo), &info); err != nil {
				logx.Error(err)
				return resp.SetStatusWithMessage(basic.CodeServiceErr, "failed to parse model info")
			}
		}
		partListRsp = append(partListRsp, types.PartListItem{
			Id:          v.Id,
			Name:        *v.Name,
			MaterialImg: materialImg,
			ModelInfo:   info,
		})
	}
	return resp.SetStatusWithMessage(basic.CodeOK, "success", types.GetModelOtherInfoRsp{
		LightList: lightListRsp,
		PartList:  partListRsp,
	})
}