package config

import (
	"time"

	sdkconfig "github.com/tidbcloud/aisupport/packages/sdk-go/infra/config"
)

type RootConfig struct {
	Log sdkconfig.Loggers `yaml:"log"`

	Environment string `yaml:"environment" default:"staging"`

	Secret SecretConfig `yaml:"secret"`

	Database sdkconfig.Database `yaml:"database"`

	APIServer APIServerConfig `yaml:"apiServer"`

	Eventbus EventbusConfig `yaml:"eventbus"`

	SQS SQSConfig `yaml:"sqs"`

	Atlassian AtlassianConfig `yaml:"atlassian"`

	Account AccountConfig `yaml:"account"`

	Billing BillingConfig `yaml:"billing"`

	DevOps DevOpsConfig `yaml:"devops"`

	Lake LakeConfig `yaml:"lake"`

	Mgmt MgmtConfig `yaml:"mgmt"`

	Reconciliation ReconciliationConfig `yaml:"reconciliation"`
}

type SecretConfig struct {
	sdkconfig.Secret `yaml:",inline"`

	RootConfigSecretName string `yaml:"rootConfigSecretName"`
}

type APIServerConfig struct {
	Address string `yaml:"address" default:":8080"`
}

type EventbusConfig struct {
	Account EventbusConsumerConfig `yaml:"account"`
	Billing BillingEventbusConfig  `yaml:"billing"`
}

type EventbusConsumerConfig struct {
	Enabled       *bool  `yaml:"enabled"`
	Topic         string `yaml:"topic" default:"AccountDataChangeEvent"`
	ConsumerGroup string `yaml:"consumerGroup" default:"jsm-syncer"`
}

type BillingEventbusConfig struct {
	Enabled          *bool  `yaml:"enabled"`
	SupportPlanTopic string `yaml:"supportPlanTopic" default:"binded-support-plan-update"`
	TenantPlanTopic  string `yaml:"tenantPlanTopic" default:"tenant_plan"`
	ConsumerGroup    string `yaml:"consumerGroup" default:"jsm-syncer"`
}

type SQSConfig struct {
	MSP  SQSQueueConfig `yaml:"msp"`
	Lake SQSQueueConfig `yaml:"lake"`
}

type SQSQueueConfig struct {
	Enabled  *bool  `yaml:"enabled"`
	QueueURL string `yaml:"queueURL"`
}

type AtlassianConfig struct {
	BaseURL   string                   `yaml:"baseURL"`
	Username  string                   `yaml:"username"`
	APIToken  string                   `yaml:"apiToken"`
	RateLimit AtlassianRateLimitConfig `yaml:"rateLimit"`
	Projects  AtlassianProjectsConfig  `yaml:"projects"`
}

type AtlassianRateLimitConfig struct {
	Global                              AtlassianGlobalRateLimitConfig `yaml:"global"`
	UserSearch                          AtlassianRequestPolicyConfig   `yaml:"userSearch"`
	FindOrganization                    AtlassianRequestPolicyConfig   `yaml:"findOrganization"`
	CreateOrganization                  AtlassianRequestPolicyConfig   `yaml:"createOrganization"`
	AddOrganizationToServiceDeskProject AtlassianRequestPolicyConfig   `yaml:"addOrganizationToServiceDeskProject"`
	ListOrganizationUsers               AtlassianRequestPolicyConfig   `yaml:"listOrganizationUsers"`
	AddUsersToOrganization              AtlassianRequestPolicyConfig   `yaml:"addUsersToOrganization"`
}

type AtlassianGlobalRateLimitConfig struct {
	Cooldown time.Duration `yaml:"cooldown" default:"1m"`
}

type AtlassianRequestPolicyConfig struct {
	RequestsPerSecond float64       `yaml:"requestsPerSecond" default:"10"`
	Burst             int           `yaml:"burst" default:"1"`
	MaxRetries        int           `yaml:"maxRetries" default:"4"`
	Cooldown          time.Duration `yaml:"cooldown" default:"1m"`
}

type AtlassianProjectsConfig struct {
	AccountBilling JiraProjectRoleConfig `yaml:"accountBilling"`
	Technical      JiraProjectRoleConfig `yaml:"technical"`
	Lake           JiraProjectRoleConfig `yaml:"lake"`
}

type JiraProjectRoleConfig struct {
	Key    string `yaml:"key"`
	RoleID string `yaml:"roleID"`
}

type AccountConfig struct {
	GRPCAddress string        `yaml:"grpcAddress"`
	Timeout     time.Duration `yaml:"timeout" default:"10s"`
	PageSize    int           `yaml:"pageSize" default:"500"`
}

type BillingConfig struct {
	BaseURL string        `yaml:"baseURL"`
	Timeout time.Duration `yaml:"timeout" default:"10s"`
}

type DevOpsConfig struct {
	BaseURL  string        `yaml:"baseURL"`
	APIToken string        `yaml:"apiToken"`
	Timeout  time.Duration `yaml:"timeout" default:"10s"`
	PageSize int           `yaml:"pageSize" default:"100"`
}

type LakeConfig struct {
	Mock LakeMockConfig `yaml:"mock"`
}

type LakeMockConfig struct {
	Enabled     bool                 `yaml:"enabled" default:"false"`
	Lakes       []LakeMockLake       `yaml:"lakes"`
	Memberships []LakeMockMembership `yaml:"memberships"`
}

type LakeMockLake struct {
	ID     string `yaml:"id"`
	Name   string `yaml:"name"`
	Tier   string `yaml:"tier"`
	OrgID  string `yaml:"orgID"`
	Status string `yaml:"status"`
}

type LakeMockMembership struct {
	LakeID string `yaml:"lakeID"`
	UserID string `yaml:"userID"`
	Status string `yaml:"status"`
}

type MgmtConfig struct {
	GRPCAddress string        `yaml:"grpcAddress"`
	Timeout     time.Duration `yaml:"timeout" default:"30s"`
}

type ReconciliationConfig struct {
	AccountIDResolution  AccountIDResolutionConfig `yaml:"accountIDResolution"`
	OrgFullSync          OrgFullSyncConfig         `yaml:"orgFullSync"`
	OrgMembershipSync    OrgMembershipSyncConfig   `yaml:"orgMembershipSync"`
	OrgMetadataBackfill  ReconciliationJobConfig   `yaml:"orgMetadataBackfill"`
	OrgMetadataRefresh   ReconciliationJobConfig   `yaml:"orgMetadataRefresh"`
	LakeSnapshot         ReconciliationJobConfig   `yaml:"lakeSnapshot"`
	TechnicalProjectRole ReconciliationJobConfig   `yaml:"technicalProjectRole"`
}

type AccountIDResolutionConfig struct {
	Enabled     *bool  `yaml:"enabled"`
	RecentSpec  string `yaml:"recentSpec" default:"*/10 * * * *"`
	FullSpec    string `yaml:"fullSpec" default:"0 2 * * *"`
	Concurrency int    `yaml:"concurrency" default:"3"`
}

type OrgFullSyncConfig struct {
	ReconciliationJobConfig `yaml:",inline"`

	JSMOrganizationWorkers     int `yaml:"jsmOrganizationWorkers" default:"5"`
	OrgMembershipWorkers       int `yaml:"orgMembershipWorkers" default:"10"`
	AtlassianMembershipWorkers int `yaml:"atlassianMembershipWorkers" default:"5"`
}

type OrgMembershipSyncConfig struct {
	ReconciliationJobConfig `yaml:",inline"`

	AtlassianMembershipWorkers int `yaml:"atlassianMembershipWorkers" default:"5"`
}

type ReconciliationJobConfig struct {
	Enabled    *bool  `yaml:"enabled"`
	Spec       string `yaml:"spec"`
	PageSize   int    `yaml:"pageSize"`
	BatchLimit int    `yaml:"batchLimit"`
}
