package profiles

import (
	"embed"
	"encoding/json"
	"fmt"
	"sort"
	"sync"

	"git.dumerain.org/alban/paycheck/internal/models"
)

//go:embed profiles.json
var embeddedFS embed.FS

type profileJSON struct {
	Label           string             `json:"label"`
	Matricule       string             `json:"matricule,omitempty"` // ✅ pour auto-match avec l'agent importé
	Rates           map[string]float64 `json:"rates"`
	ForfaitDimFerie float64            `json:"forfait_dim_ferie"`
}

type Repo struct {
	mu       sync.RWMutex
	profiles map[string]models.Profile
	rules    models.GlobalRules
}

// NewEmbeddedRepo charge les profils depuis profiles.json (embarqué).
func NewEmbeddedRepo() (*Repo, *models.GlobalRules, error) {
	b, err := embeddedFS.ReadFile("profiles.json")
	if err != nil {
		return nil, nil, err
	}

	var raw map[string]profileJSON
	if err := json.Unmarshal(b, &raw); err != nil {
		return nil, nil, fmt.Errorf("profiles.json invalide: %w", err)
	}

	repo := &Repo{profiles: map[string]models.Profile{}}

	for id, p := range raw {
		repo.profiles[id] = models.Profile{
			ID:        id,
			Label:     p.Label,
			Matricule: p.Matricule,
			T456:      p.Rates["456"],
			T458:      p.Rates["458"],
			T459:      p.Rates["459"],
			T471:      p.Rates["471"],
		}
		if repo.rules.ForfaitDimFerie == 0 {
			repo.rules.ForfaitDimFerie = p.ForfaitDimFerie
		}
	}

	// Valeur par défaut de sécurité si le JSON n'a aucun profil
	if repo.rules.ForfaitDimFerie == 0 {
		repo.rules.ForfaitDimFerie = 120
	}

	return repo, &repo.rules, nil
}

// List renvoie les profils triés par label (dropdown stable).
func (r *Repo) List() ([]models.ProfileListItem, error) {
	r.mu.RLock()
	defer r.mu.RUnlock()

	items := make([]models.ProfileListItem, 0, len(r.profiles))
	for _, p := range r.profiles {
		items = append(items, models.ProfileListItem{
			ID:        p.ID,
			Label:     p.Label,
			Matricule: p.Matricule,
		})
	}
	sort.Slice(items, func(i, j int) bool { return items[i].Label < items[j].Label })
	return items, nil
}

func (r *Repo) Get(id string) (models.Profile, error) {
	r.mu.RLock()
	defer r.mu.RUnlock()

	p, ok := r.profiles[id]
	if !ok {
		return models.Profile{}, fmt.Errorf("profil introuvable: %s", id)
	}
	return p, nil
}

func (r *Repo) Rules() models.GlobalRules {
	r.mu.RLock()
	defer r.mu.RUnlock()
	return r.rules
}
