package facade

import (
	"context"
	"time"

	"github.com/tidbcloud/account/idl/pbgen/proto/account"
	"github.com/tidbcloud/account/idl/pbgen/proto/acl"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/serverless-service/internal/domain/constant"
)

type User struct {
	ID             uint64
	TenantID       uint64
	Tenant         *Tenant
	FirstName      string
	LastName       string
	Email          string
	Status         constant.UserStatus
	InvitedAt      *time.Time
	Job            string
	PhoneNumber    string
	Projects       []Project
	Role           constant.OrgRole
	IsImpersonated bool
}

type Tenant struct {
	ID                        uint64
	Name                      string
	Alias                     string
	Email                     string
	Country                   string
	TimeZone                  string
	Status                    constant.TenantStatus
	Plan                      constant.TenantPlan
	POCBindedPackageID        uint64
	OnDemandBindedPackageID   uint64
	DevTierBindedPackageID    uint64
	Kind                      constant.TenantKind
	AcceptService             bool
	ZendeskID                 uint64
	ThirdPartyAccountProvider *string
	ThirdPartyAccountCode     *string
	Projects                  []*Project
	BillingEmail              string
	AccountManager            string // the email address of account manager
}

type Project struct {
	ID             uint64
	Name           string
	TenantID       uint64
	Tenant         *Tenant
	Status         constant.ProjectStatus
	DeletedTime    *time.Time
	IsCrossAccount bool
	AwsCmekEnabled bool
}

type TenantFilter struct {
	TenantIDs []uint64
	Status    []constant.TenantStatus
}

type OpenAPIAccess struct {
	OrgID    uint64
	Projects []uint64
	Roles    []acl.OrgRole
}

type DBUserJwt struct {
	UserName string
	Jwt      string
}

type DBUser struct {
	TenantId    uint64
	Id          uint64
	Username    string
	Email       string
	BuiltinRole constant.BuiltinRole
}

type AccountFacade interface {
	GetAuthUserInOrg(ctx context.Context, email string, orgID uint64, skipCheckOrg bool) (*User, bool, error)
	GetOrCreateSystemUser(ctx context.Context, orgID uint64) (*User, error)
	GetTenant(ctx context.Context, tenantID uint64) (*Tenant, error)
	QueryTenants(ctx context.Context, filter *TenantFilter) (map[uint64]*Tenant, error)
	GetProject(ctx context.Context, projectID uint64) (*Project, error)
	GetOpenAPIAccess(ctx context.Context, publicKey string) (*OpenAPIAccess, error)
	GetJwtByUser(ctx context.Context, email string, userID, clusterID uint64) (*DBUserJwt, error)
	GetBranchJwtByApiKey(ctx context.Context, publicKey string, branchID string) (*DBUserJwt, error)
	GetJwtByApiKey(ctx context.Context, publicKey string, clusterID uint64) (*DBUserJwt, error)
	GetDBUsers(ctx context.Context, orgID, projectID uint64, token string) ([]*DBUser, error)
	GetCloudAdminPasswd(ctx context.Context, clusterId uint64) (string, bizerr.BizError)
	ListOrgMapByIDs(ctx context.Context, ids []uint64) (map[uint64]*account.Org, bizerr.BizError)
	SendTenantOwnerEmailOnce(
		ctx context.Context,
		tenantID uint64,
		key string,
		templateID string,
		vars map[string]string,
	) error
	ListActiveOrgs(ctx context.Context) ([]*account.Org, bizerr.BizError)
	ListProjectsMapByOrg(ctx context.Context, orgId uint64) (map[uint64]*account.Project, bizerr.BizError)
}
