package settings

import (
	"log"
	"os"
	"strings"

	"github.com/rose_cat707/luminary/internal/auth"
	"github.com/rose_cat707/luminary/internal/model"
	"gorm.io/gorm"
)

// encryptionKeyCandidates returns possible keys ordered for repair attempts.
func encryptionKeyCandidates() []string {
	seen := map[string]bool{}
	var out []string
	add := func(key string) {
		key = strings.TrimSpace(key)
		if key == "" || seen[key] {
			return
		}
		seen[key] = true
		out = append(out, key)
	}

	add(os.Getenv("LUMINARY_ENCRYPTION_KEY"))
	add(legacyDefaultEncryptionKey)
	return out
}

// EnsureEncryptionKeyWorks verifies provider keys can be decrypted and repairs the
// stored encryption_key from legacy sources when needed.
func (r *Runtime) EnsureEncryptionKeyWorks() {
	var sample model.ProviderKey
	err := r.db.Where("api_key_enc <> ''").First(&sample).Error
	if err == gorm.ErrRecordNotFound {
		return
	}
	if err != nil {
		log.Printf("settings: check encryption key: %v", err)
		return
	}

	current := r.EncryptionKey()
	if _, err := auth.Decrypt(sample.APIKeyEnc, current); err == nil {
		return
	}

	for _, candidate := range encryptionKeyCandidates() {
		if candidate == current {
			continue
		}
		if _, err := auth.Decrypt(sample.APIKeyEnc, candidate); err != nil {
			continue
		}
		key := candidate
		if err := r.Update(UpdateInput{EncryptionKey: &key}); err != nil {
			log.Printf("settings: repair encryption_key: %v", err)
			return
		}
		log.Printf("settings: repaired encryption_key from legacy source")
		return
	}

	log.Printf("settings: provider keys cannot be decrypted; set the correct encryption_key in admin system settings or re-save provider keys")
}
