package app

import (
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/store/model"
)

func (store *Store) encryptGitHubAppConfigSecret(secret string) (string, error) {
	trimmedSecret := strings.TrimSpace(secret)
	if trimmedSecret == "" {
		return "", badRequest("GitHub App secret fields are required.")
	}
	if !store.hasAppCredentialStorage() {
		return "", badRequest("app credential storage is not configured on server")
	}

	ciphertext, err := encryptAppCredential(store.appCredentialStorageKey, trimmedSecret)
	if err != nil {
		return "", fmt.Errorf("encrypt github app config secret: %w", err)
	}
	envelope := model.CredentialEnvelope{
		Storage:    appCredentialStorageScheme,
		Ciphertext: ciphertext,
	}
	encodedEnvelope, err := model.MarshalJSONObject("github app config secret envelope", envelope)
	if err != nil {
		return "", fmt.Errorf("encode github app config secret envelope: %w", err)
	}
	return string(encodedEnvelope), nil
}

func (store *Store) encryptOptionalGitHubAppConfigSecret(secret string) (string, error) {
	if strings.TrimSpace(secret) == "" {
		return "", nil
	}
	return store.encryptGitHubAppConfigSecret(secret)
}

func (store *Store) decryptGitHubAppConfigSecret(stored string) (string, error) {
	trimmed := strings.TrimSpace(stored)
	if trimmed == "" {
		return "", nil
	}

	var envelope model.CredentialEnvelope
	if err := model.UnmarshalJSONString("github app config secret envelope", trimmed, &envelope); err != nil {
		return trimmed, nil
	}
	if strings.TrimSpace(envelope.Storage) == "" {
		return trimmed, nil
	}
	if strings.TrimSpace(envelope.Storage) != appCredentialStorageScheme {
		return "", fmt.Errorf("unsupported github app config secret storage scheme %q", envelope.Storage)
	}
	if !store.hasAppCredentialStorage() {
		return "", badRequest("app credentials are configured but server credential storage is unavailable")
	}
	plaintext, err := DecryptCredentialWithFallback(store.appCredentialDecryptionKeys(), envelope.Ciphertext)
	if err == nil {
		return plaintext, nil
	}
	return "", err
}

func (store *Store) encryptGiteaAppConfigSecret(secret string) (string, error) {
	trimmedSecret := strings.TrimSpace(secret)
	if trimmedSecret == "" {
		return "", badRequest("Gitea App secret fields are required.")
	}
	if !store.hasAppCredentialStorage() {
		return "", badRequest("app credential storage is not configured on server")
	}

	ciphertext, err := encryptAppCredential(store.appCredentialStorageKey, trimmedSecret)
	if err != nil {
		return "", fmt.Errorf("encrypt gitea app config secret: %w", err)
	}
	envelope := model.CredentialEnvelope{
		Storage:    appCredentialStorageScheme,
		Ciphertext: ciphertext,
	}
	encodedEnvelope, err := model.MarshalJSONObject("gitea app config secret envelope", envelope)
	if err != nil {
		return "", fmt.Errorf("encode gitea app config secret envelope: %w", err)
	}
	return string(encodedEnvelope), nil
}

func (store *Store) decryptGiteaAppConfigSecret(stored string) (string, error) {
	trimmed := strings.TrimSpace(stored)
	if trimmed == "" {
		return "", nil
	}

	var envelope model.CredentialEnvelope
	if err := model.UnmarshalJSONString("gitea app config secret envelope", trimmed, &envelope); err != nil {
		return trimmed, nil
	}
	if strings.TrimSpace(envelope.Storage) == "" {
		return trimmed, nil
	}
	if strings.TrimSpace(envelope.Storage) != appCredentialStorageScheme {
		return "", fmt.Errorf("unsupported gitea app config secret storage scheme %q", envelope.Storage)
	}
	if !store.hasAppCredentialStorage() {
		return "", badRequest("app credentials are configured but server credential storage is unavailable")
	}
	plaintext, err := DecryptCredentialWithFallback(store.appCredentialDecryptionKeys(), envelope.Ciphertext)
	if err == nil {
		return plaintext, nil
	}
	return "", err
}
