package user

import (
	"context"
	"fmt"

	"github.com/tidbcloud/tiinf/sdk/auth"

	mspsvc "github.com/tidbcloud/account/internel/svc/msp"
	usersvc "github.com/tidbcloud/account/internel/svc/user"

	"github.com/tidbcloud/account/internel/dao/msp"
	"github.com/tidbcloud/tiinf/errs"

	"github.com/tidbcloud/account/central/utils"
	"github.com/tidbcloud/account/internel/dao/entity"
	"go.uber.org/zap"

	"github.com/tidbcloud/tiinf/monitor/tilog"

	"google.golang.org/protobuf/types/known/emptypb"

	"github.com/tidbcloud/account/idl/pbgen/proto/central"
)

func (s *UserService) QueryUserServicesAgreement(ctx context.Context, req *central.GetUserServicesAgreementReq) (*central.QueryUserServicesAgreementResp, error) {

	tilog.Info(ctx, "QueryUserServicesAgreement start", zap.Any("req", req))
	if err := validUserServicesAgreementReq(ctx, req); err != nil {
		return nil, err
	}
	user, err := usersvc.GetUserFromContext(ctx)
	if err != nil {
		return nil, err
	}

	svc, _ := mspsvc.GetMspSvc()
	isAgree, err := svc.UserIsAgreeServicesAgreements(ctx, user.ID.Uint64(), req.OrgId)
	if err != nil {
		return nil, err
	}
	tilog.Info(ctx, "GetMspUserServicesAgreement result", zap.Any("customerOrgId", req.OrgId), zap.Any("isAgree", isAgree))

	// only user in table[spUserServicesAgreements],  isAgree=[true,false]
	// else isAgree=true
	resp := &central.QueryUserServicesAgreementResp{IsAgree: isAgree}
	return resp, err
}

func validUserServicesAgreementReq(ctx context.Context, req *central.GetUserServicesAgreementReq) error {
	msg := ""
	if req.OrgId == 0 {
		msg = "org_id cannot be empty"
	}

	if msg != "" {
		tilog.Info(ctx, msg)
		return errs.NewBadRequest(msg, nil)
	}
	return nil

}

// SaveUserServicesAgreement
//
//	@Description: user accpet  the servicesAgreement
//	@Author wangletian 2024-01-17 09:55:15
//	@receiver s
//	@param ctx
//	@param req
//	@return *emptypb.Empty
//	@return error
func (s *UserService) SaveUserServicesAgreement(ctx context.Context, req *central.UserServicesAgreement) (*emptypb.Empty, error) {

	tilog.Info(ctx, "SaveUserServicesAgreement start", zap.Any("req", req))
	user, err := usersvc.GetUserFromContext(ctx)
	if err != nil {
		return &emptypb.Empty{}, err
	}

	if req.OrgId == 0 {
		return &emptypb.Empty{}, utils.ConvertErr2GrpcErr(errs.NewBadRequest("org_id must not null", nil))
	}

	param := &auth.CheckPermissionParam{
		IdentityTye: auth.AccessIdentityTypeUserID,
		IdentityVal: fmt.Sprintf("%d", user.ID),
		ResourceUri: "account/orgs/{org_id}/create_msp_service_agreement",
		ResourceParam: map[string]string{
			"org_id": fmt.Sprintf("%d", req.OrgId),
		},
	}
	permission, err := auth.CheckIdentityPermission(ctx, param)
	if err != nil {
		tilog.Error(ctx, "SaveUserServicesAgreement check identity permission error", zap.Any("param", param), zap.Any("err", err))
		return nil, err
	}
	if !permission.HasPermission {
		tilog.Info(ctx, "SaveUserServicesAgreement check identity permission not pass", zap.Any("param", param), zap.Any("ret", permission))
		return nil, errs.NewForbidden(permission.Message, nil)
	}

	mspSvc, _ := mspsvc.GetMspSvc()
	status := string(entity.Active)

	err = mspSvc.UpdateMspUserServicesAgreementByParam(ctx, msp.UserServicesAgreementFilter{UserID: user.ID, CustomerOrgID: entity.ID(req.OrgId), Status: &status}, entity.MspUserServicesAgreement{IsAgree: true})

	tilog.Info(ctx, "SaveUserServicesAgreement", zap.Any("result ", err == nil))

	return &emptypb.Empty{}, err
}
