package com.astalange.web.controller;

import com.astalange.core.entity.Paiement;
import com.astalange.core.repository.CategorieRepository;
import com.astalange.core.repository.ModePaiementRepository;
import com.astalange.core.repository.PaiementRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.stream.Collectors;

@Controller
public class PaiementsController {

    private final PaiementRepository paiementRepository;
    private final CategorieRepository categorieRepository;
    private final ModePaiementRepository modePaiementRepository;

    public PaiementsController(PaiementRepository paiementRepository,
                               CategorieRepository categorieRepository,
                               ModePaiementRepository modePaiementRepository) {
        this.paiementRepository = paiementRepository;
        this.categorieRepository = categorieRepository;
        this.modePaiementRepository = modePaiementRepository;
    }

    @GetMapping("/paiements")
    public String listPaiements(
            @RequestParam(required = false) String query,
            @RequestParam(required = false) String adherent,
            @RequestParam(required = false) String categorie,
            @RequestParam(required = false) String saison,
            @RequestParam(required = false) String modePaiement,
            @RequestParam(required = false) String montant,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "20") int size,
            Model model) {

        List<Paiement> allPaiements = paiementRepository.findAllWithAssociations();

        List<Paiement> filtered = allPaiements.stream()
                .filter(p -> {
                    // Global query
                    if (query != null && !query.trim().isEmpty()) {
                        String q = query.toLowerCase().trim();
                        String fullName = (p.getLicence().getAdherent().getPrenom() + " " + p.getLicence().getAdherent().getNom()).toLowerCase();
                        String catName = p.getLicence().getCategorie().getNom().toLowerCase();
                        String modeName = p.getModePaiement().getNom().toLowerCase();
                        String seasonName = p.getLicence().getSaison().getNom().toLowerCase();
                        if (!fullName.contains(q) && !catName.contains(q) && !modeName.contains(q) && !seasonName.contains(q)) {
                            return false;
                        }
                    }

                    // Column filters
                    if (adherent != null && !adherent.trim().isEmpty()) {
                        String af = adherent.toLowerCase().trim();
                        String fullName = (p.getLicence().getAdherent().getPrenom() + " " + p.getLicence().getAdherent().getNom()).toLowerCase();
                        if (!fullName.contains(af)) {
                            return false;
                        }
                    }

                    if (categorie != null && !categorie.trim().isEmpty()) {
                        if (!p.getLicence().getCategorie().getNom().equalsIgnoreCase(categorie.trim())) {
                            return false;
                        }
                    }

                    if (saison != null && !saison.trim().isEmpty()) {
                        String sf = saison.toLowerCase().trim();
                        if (!p.getLicence().getSaison().getNom().toLowerCase().contains(sf)) {
                            return false;
                        }
                    }

                    if (modePaiement != null && !modePaiement.trim().isEmpty()) {
                        if (!p.getModePaiement().getNom().equalsIgnoreCase(modePaiement.trim())) {
                            return false;
                        }
                    }

                    if (montant != null && !montant.trim().isEmpty()) {
                        String mf = montant.trim();
                        if (!p.getMontant().toString().contains(mf)) {
                            return false;
                        }
                    }

                    return true;
                })
                .collect(Collectors.toList());

        int totalElements = filtered.size();
        int totalPages = (int) Math.ceil((double) totalElements / size);
        int fromIndex = page * size;
        int toIndex = Math.min(fromIndex + size, totalElements);

        List<Paiement> paginated = List.of();
        if (fromIndex < totalElements) {
            paginated = filtered.subList(fromIndex, toIndex);
        }

        model.addAttribute("paiements", paginated);
        model.addAttribute("categories", categorieRepository.findAll());
        model.addAttribute("modesPaiement", modePaiementRepository.findAll());
        model.addAttribute("currentPage", page);
        model.addAttribute("pageSize", size);
        model.addAttribute("totalPages", totalPages);
        model.addAttribute("totalElements", totalElements);

        // Keep filter values in model to restore inputs after swap
        model.addAttribute("searchQuery", query);
        model.addAttribute("adherentFilter", adherent);
        model.addAttribute("categorieFilter", categorie);
        model.addAttribute("saisonFilter", saison);
        model.addAttribute("modePaiementFilter", modePaiement);
        model.addAttribute("montantFilter", montant);

        return "paiements/list";
    }
}
