package dev.lions.btpxpress.view;

import dev.lions.btpxpress.service.StockService;
import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;

@Named("stockView")
@ViewScoped
@Getter
@Setter
public class StockView extends BaseListView<StockView.Stock, Long> {

    private static final Logger LOG = LoggerFactory.getLogger(StockView.class);

    @Inject
    StockService stockService;

    private String filtreReference;
    private String filtreDesignation;
    private String filtreCategorie;
    private String filtreStatut;
    private Long stockId;

    @PostConstruct
    public void init() {
        if (filtreStatut == null) {
            filtreStatut = "TOUS";
        }
        if (filtreCategorie == null) {
            filtreCategorie = "TOUS";
        }
        loadItems();
    }

    public void setFiltreStatut(String statut) {
        this.filtreStatut = statut;
    }

    public void setFiltreCategorie(String categorie) {
        this.filtreCategorie = categorie;
    }

    @Override
    public void loadItems() {
        loading = true;
        try {
            items = new ArrayList<>();

            // Récupération depuis l'API backend
            List<Map<String, Object>> stocksData = stockService.getAllStocks();

            for (Map<String, Object> data : stocksData) {
                Stock s = new Stock();

                s.setId(data.get("id") != null ? Long.valueOf(data.get("id").toString().hashCode()) : null);
                s.setReference((String) data.get("reference"));
                s.setDesignation((String) data.get("designation"));
                s.setCategorie((String) data.get("categorie"));
                s.setUniteMesure((String) data.get("uniteMesure"));
                s.setStatut((String) data.get("statut"));

                // Quantité disponible
                Object qteObj = data.get("quantiteDisponible");
                if (qteObj != null) {
                    s.setQuantiteDisponible(qteObj instanceof Number ?
                        ((Number) qteObj).doubleValue() :
                        Double.parseDouble(qteObj.toString()));
                } else {
                    s.setQuantiteDisponible(0.0);
                }

                // Seuil d'alerte
                Object seuilObj = data.get("seuilAlerte");
                if (seuilObj != null) {
                    s.setSeuilAlerte(seuilObj instanceof Number ?
                        ((Number) seuilObj).doubleValue() :
                        Double.parseDouble(seuilObj.toString()));
                } else {
                    s.setSeuilAlerte(0.0);
                }

                // Prix unitaire
                Object prixObj = data.get("prixUnitaire");
                if (prixObj != null) {
                    s.setPrixUnitaire(prixObj instanceof Number ?
                        ((Number) prixObj).doubleValue() :
                        Double.parseDouble(prixObj.toString()));
                } else {
                    s.setPrixUnitaire(0.0);
                }

                if (data.get("dateCreation") != null) {
                    s.setDateCreation(LocalDateTime.parse(data.get("dateCreation").toString()));
                }

                items.add(s);
            }

            LOG.info("Stocks chargés depuis l'API : {} élément(s)", items.size());
            applyFilters(items, buildFilters());
        } catch (Exception e) {
            LOG.error("Erreur chargement stocks depuis l'API", e);
            items = new ArrayList<>();
        } finally {
            loading = false;
        }
    }

    private List<Predicate<Stock>> buildFilters() {
        List<Predicate<Stock>> filters = new ArrayList<>();
        if (filtreReference != null && !filtreReference.trim().isEmpty()) {
            filters.add(s -> s.getReference() != null &&
                s.getReference().toLowerCase().contains(filtreReference.toLowerCase()));
        }
        if (filtreDesignation != null && !filtreDesignation.trim().isEmpty()) {
            filters.add(s -> s.getDesignation() != null &&
                s.getDesignation().toLowerCase().contains(filtreDesignation.toLowerCase()));
        }
        if (filtreCategorie != null && !filtreCategorie.trim().isEmpty() && !"TOUS".equals(filtreCategorie)) {
            filters.add(s -> s.getCategorie() != null && s.getCategorie().equals(filtreCategorie));
        }
        if (filtreStatut != null && !filtreStatut.trim().isEmpty() && !"TOUS".equals(filtreStatut)) {
            filters.add(s -> s.getStatut() != null && s.getStatut().equals(filtreStatut));
        }
        return filters;
    }

    @Override
    protected void resetFilterFields() {
        filtreReference = null;
        filtreDesignation = null;
        filtreCategorie = "TOUS";
        filtreStatut = "TOUS";
    }

    @Override
    protected String getDetailsPath() {
        return "/stock/";
    }

    @Override
    protected String getCreatePath() {
        return "/stock/nouveau";
    }

    @Override
    protected void performDelete() {
        LOG.info("Suppression stock : {}", selectedItem.getId());
    }

    @Override
    protected Stock createNewEntity() {
        Stock stock = new Stock();
        stock.setStatut("DISPONIBLE");
        stock.setQuantiteDisponible(0.0);
        stock.setSeuilAlerte(0.0);
        stock.setPrixUnitaire(0.0);
        stock.setDateCreation(LocalDateTime.now());
        return stock;
    }

    @Override
    protected void performCreate() {
        if (selectedItem.getId() == null) {
            selectedItem.setId(System.currentTimeMillis());
        }
        selectedItem.setDateCreation(LocalDateTime.now());
        items.add(selectedItem);
        LOG.info("Created: {}", selectedItem);
    }

    @Override
    protected void performUpdate() {
        LOG.info("Updated: {}", selectedItem);
    }

    @Override
    protected Long getEntityId(Stock entity) {
        return entity.getId();
    }

    @Override
    public String createNew() {
        selectedItem = new Stock();
        selectedItem.setStatut("DISPONIBLE");
        return getCreatePath() + "?faces-redirect=true";
    }

    /**
     * Vérifie si un stock est en alerte (quantité < seuil)
     */
    public boolean isEnAlerte(Stock stock) {
        return stock.getQuantiteDisponible() < stock.getSeuilAlerte();
    }

    @lombok.Getter
    @lombok.Setter
    public static class Stock {
        private Long id;
        private String reference;
        private String designation;
        private String categorie;
        private String uniteMesure;
        private String statut;
        private double quantiteDisponible;
        private double seuilAlerte;
        private double prixUnitaire;
        private LocalDateTime dateCreation;
    }
}
