package mock

import (
	"context"
	"sync"

	"github.com/ocdp/cluster-service/internal/domain/entity"
	"github.com/ocdp/cluster-service/internal/domain/repository"
	"github.com/ocdp/cluster-service/internal/pkg/crypto"
)

// RegistryRepositoryMock Registry 仓储 Mock 实现（内存存储，支持加密）
type RegistryRepositoryMock struct {
	mu         sync.RWMutex
	registries map[string]*entity.Registry // key: registry ID
	encryptor  crypto.Encryptor            // 加密器
}

// NewRegistryRepositoryMock 创建 Mock 实现
func NewRegistryRepositoryMock(encryptor crypto.Encryptor) repository.RegistryRepository {
	return &RegistryRepositoryMock{
		registries: make(map[string]*entity.Registry),
		encryptor:  encryptor,
	}
}

func (r *RegistryRepositoryMock) Create(ctx context.Context, registry *entity.Registry) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	// 检查名称是否已存在
	for _, reg := range r.registries {
		if reg.Name == registry.Name {
			return entity.ErrRegistryExists
		}
	}

	// 加密敏感数据后存储
	encryptedRegistry := r.encryptRegistry(registry)
	r.registries[registry.ID] = encryptedRegistry
	return nil
}

func (r *RegistryRepositoryMock) GetByID(ctx context.Context, id string) (*entity.Registry, error) {
	r.mu.RLock()
	defer r.mu.RUnlock()

	registry, exists := r.registries[id]
	if !exists {
		return nil, entity.ErrRegistryNotFound
	}

	// 解密敏感数据后返回
	return r.decryptRegistry(registry), nil
}

func (r *RegistryRepositoryMock) GetByName(ctx context.Context, name string) (*entity.Registry, error) {
	r.mu.RLock()
	defer r.mu.RUnlock()

	for _, registry := range r.registries {
		if registry.Name == name {
			// 解密敏感数据后返回
			return r.decryptRegistry(registry), nil
		}
	}

	return nil, entity.ErrRegistryNotFound
}

func (r *RegistryRepositoryMock) Update(ctx context.Context, registry *entity.Registry) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	if _, exists := r.registries[registry.ID]; !exists {
		return entity.ErrRegistryNotFound
	}

	// 加密敏感数据后存储
	encryptedRegistry := r.encryptRegistry(registry)
	r.registries[registry.ID] = encryptedRegistry
	return nil
}

func (r *RegistryRepositoryMock) Delete(ctx context.Context, id string) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	if _, exists := r.registries[id]; !exists {
		return entity.ErrRegistryNotFound
	}

	delete(r.registries, id)
	return nil
}

func (r *RegistryRepositoryMock) List(ctx context.Context) ([]*entity.Registry, error) {
	r.mu.RLock()
	defer r.mu.RUnlock()

	registries := make([]*entity.Registry, 0, len(r.registries))
	for _, registry := range r.registries {
		// 解密敏感数据后返回
		registries = append(registries, r.decryptRegistry(registry))
	}

	return registries, nil
}

// encryptRegistry 加密 Registry 的敏感数据
func (r *RegistryRepositoryMock) encryptRegistry(registry *entity.Registry) *entity.Registry {
	encrypted := *registry // 复制

	// 加密密码
	if registry.Password != "" && !crypto.IsEncrypted(registry.Password) {
		if encryptedPassword, err := r.encryptor.Encrypt(registry.Password); err == nil {
			encrypted.Password = encryptedPassword
		}
	}

	return &encrypted
}

// decryptRegistry 解密 Registry 的敏感数据
func (r *RegistryRepositoryMock) decryptRegistry(registry *entity.Registry) *entity.Registry {
	decrypted := *registry // 复制

	// 解密密码
	if registry.Password != "" && crypto.IsEncrypted(registry.Password) {
		if decryptedPassword, err := r.encryptor.Decrypt(registry.Password); err == nil {
			decrypted.Password = decryptedPassword
		}
	}

	return &decrypted
}
