package bridge

import (
	"fmt"
	"sync"

	"git.yeij.top/AskaEth/Cyrene/platform-bridge/internal/permissions"
)

// IdentityMapper maps platform identities to Cyrene users.
type IdentityMapper struct {
	mu          sync.RWMutex
	byPlatform  map[string]map[string]*permissions.PlatformIdentity // platform -> platformUID -> identity
}

func NewIdentityMapper() *IdentityMapper {
	return &IdentityMapper{
		byPlatform: make(map[string]map[string]*permissions.PlatformIdentity),
	}
}

// Register adds or updates a platform identity mapping.
func (m *IdentityMapper) Register(id permissions.PlatformIdentity) {
	m.mu.Lock()
	defer m.mu.Unlock()
	if m.byPlatform[id.Platform] == nil {
		m.byPlatform[id.Platform] = make(map[string]*permissions.PlatformIdentity)
	}
	m.byPlatform[id.Platform][id.PlatformUID] = &id
}

// Resolve finds the Cyrene user for a platform identity.
func (m *IdentityMapper) Resolve(platform, platformUID string) (*permissions.PlatformIdentity, error) {
	m.mu.RLock()
	defer m.mu.RUnlock()
	plat, ok := m.byPlatform[platform]
	if !ok {
		return nil, fmt.Errorf("unknown platform: %s", platform)
	}
	id, ok := plat[platformUID]
	if !ok {
		return nil, fmt.Errorf("unknown user on %s: %s", platform, platformUID)
	}
	return id, nil
}

// ResolveOrNil finds the Cyrene user for a platform identity, returning nil for unknown users.
func (m *IdentityMapper) ResolveOrNil(platform, platformUID string) *permissions.PlatformIdentity {
	m.mu.RLock()
	defer m.mu.RUnlock()
	plat, ok := m.byPlatform[platform]
	if !ok {
		return nil
	}
	return plat[platformUID]
}

// IsAdmin returns true if the given platform user is a registered admin.
func (m *IdentityMapper) IsAdmin(platform, platformUID string) bool {
	id := m.ResolveOrNil(platform, platformUID)
	return id != nil && id.PermissionLevel == "admin"
}

// List returns all identities for a platform.
func (m *IdentityMapper) List(platform string) []permissions.PlatformIdentity {
	m.mu.RLock()
	defer m.mu.RUnlock()
	plat, ok := m.byPlatform[platform]
	if !ok {
		return nil
	}
	result := make([]permissions.PlatformIdentity, 0, len(plat))
	for _, id := range plat {
		result = append(result, *id)
	}
	return result
}

// ListAll returns all registered identities.
func (m *IdentityMapper) ListAll() map[string][]permissions.PlatformIdentity {
	m.mu.RLock()
	defer m.mu.RUnlock()
	result := make(map[string][]permissions.PlatformIdentity)
	for plat, users := range m.byPlatform {
		for _, id := range users {
			result[plat] = append(result[plat], *id)
		}
	}
	return result
}
