package adapterimpl

import (
	"context"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/go-resty/resty/v2"
	"github.com/google/uuid"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/domain/adapter"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/httputil"
)

type sys9Lifecycle struct {
	client         *resty.Client
	authManager    adapter.Sys9AuthManager
	secretProvider adapter.Sys9SecretProvider
}

type sys9ManagedDatabaseEndpoint struct {
	Host string `json:"host"`
	Port int32  `json:"port"`
}

type sys9ManagedDatabaseConnectionInfoResponse struct {
	Endpoints []sys9ManagedDatabaseEndpoint `json:"endpoints"`
}

type sys9SecretDeliveryChallengeResponse struct {
	ChallengeID string `json:"challengeId"`
	ID          string `json:"id"`
	Challenge   string `json:"challenge"`
}

type sys9SecretDeliveryData struct {
	Password string `json:"password"`
}

type sys9SecretEnvelopeV1 struct {
	SecretDeliveryID           string `json:"secretDeliveryId"`
	SealedCredentialVersion    any    `json:"sealedCredentialVersion"`
	SecretReferenceSha256      string `json:"secretReferenceSha256"`
	KeyEncapsulationAlgorithm  string `json:"keyEncapsulationAlgorithm"`
	EncapsulatedKey            string `json:"encapsulatedKey"`
	ContentEncryptionAlgorithm string `json:"contentEncryptionAlgorithm"`
	Nonce                      string `json:"nonce"`
	Ciphertext                 string `json:"ciphertext"`
	AssociatedDataSha256       string `json:"associatedDataSha256"`
	ClientPublicKeySha256      string `json:"clientPublicKeySha256"`
	IssuedAt                   string `json:"issuedAt"`
	DeliveryWindowExpiresAt    string `json:"deliveryWindowExpiresAt"`
	IssuerSignature            string `json:"issuerSignature"`
}

type sys9SecretDeliveryRedeemResponse struct {
	Password         string                  `json:"password"`
	Secret           string                  `json:"secret"`
	Data             *sys9SecretDeliveryData `json:"data"`
	SecretEnvelopeV1 *sys9SecretEnvelopeV1   `json:"secretEnvelopeV1"`
	// Some Sys9 responses may project SecretEnvelopeV1 at top-level fields.
	SecretDeliveryID           string `json:"secretDeliveryId"`
	SealedCredentialVersion    any    `json:"sealedCredentialVersion"`
	SecretReferenceSha256      string `json:"secretReferenceSha256"`
	KeyEncapsulationAlgorithm  string `json:"keyEncapsulationAlgorithm"`
	EncapsulatedKey            string `json:"encapsulatedKey"`
	ContentEncryptionAlgorithm string `json:"contentEncryptionAlgorithm"`
	Nonce                      string `json:"nonce"`
	Ciphertext                 string `json:"ciphertext"`
	AssociatedDataSha256       string `json:"associatedDataSha256"`
	ClientPublicKeySha256      string `json:"clientPublicKeySha256"`
	IssuedAt                   string `json:"issuedAt"`
	DeliveryWindowExpiresAt    string `json:"deliveryWindowExpiresAt"`
	IssuerSignature            string `json:"issuerSignature"`
}

type sys9SecretDeliveryScope struct {
	ServiceInstanceID         string `json:"serviceInstanceId"`
	ServiceInstanceGeneration int64  `json:"serviceInstanceGeneration"`
	Plane                     string `json:"plane"`
	CredentialKind            string `json:"credentialKind"`
	CredentialGeneration      int64  `json:"credentialGeneration"`
}

type sys9ServiceInstanceState struct {
	Generation int64
	StrongETag string
}

type sys9ManagedDatabaseState struct {
	Version    int64
	StrongETag string
}

type sys9ManagedDatabaseBackupV1 struct {
	BackupID  string `json:"backupId"`
	CreatedAt string `json:"createdAt"`
	ExpiresAt string `json:"expiresAt"`
	State     string `json:"state"`
}

type sys9ListManagedDatabaseBackupsResponseV1 struct {
	Backups       []sys9ManagedDatabaseBackupV1 `json:"backups"`
	NextPageToken string                        `json:"nextPageToken"`
}

type sys9ManagedDatabaseBackupPolicyV1 struct {
	Enabled       bool   `json:"enabled"`
	Schedule      string `json:"schedule"`
	RetentionDays int64  `json:"retentionDays"`
	StrongETag    string `json:"strongEtag"`
}

func NewSys9Lifecycle(authManager adapter.Sys9AuthManager, secretProvider adapter.Sys9SecretProvider) adapter.Sys9Lifecycle {
	return &sys9Lifecycle{
		client:         resty.New(),
		authManager:    authManager,
		secretProvider: secretProvider,
	}
}

func (s *sys9Lifecycle) CreateCluster(ctx context.Context, cluster *entity.Cluster) (*adapter.Sys9CreateClusterResult, error) {
	if cluster == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster is required")
	}
	if cluster.Region == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if !isPGStarterCluster(cluster) {
		return nil, bizerr.New(bizerr.ErrCodeParams, "sys9 lifecycle only supports postgres compatible engine")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}

	path := "/api/v1/service-instances"
	requestContextID := uuid.NewString()
	idempotencyKey := fmt.Sprintf("pg-starter-create-%s", cluster.ClusterId)

	body := map[string]any{
		"brandId":           profile.BrandID,
		"ownerAccountId":    profile.AccountID,
		"displayName":       cluster.ClusterId,
		"placementPolicyId": "pg-starter-default",
		"provisioningEntitlement": map[string]any{
			"entitlementId":             "33333333-3333-4333-8333-333333333333",
			"brandId":                   profile.BrandID,
			"accountId":                 profile.AccountID,
			"provisioningProfileId":     "mock-profile",
			"provisioningProfileSha256": "c2hhMjU2",
			"revision":                  1,
			"issuedAt":                  "2030-01-01T00:00:00Z",
			"expiresAt":                 "2030-02-01T00:00:00Z",
			"issuerKeyId":               "mock-issuer-key",
			"signature":                 "c2ln",
			"meterGrants":               []any{},
		},
		"managedDatabaseCreationSpec": map[string]any{
			"family":          "DATABASE_FAMILY_POSTGRESQL",
			"profileId":       "mock-postgres",
			"profileRevision": 1,
			"profileSha256":   "c2hhMjU2",
			"postgresql": map[string]any{
				"profileId":       "mock-postgres",
				"profileRevision": 1,
				"profileSha256":   "c2hhMjU2",
			},
		},
	}

	resp, err := httputil.DoRequest(ctx, s.client, http.MethodPost, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		req.ForceContentType("application/json")
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
		req.SetHeader("X-Request-Context-ID", requestContextID)
		req.SetHeader("Idempotency-Key", idempotencyKey)
		req.SetBody(body)
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "create sys9 service instance failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out struct {
		ResourceID  string `json:"resourceId"`
		OperationID string `json:"operationId"`
	}
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode create sys9 service instance response failed: %v", err)
	}
	if out.ResourceID == "" || out.OperationID == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 create response missing ids")
	}

	return &adapter.Sys9CreateClusterResult{
		ServiceInstanceID: out.ResourceID,
		OperationID:       out.OperationID,
	}, nil
}

func (s *sys9Lifecycle) GetOperation(ctx context.Context, cluster *entity.Cluster, operationID string) (*adapter.Sys9Operation, error) {
	if cluster == nil || cluster.Region == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if operationID == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "operation id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}

	path := fmt.Sprintf("/api/v1/operations/%s", operationID)
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodGet, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "get sys9 operation failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out struct {
		OperationID string `json:"operationId"`
		Phase       string `json:"phase"`
		ResourceID  string `json:"resourceId"`
	}
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 operation failed: %v", err)
	}
	if out.OperationID == "" {
		out.OperationID = operationID
	}

	return &adapter.Sys9Operation{OperationID: out.OperationID, Phase: out.Phase, ResourceID: strings.TrimSpace(out.ResourceID)}, nil
}

func (s *sys9Lifecycle) DeleteCluster(ctx context.Context, cluster *entity.Cluster, serviceInstanceID string) error {
	if cluster == nil || cluster.Region == nil {
		return bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return err
	}

	path := fmt.Sprintf("/api/v1/service-instances/%s", serviceInstanceID)
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodDelete, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
	})
	if err != nil {
		return bizerr.New(bizerr.ErrCodeUnknown, "delete sys9 service instance failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return mapSys9Error(resp.StatusCode(), resp.Body())
	}

	return nil
}

func (s *sys9Lifecycle) GetManagedDatabaseConnectionInfo(
	ctx context.Context,
	cluster *entity.Cluster,
	serviceInstanceID string,
) (*adapter.Sys9ManagedDatabaseConnectionInfo, error) {
	if cluster == nil || cluster.Region == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}

	path := fmt.Sprintf("/api/v1/service-instances/%s/managed-database/connection-info", serviceInstanceID)
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodGet, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "get sys9 managed database connection info failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out sys9ManagedDatabaseConnectionInfoResponse
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 managed database connection info failed: %v", err)
	}
	if len(out.Endpoints) == 0 || out.Endpoints[0].Host == "" || out.Endpoints[0].Port <= 0 {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 managed database connection info missing endpoint")
	}

	return &adapter.Sys9ManagedDatabaseConnectionInfo{Host: out.Endpoints[0].Host, Port: out.Endpoints[0].Port}, nil
}

func (s *sys9Lifecycle) RotateManagedDatabaseAdministrativeCredential(
	ctx context.Context,
	cluster *entity.Cluster,
	serviceInstanceID string,
	operationToken string,
) (string, error) {
	if cluster == nil || cluster.Region == nil {
		return "", bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return "", bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return "", err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return "", err
	}
	state, err := s.loadServiceInstanceState(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return "", err
	}

	path := fmt.Sprintf("/api/v1/service-instances/%s/managed-database:rotate-administrative-credential", serviceInstanceID)
	body := map[string]any{}
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodPost, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		req.ForceContentType("application/json")
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
		req.SetHeader("X-Request-Context-ID", uuid.NewString())
		req.SetHeader("If-Match", state.StrongETag)
		if operationToken != "" {
			req.SetHeader("Idempotency-Key", operationToken)
		}
		req.SetBody(body)
	})
	if err != nil {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "rotate sys9 managed database administrative credential failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return "", mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out struct {
		OperationID string `json:"operationId"`
	}
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "decode rotate credential response failed: %v", err)
	}
	if out.OperationID == "" {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "sys9 rotate response missing operation id")
	}

	return out.OperationID, nil
}

func (s *sys9Lifecycle) RedeemManagedDatabaseAdministrativeCredential(
	ctx context.Context,
	cluster *entity.Cluster,
	serviceInstanceID string,
	_ string,
) (string, error) {
	if cluster == nil || cluster.Region == nil {
		return "", bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return "", bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return "", err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return "", err
	}

	challenge, err := s.createSecretDeliveryChallenge(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return "", err
	}

	return s.redeemSecretDeliveryChallenge(ctx, cluster, profile, session, serviceInstanceID, challenge)
}

func (s *sys9Lifecycle) CreateManagedDatabaseBackup(
	ctx context.Context,
	cluster *entity.Cluster,
	serviceInstanceID string,
) (string, error) {
	if cluster == nil || cluster.Region == nil {
		return "", bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return "", bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return "", err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return "", err
	}
	state, err := s.loadServiceInstanceState(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return "", err
	}

	path := fmt.Sprintf("/api/v1/service-instances/%s/managed-database/backups", serviceInstanceID)
	body := map[string]any{"type": "BACKUP_TYPE_ON_DEMAND"}
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodPost, cluster.Region.GetServiceAddress(), path, func(request *resty.Request) {
		request.ForceContentType("application/json")
		authHeader, dpopHeader := s.authHeaders(profile, session)
		request.SetHeader("Authorization", authHeader)
		request.SetHeader("DPoP", dpopHeader)
		request.SetHeader("X-Request-Context-ID", uuid.NewString())
		request.SetHeader("If-Match", state.StrongETag)
		request.SetHeader("Idempotency-Key", uuid.NewString())
		request.SetBody(body)
	})
	if err != nil {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "create sys9 managed database backup failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return "", mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out struct {
		OperationID string `json:"operationId"`
	}
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "decode create sys9 managed database backup failed: %v", err)
	}
	if strings.TrimSpace(out.OperationID) == "" {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "sys9 create managed database backup response missing operation id")
	}

	return out.OperationID, nil
}

func (s *sys9Lifecycle) ListManagedDatabaseBackups(
	ctx context.Context,
	cluster *entity.Cluster,
	serviceInstanceID string,
	req *adapter.Sys9ListManagedDatabaseBackupsRequest,
) (*adapter.Sys9ListManagedDatabaseBackupsResponse, error) {
	if cluster == nil || cluster.Region == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}

	path := fmt.Sprintf("/api/v1/service-instances/%s/managed-database/backups", serviceInstanceID)
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodGet, cluster.Region.GetServiceAddress(), path, func(request *resty.Request) {
		authHeader, dpopHeader := s.authHeaders(profile, session)
		request.SetHeader("Authorization", authHeader)
		request.SetHeader("DPoP", dpopHeader)
		if req != nil && req.MaxCount > 0 {
			request.SetQueryParam("pageSize", strconv.FormatUint(uint64(req.MaxCount), 10))
		}
		if req != nil && req.PageToken != "" {
			request.SetQueryParam("pageToken", req.PageToken)
		}
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "list sys9 managed database backups failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out sys9ListManagedDatabaseBackupsResponseV1
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 managed database backups failed: %v", err)
	}

	backups := make([]*adapter.Sys9ManagedDatabaseBackup, 0, len(out.Backups))
	for _, b := range out.Backups {
		backup, err := toDomainManagedDatabaseBackup(b)
		if err != nil {
			return nil, err
		}
		if req != nil && req.LastBackupTime != nil && !backup.BackupTime.After(*req.LastBackupTime) {
			continue
		}
		backups = append(backups, backup)
	}

	hasMore := strings.TrimSpace(out.NextPageToken) != ""
	return &adapter.Sys9ListManagedDatabaseBackupsResponse{
		Items:         backups,
		HasMore:       hasMore,
		NextPageToken: out.NextPageToken,
	}, nil
}

func (s *sys9Lifecycle) GetManagedDatabaseBackup(
	ctx context.Context,
	cluster *entity.Cluster,
	serviceInstanceID string,
	backupID string,
) (*adapter.Sys9ManagedDatabaseBackup, error) {
	if cluster == nil || cluster.Region == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}
	if backupID == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "backup id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}

	path := fmt.Sprintf("/api/v1/service-instances/%s/managed-database/backups/%s", serviceInstanceID, backupID)
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodGet, cluster.Region.GetServiceAddress(), path, func(request *resty.Request) {
		authHeader, dpopHeader := s.authHeaders(profile, session)
		request.SetHeader("Authorization", authHeader)
		request.SetHeader("DPoP", dpopHeader)
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "get sys9 managed database backup failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out sys9ManagedDatabaseBackupV1
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 managed database backup failed: %v", err)
	}

	return toDomainManagedDatabaseBackup(out)
}

func (s *sys9Lifecycle) GetManagedDatabaseBackupPolicy(
	ctx context.Context,
	cluster *entity.Cluster,
	serviceInstanceID string,
) (*adapter.Sys9ManagedDatabaseBackupPolicy, error) {
	if cluster == nil || cluster.Region == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}

	policy, _, err := s.loadManagedDatabaseBackupPolicyState(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return nil, err
	}
	return policy, nil
}

func (s *sys9Lifecycle) UpdateManagedDatabaseBackupPolicy(
	ctx context.Context,
	cluster *entity.Cluster,
	serviceInstanceID string,
	policy *adapter.Sys9ManagedDatabaseBackupPolicy,
) (*adapter.Sys9ManagedDatabaseBackupPolicy, error) {
	if cluster == nil || cluster.Region == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster region is required")
	}
	if serviceInstanceID == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "service instance id is required")
	}
	if policy == nil {
		return nil, bizerr.New(bizerr.ErrCodeParams, "backup policy is required")
	}
	if strings.TrimSpace(policy.Schedule) == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "backup policy schedule is required")
	}
	if policy.RetentionDays == 0 {
		return nil, bizerr.New(bizerr.ErrCodeParams, "backup policy retention days must be greater than 0")
	}

	session, err := s.authManager.GetSession(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}
	profile, err := s.resolveProfile(ctx, cluster.Region)
	if err != nil {
		return nil, err
	}

	_, ifMatch, err := s.loadManagedDatabaseBackupPolicyState(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return nil, err
	}

	path := fmt.Sprintf("/api/v1/service-instances/%s/managed-database/backup-policy", serviceInstanceID)
	body := map[string]any{
		"enabled":       policy.Enabled,
		"schedule":      strings.TrimSpace(policy.Schedule),
		"retentionDays": policy.RetentionDays,
	}
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodPatch, cluster.Region.GetServiceAddress(), path, func(request *resty.Request) {
		request.ForceContentType("application/json")
		authHeader, dpopHeader := s.authHeaders(profile, session)
		request.SetHeader("Authorization", authHeader)
		request.SetHeader("DPoP", dpopHeader)
		request.SetHeader("X-Request-Context-ID", uuid.NewString())
		request.SetHeader("If-Match", ifMatch)
		request.SetHeader("Idempotency-Key", uuid.NewString())
		request.SetBody(body)
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "update sys9 managed database backup policy failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out sys9ManagedDatabaseBackupPolicyV1
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 managed database backup policy failed: %v", err)
	}

	return toDomainManagedDatabaseBackupPolicy(out)
}

func (s *sys9Lifecycle) loadManagedDatabaseBackupPolicyState(
	ctx context.Context,
	cluster *entity.Cluster,
	profile *adapter.Sys9OEMProfile,
	session *adapter.Sys9Session,
	serviceInstanceID string,
) (*adapter.Sys9ManagedDatabaseBackupPolicy, string, error) {
	path := fmt.Sprintf("/api/v1/service-instances/%s/managed-database/backup-policy", serviceInstanceID)
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodGet, cluster.Region.GetServiceAddress(), path, func(request *resty.Request) {
		authHeader, dpopHeader := s.authHeaders(profile, session)
		request.SetHeader("Authorization", authHeader)
		request.SetHeader("DPoP", dpopHeader)
	})
	if err != nil {
		return nil, "", bizerr.New(bizerr.ErrCodeUnknown, "get sys9 managed database backup policy failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, "", mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out sys9ManagedDatabaseBackupPolicyV1
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, "", bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 managed database backup policy failed: %v", err)
	}

	policy, err := toDomainManagedDatabaseBackupPolicy(out)
	if err != nil {
		return nil, "", err
	}

	etag := strings.TrimSpace(resp.Header().Get("ETag"))
	if etag == "" {
		etag = strings.TrimSpace(out.StrongETag)
	}
	if etag == "" {
		return nil, "", bizerr.New(bizerr.ErrCodeUnknown, "sys9 managed database backup policy etag is missing")
	}

	return policy, etag, nil
}

func toDomainManagedDatabaseBackup(in sys9ManagedDatabaseBackupV1) (*adapter.Sys9ManagedDatabaseBackup, error) {
	backupID := strings.TrimSpace(in.BackupID)
	if backupID == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 managed database backup id is missing")
	}
	backupTime := time.Now().UTC()
	if strings.TrimSpace(in.CreatedAt) != "" {
		parsed, err := parseSys9Timestamp(in.CreatedAt)
		if err != nil {
			return nil, bizerr.New(bizerr.ErrCodeUnknown, "parse sys9 backup createdAt failed: %v", err)
		}
		backupTime = parsed
	}
	backup := &adapter.Sys9ManagedDatabaseBackup{
		BackupID:   backupID,
		BackupName: backupID,
		BackupTime: backupTime,
		State:      strings.TrimSpace(in.State),
	}
	if strings.TrimSpace(in.ExpiresAt) != "" {
		expiresAt, err := parseSys9Timestamp(in.ExpiresAt)
		if err != nil {
			return nil, bizerr.New(bizerr.ErrCodeUnknown, "parse sys9 backup expiresAt failed: %v", err)
		}
		backup.Expiration = &expiresAt
	}
	return backup, nil
}

func toDomainManagedDatabaseBackupPolicy(in sys9ManagedDatabaseBackupPolicyV1) (*adapter.Sys9ManagedDatabaseBackupPolicy, error) {
	if strings.TrimSpace(in.Schedule) == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 managed database backup policy schedule is missing")
	}
	if in.RetentionDays <= 0 {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 managed database backup policy retention days is invalid")
	}
	return &adapter.Sys9ManagedDatabaseBackupPolicy{
		Enabled:       in.Enabled,
		Schedule:      strings.TrimSpace(in.Schedule),
		RetentionDays: uint32(in.RetentionDays),
	}, nil
}

func parseSys9Timestamp(value string) (time.Time, error) {
	trimmed := strings.TrimSpace(value)
	if trimmed == "" {
		return time.Time{}, fmt.Errorf("timestamp is empty")
	}
	if t, err := time.Parse(time.RFC3339Nano, trimmed); err == nil {
		return t.UTC(), nil
	}
	t, err := time.Parse(time.RFC3339, trimmed)
	if err != nil {
		return time.Time{}, err
	}
	return t.UTC(), nil
}

func (s *sys9Lifecycle) createSecretDeliveryChallenge(
	ctx context.Context,
	cluster *entity.Cluster,
	profile *adapter.Sys9OEMProfile,
	session *adapter.Sys9Session,
	serviceInstanceID string,
) (*sys9SecretDeliveryChallengeResponse, error) {
	scope, err := s.loadAdministrativeCredentialScope(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return nil, err
	}

	clientPublicKey := profile.TemporaryDPoPPublicKey
	if clientPublicKey == "" {
		clientPublicKey = profile.DPoPPublicKey
	}
	if clientPublicKey == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "sys9 profile temporary/public dpop key is required for secret delivery")
	}
	if profile.TLSExporterDigest == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "sys9 profile tls exporter digest is required for secret delivery")
	}

	path := "/api/v1/secret-delivery-challenges"
	body := map[string]any{
		"scope":             scope,
		"clientPublicKey":   clientPublicKey,
		"tlsExporterSha256": profile.TLSExporterDigest,
	}

	resp, err := httputil.DoRequest(ctx, s.client, http.MethodPost, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		req.ForceContentType("application/json")
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
		req.SetHeader("X-Request-Context-ID", uuid.NewString())
		req.SetBody(body)
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "create sys9 secret delivery challenge failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out sys9SecretDeliveryChallengeResponse
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 secret delivery challenge failed: %v", err)
	}
	if out.ChallengeID == "" {
		out.ChallengeID = out.ID
	}
	if out.ChallengeID == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "empty sys9 secret delivery challenge id")
	}
	if out.Challenge == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "empty sys9 secret delivery challenge proof")
	}

	return &out, nil
}

func (s *sys9Lifecycle) loadAdministrativeCredentialScope(
	ctx context.Context,
	cluster *entity.Cluster,
	profile *adapter.Sys9OEMProfile,
	session *adapter.Sys9Session,
	serviceInstanceID string,
) (*sys9SecretDeliveryScope, error) {
	state, err := s.loadServiceInstanceState(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return nil, err
	}
	managedState, err := s.loadManagedDatabaseState(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return nil, err
	}

	return &sys9SecretDeliveryScope{
		ServiceInstanceID:         serviceInstanceID,
		ServiceInstanceGeneration: state.Generation,
		Plane:                     "PLANE_DB",
		CredentialKind:            "SECRET_CREDENTIAL_KIND_MANAGED_DATABASE_ADMINISTRATIVE",
		CredentialGeneration:      managedState.Version,
	}, nil
}

func (s *sys9Lifecycle) loadServiceInstanceState(
	ctx context.Context,
	cluster *entity.Cluster,
	profile *adapter.Sys9OEMProfile,
	session *adapter.Sys9Session,
	serviceInstanceID string,
) (*sys9ServiceInstanceState, error) {
	path := fmt.Sprintf("/api/v1/service-instances/%s", serviceInstanceID)
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodGet, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "get sys9 service instance failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}
	strongETag := strings.TrimSpace(resp.Header().Get("ETag"))

	var out struct {
		Generation any    `json:"generation"`
		StrongETag string `json:"strongEtag"`
	}
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 service instance failed: %v", err)
	}
	generation, err := parseSys9Int64(out.Generation)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "parse sys9 service instance generation failed: %v", err)
	}
	if generation <= 0 {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 service instance generation is missing")
	}
	if strongETag == "" {
		strongETag = strings.TrimSpace(out.StrongETag)
	}
	if strongETag == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 service instance etag is missing")
	}

	return &sys9ServiceInstanceState{
		Generation: generation,
		StrongETag: strongETag,
	}, nil
}

func parseSys9Int64(value any) (int64, error) {
	switch v := value.(type) {
	case float64:
		return int64(v), nil
	case int64:
		return v, nil
	case string:
		parsed, err := strconv.ParseInt(strings.TrimSpace(v), 10, 64)
		if err != nil {
			return 0, err
		}
		return parsed, nil
	default:
		return 0, fmt.Errorf("unsupported int64 type %T", value)
	}
}

func (s *sys9Lifecycle) loadManagedDatabaseState(
	ctx context.Context,
	cluster *entity.Cluster,
	profile *adapter.Sys9OEMProfile,
	session *adapter.Sys9Session,
	serviceInstanceID string,
) (*sys9ManagedDatabaseState, error) {
	path := fmt.Sprintf("/api/v1/service-instances/%s/managed-database", serviceInstanceID)
	resp, err := httputil.DoRequest(ctx, s.client, http.MethodGet, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
	})
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "get sys9 managed database failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return nil, mapSys9Error(resp.StatusCode(), resp.Body())
	}

	strongETag := strings.TrimSpace(resp.Header().Get("ETag"))
	var out struct {
		Version    any    `json:"version"`
		StrongETag string `json:"strongEtag"`
	}
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 managed database failed: %v", err)
	}
	version, err := parseSys9Int64(out.Version)
	if err != nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "parse sys9 managed database version failed: %v", err)
	}
	if version <= 0 {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 managed database version is missing")
	}
	if strongETag == "" {
		strongETag = strings.TrimSpace(out.StrongETag)
	}
	if strongETag == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 managed database etag is missing")
	}

	return &sys9ManagedDatabaseState{
		Version:    version,
		StrongETag: strongETag,
	}, nil
}

func (s *sys9Lifecycle) redeemSecretDeliveryChallenge(
	ctx context.Context,
	cluster *entity.Cluster,
	profile *adapter.Sys9OEMProfile,
	session *adapter.Sys9Session,
	serviceInstanceID string,
	challenge *sys9SecretDeliveryChallengeResponse,
) (string, error) {
	if challenge == nil {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "secret delivery challenge is required")
	}
	if challenge.ChallengeID == "" {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "secret delivery challenge id is required")
	}
	if challenge.Challenge == "" {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "secret delivery challenge proof is required")
	}

	scope, err := s.loadAdministrativeCredentialScope(ctx, cluster, profile, session, serviceInstanceID)
	if err != nil {
		return "", err
	}
	clientPublicKey := profile.TemporaryDPoPPublicKey
	if clientPublicKey == "" {
		clientPublicKey = profile.DPoPPublicKey
	}

	path := "/api/v1/secret-delivery-challenges:redeem"
	body := map[string]any{
		"challengeId":       challenge.ChallengeID,
		"challengeProof":    challenge.Challenge,
		"scope":             scope,
		"clientPublicKey":   clientPublicKey,
		"tlsExporterSha256": profile.TLSExporterDigest,
	}

	resp, err := httputil.DoRequest(ctx, s.client, http.MethodPost, cluster.Region.GetServiceAddress(), path, func(req *resty.Request) {
		req.ForceContentType("application/json")
		authHeader, dpopHeader := s.authHeaders(profile, session)
		req.SetHeader("Authorization", authHeader)
		req.SetHeader("DPoP", dpopHeader)
		req.SetHeader("X-Request-Context-ID", uuid.NewString())
		req.SetBody(body)
	})
	if err != nil {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "redeem sys9 secret delivery challenge failed: %v", err)
	}
	if resp.StatusCode() >= 400 {
		return "", mapSys9Error(resp.StatusCode(), resp.Body())
	}

	var out sys9SecretDeliveryRedeemResponse
	if err := json.Unmarshal(resp.Body(), &out); err != nil {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "decode sys9 secret delivery redeem response failed: %v", err)
	}

	if out.Password != "" {
		return out.Password, nil
	}
	if out.Secret != "" {
		return out.Secret, nil
	}
	if out.Data != nil && out.Data.Password != "" {
		return out.Data.Password, nil
	}
	envelope := out.SecretEnvelopeV1
	if envelope == nil && out.Ciphertext != "" {
		envelope = &sys9SecretEnvelopeV1{
			SecretDeliveryID:           out.SecretDeliveryID,
			SealedCredentialVersion:    out.SealedCredentialVersion,
			SecretReferenceSha256:      out.SecretReferenceSha256,
			KeyEncapsulationAlgorithm:  out.KeyEncapsulationAlgorithm,
			EncapsulatedKey:            out.EncapsulatedKey,
			ContentEncryptionAlgorithm: out.ContentEncryptionAlgorithm,
			Nonce:                      out.Nonce,
			Ciphertext:                 out.Ciphertext,
			AssociatedDataSha256:       out.AssociatedDataSha256,
			ClientPublicKeySha256:      out.ClientPublicKeySha256,
			IssuedAt:                   out.IssuedAt,
			DeliveryWindowExpiresAt:    out.DeliveryWindowExpiresAt,
			IssuerSignature:            out.IssuerSignature,
		}
	}
	if envelope != nil {
		plaintext, decErr := decryptMockSecretEnvelope(envelope)
		if decErr != nil {
			return "", decErr
		}
		return plaintext, nil
	}

	return "", bizerr.New(bizerr.ErrCodeUnknown, "sys9 secret delivery redeem response missing plaintext password")
}

func decryptMockSecretEnvelope(envelope *sys9SecretEnvelopeV1) (string, error) {
	if envelope == nil {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "secret envelope is nil")
	}
	if !strings.EqualFold(envelope.ContentEncryptionAlgorithm, "MOCK") || !strings.EqualFold(envelope.KeyEncapsulationAlgorithm, "MOCK") {
		return "", bizerr.New(
			bizerr.ErrCodeUnknown,
			"unsupported sys9 secret envelope algorithm: kem=%s content=%s",
			envelope.KeyEncapsulationAlgorithm,
			envelope.ContentEncryptionAlgorithm,
		)
	}
	if envelope.SecretReferenceSha256 == "" {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "secret envelope missing secret reference digest")
	}

	const mockPlaintext = "mock-secret"
	digest := sha256.Sum256([]byte(mockPlaintext))
	expected := base64.StdEncoding.EncodeToString(digest[:])
	if envelope.SecretReferenceSha256 != expected {
		return "", bizerr.New(bizerr.ErrCodeUnknown, "mock secret digest mismatch")
	}

	return mockPlaintext, nil
}

func bearerToken(session *adapter.Sys9Session) string {
	token := ""
	if session != nil {
		token = session.AccessToken
	}
	if token == "" {
		return ""
	}
	return "Bearer " + token
}

func sessionToken(session *adapter.Sys9Session) string {
	if session == nil {
		return ""
	}
	return session.SessionToken
}

func (s *sys9Lifecycle) authHeaders(
	profile *adapter.Sys9OEMProfile,
	session *adapter.Sys9Session,
) (authorization, dpop string) {
	authHeader := bearerToken(session)
	dpopHeader := sessionToken(session)
	if profile != nil && profile.DevToken != "" {
		authHeader = "Bearer " + profile.DevToken
		dpopHeader = profile.DPoPProof
	}
	return authHeader, dpopHeader
}

func (s *sys9Lifecycle) resolveProfile(ctx context.Context, region *entity.Region) (*adapter.Sys9OEMProfile, error) {
	if region == nil || region.GetSys9Config() == nil || region.GetSys9Config().GetOemProfileRef() == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "sys9 oem profile ref is required")
	}
	if s.secretProvider == nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sys9 secret provider is required")
	}
	return s.secretProvider.ResolveProfile(ctx, region.GetSys9Config().GetOemProfileRef())
}

func isPGStarterCluster(cluster *entity.Cluster) bool {
	if cluster == nil || cluster.Region == nil {
		return false
	}
	if cluster.ServicePlan != globalcommonv1.ServicePlan_Starter {
		return false
	}
	return strings.EqualFold(cluster.EngineType, "POSTGRESQL_COMPATIBLE")
}
