/**
 @author: xiaopengzhu
 @date: 2022/7/21
 @description:审批流controller
**/

package approval

import (
	"github.com/gin-gonic/gin"

	srvv1 "github.com/pingcap-inc/pchub/internal/apiserver/service/v1"
	"github.com/pingcap-inc/pchub/internal/apiserver/store"
	"github.com/pingcap-inc/pchub/internal/pkg/code"
	"github.com/pingcap-inc/pchub/internal/pkg/middleware"
	modelv1 "github.com/pingcap-inc/pchub/model/v1"
	"github.com/pingcap-inc/pchub/pkg/errors"
	"github.com/pingcap-inc/pchub/pkg/log"
	"github.com/pingcap-inc/pchub/pkg/util/ginres"
)

type approvalController struct {
	srv srvv1.Service
}

func NewApprovalController(store store.Factory) *approvalController {
	return &approvalController{
		srv: srvv1.NewService(store),
	}
}

func (s *approvalController) CreateApproval(c *gin.Context) {
	log.L(c).Info("ApprovalController.CreateApproval called")

	var body modelv1.ApprovalBody
	err := c.ShouldBindJSON(&body)
	if err != nil {
		ginres.WriteResponse(c, errors.WithCode(code.ErrInvalidJSON, ""), nil)

		return
	}
	if body.ApprovalType < 0 || body.ApprovalType > 7 {
		ginres.WriteResponse(c, errors.WithCode(code.ErrApprovalType, ""), nil)

		return
	}
	authingId, err := middleware.GetAuthingId(c)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}
	user, err := s.srv.User().GetUserByID(c, authingId)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}
	err = s.srv.Approval().CreateApproval(c, user, body)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}

	ginres.WriteResponse(c, nil, "ok")
}

func (s *approvalController) GetAllApproval(c *gin.Context) {
	log.L(c).Info("GetAllApproval")
	params := ginres.ParseQuery(c, "approvalType", "status", "startTime", "endTime", "size", "current")

	authingId, err := middleware.GetAuthingId(c)
	if err != nil {
		ginres.WriteResponse(c, err, nil)
	}
	approvals, err := s.srv.Approval().GetAllApproval(c, authingId, params)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}
	ginres.WriteResponse(c, nil, approvals)
}

func (s *approvalController) GetApprovalByInstanceCode(c *gin.Context) {
	log.L(c).Info("GetApprovalByInstanceCode")
	instanceCode := c.Param("instanceCode")
	if instanceCode == "" {
		ginres.WriteResponse(c, errors.WithCode(code.ErrValidation, "Param 'instanceCode' missing"), nil)

		return
	}
	instance, err := s.srv.Approval().GetApprovalByInstanceCode(c, instanceCode)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}
	authingId, err := middleware.GetAuthingId(c)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}
	user, err := s.srv.User().GetUserByID(c, authingId)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}
	if user.LarkUserID != instance.Luid {
		ginres.WriteResponse(c, errors.WithCode(code.ErrNotApprovalOwner, ""), nil)

		return
	}
	approvalInLark, err := s.srv.Approval().GetApprovalFromLark(c, instanceCode)
	if err != nil {
		ginres.WriteResponse(c, err, nil)

		return
	}

	ginres.WriteResponse(c, nil, approvalInLark)
}

func (s *approvalController) Subscribe(c *gin.Context) {
	log.L(c).Info("ApprovalController.Subscribe called")

	s.srv.Approval().Subscribe(c)

	ginres.WriteResponse(c, nil, "done")
}
