package sop_task

import (
	"context"
	"strconv"
	"wechat-api/ent"
	"wechat-api/ent/soptask"
	"wechat-api/internal/utils/dberrorhandler"

	"wechat-api/internal/svc"
	"wechat-api/internal/types"

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

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

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

func (l *GetSopTaskOutlineLogic) GetSopTaskOutline(req *types.IDReq) (resp *types.SopTaskOutlineResp, err error) {
	organizationId := l.ctx.Value("organizationId").(uint64)
	data, err := l.svcCtx.DB.SopTask.Query().
		Where(soptask.ID(req.Id), soptask.OrganizationIDEQ(organizationId)).
		WithTaskStages(func(query *ent.SopStageQuery) {
			query.WithStageNodes()
		}).
		Only(l.ctx)
	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, req)
	}

	var sopTaskOutlineInfo []types.SopTaskOutlineInfo
	sopTaskOutlineInfo = []types.SopTaskOutlineInfo{}
	for _, stage := range data.Edges.TaskStages {
		nodes := stage.Edges.StageNodes
		nodesSet := make(map[uint64][]*ent.SopNode)
		for _, node := range nodes {
			nodesSet[node.ParentID] = append(nodesSet[node.ParentID], node)
		}

		key := strconv.Itoa(int(stage.ID))
		children := getChildren(nodesSet, 0)
		outlineInfo := types.SopTaskOutlineInfo{
			Title:    stage.Name,
			Key:      key,
			Children: children,
		}
		sopTaskOutlineInfo = append(sopTaskOutlineInfo, outlineInfo)
	}
	resp = &types.SopTaskOutlineResp{}
	resp.Msg = "success"
	resp.Data = sopTaskOutlineInfo
	return resp, nil
}

func getChildren(nodesSet map[uint64][]*ent.SopNode, parentID uint64) (nodeChildren []types.SopTaskOutlineInfo) {
	if nodesSet[parentID] == nil || len(nodesSet[parentID]) == 0 {
		return nil
	}
	nodeChildren = []types.SopTaskOutlineInfo{}
	for _, node := range nodesSet[parentID] {
		key := strconv.Itoa(int(node.ID))
		nodeChildren = append(nodeChildren, types.SopTaskOutlineInfo{
			Title:    node.Name,
			Key:      key,
			Children: getChildren(nodesSet, node.ID),
		})
	}
	return nodeChildren
}
