package com.astalange.core.service;

import com.astalange.core.entity.*;
import com.astalange.core.repository.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class CategorieService {

    private final CategorieRepository categorieRepository;
    private final SaisonRepository saisonRepository;
    private final EquipementRepository equipementRepository;
    private final LicenceRepository licenceRepository;

    public CategorieService(CategorieRepository categorieRepository, SaisonRepository saisonRepository, EquipementRepository equipementRepository, LicenceRepository licenceRepository) {
        this.categorieRepository = categorieRepository;
        this.saisonRepository = saisonRepository;
        this.equipementRepository = equipementRepository;
        this.licenceRepository = licenceRepository;
    }

    public record EquipementConfig(boolean obligatoire, java.math.BigDecimal prix) {}

    @Transactional
    public void saveCategorie(Categorie categorie, java.util.Map<Long, EquipementConfig> equipementConfigs) {
        Saison activeSaison;
        Categorie existing = null;
        if (categorie.getId() == null) {
            activeSaison = saisonRepository.findByEstActiveTrue()
                    .orElseThrow(() -> new IllegalStateException("Aucune saison active trouvée"));
            categorie.setSaison(activeSaison);
        } else {
            final Long catId = categorie.getId();
            existing = categorieRepository.findById(catId)
                    .orElseThrow(() -> new IllegalArgumentException("Invalid category ID: " + catId));
            categorie.setSaison(existing.getSaison());
            activeSaison = existing.getSaison();
        }

        // Handle CategorieEquipement
        if (existing != null) {
            categorie.getCategorieEquipements().clear();
            categorie.getCategorieEquipements().addAll(existing.getCategorieEquipements());
        }

        List<CategorieEquipement> nouveauxEquipements = new ArrayList<>();
        if (equipementConfigs != null) {
            for (java.util.Map.Entry<Long, EquipementConfig> entry : equipementConfigs.entrySet()) {
                Long eqId = entry.getKey();
                EquipementConfig config = entry.getValue();
                Equipement eq = equipementRepository.findById(eqId).orElse(null);
                if (eq != null) {
                    CategorieEquipement ce = new CategorieEquipement();
                    ce.setCategorie(categorie);
                    ce.setEquipement(eq);
                    ce.setObligatoire(config.obligatoire());
                    ce.setPrix(config.prix() != null ? config.prix() : java.math.BigDecimal.ZERO);
                    nouveauxEquipements.add(ce);
                }
            }
        }

        categorie.getCategorieEquipements().clear();
        categorie.getCategorieEquipements().addAll(nouveauxEquipements);

        categorie = categorieRepository.save(categorie);

        // Mettre à jour les adhérents (via les licences de la saison actuelle)
        List<Licence> licences = licenceRepository.findBySaisonAndCategorie(activeSaison, categorie);
        for (Licence licence : licences) {
            updateDotationsForLicence(licence, nouveauxEquipements);
        }
    }

    public void syncDotationsForLicence(Licence licence) {
        if (licence.getCategorie() != null) {
            updateDotationsForLicence(licence, licence.getCategorie().getCategorieEquipements());
        }
    }

    public void updateDotationsForLicence(Licence licence, List<CategorieEquipement> categorieEquipements) {
        List<Dotation> currentDotations = licence.getDotations();
        List<Dotation> toRemove = new ArrayList<>();

        // Remove dotations for equipements no longer in the category
        for (Dotation d : currentDotations) {
            boolean found = false;
            for (CategorieEquipement ce : categorieEquipements) {
                if (ce.getEquipement().getId().equals(d.getEquipement().getId())) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                toRemove.add(d);
            }
        }
        currentDotations.removeAll(toRemove);

        // Add missing dotations
        for (CategorieEquipement ce : categorieEquipements) {
            boolean found = false;
            for (Dotation d : currentDotations) {
                if (ce.getEquipement().getId().equals(d.getEquipement().getId())) {
                    found = true;
                    if (Boolean.TRUE.equals(ce.getObligatoire()) && !Boolean.TRUE.equals(d.getChoisi())) {
                        d.setChoisi(true);
                    }
                    break;
                }
            }
            if (!found) {
                Dotation newDotation = new Dotation();
                newDotation.setLicence(licence);
                newDotation.setEquipement(ce.getEquipement());
                newDotation.setChoisi(ce.getObligatoire()); // By default checked if obligatoire
                newDotation.setFourni(false);
                currentDotations.add(newDotation);
            }
        }
        
        licenceRepository.save(licence);
    }
}
