package repo

import (
	jmpent "github.com/tidbcloud/devops/entity/jump"
	jmpmod "github.com/tidbcloud/devops/models/jump"
	"github.com/tidbcloud/devops/pkg/infra/utils/pointer"
	"github.com/tidbcloud/devops/pkg/infra/utils/repoopt"
)

var (
	AuthorizationOpts iOpts
	JumpOpts          jOpts
)

type iOpts struct{}

func (_ iOpts) WithPager(page int, perPage int) repoopt.Option {
	pager := &repoopt.Pager{
		Page:    page,
		PerPage: perPage,
	}

	order := &repoopt.Order{
		Column: "created_at",
		Desc:   true,
	}
	return repoopt.Aggregate(pager, order)
}

func (_ iOpts) PhaseIs(phase jmpent.AuthorizationPhase) repoopt.Option {
	return &repoopt.Filter[jmpent.AuthorizationPhase]{
		Column: "phase",
		Value:  &phase,
	}
}

func (_ iOpts) PhaseIn(phases []jmpent.AuthorizationPhase) repoopt.Option {
	return &repoopt.Filter[jmpent.AuthorizationPhase]{
		Column: "phase",
		Values: phases,
	}
}

func (_ iOpts) PhaseNotIn(phases []jmpent.AuthorizationPhase) repoopt.Option {
	return &repoopt.Filter[jmpent.AuthorizationPhase]{
		Column:    "phase",
		ValuesNot: phases,
	}
}

func (_ iOpts) ApplicantIs(applicant string) repoopt.Option {
	return &repoopt.Filter[string]{
		Column: "applicant",
		Value:  &applicant,
	}
}

func (_ iOpts) ApplicantIn(applicants []string) repoopt.Option {
	return &repoopt.Filter[string]{
		Column: "applicant",
		Values: applicants,
	}
}

func (_ iOpts) ApprovalIs(id uint64) repoopt.Option {
	return &repoopt.Filter[uint64]{
		Column: "approval_id",
		Value:  &id,
	}
}

func (_ iOpts) FilterJump(subFilters ...repoopt.Option) repoopt.Option {
	if len(subFilters) == 0 {
		return nil
	}

	subQ := &repoopt.Select{
		Module: jmpmod.Jump{},
		Select: []string{"auth_id"},

		Filter: repoopt.Aggregate(subFilters...),
	}

	return &repoopt.FilterWithSubQuery{
		Column:   "id",
		SubQuery: subQ,
		Values:   true,
	}
}

type jOpts struct{}

func (_ jOpts) DestinationIDLike(id string) repoopt.Option {
	return &repoopt.Filter[string]{
		Column: "destination_id",
		Like:   pointer.Pointer("%%" + id + "%%"),
	}
}

func (_ jOpts) DestinationTypeIs(destType jmpent.DestinationType) repoopt.Option {
	return &repoopt.Filter[jmpent.DestinationType]{
		Column: "destination_type",
		Value:  &destType,
	}
}
