package dev.lions.btpxpress.view;

import dev.lions.btpxpress.service.ClientService;
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("clientsView")
@ViewScoped
@Getter
@Setter
public class ClientsView extends BaseListView<ClientsView.Client, Long> {

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

    @Inject
    ClientService clientService;

    private String filtreNom;
    private String filtreEmail;
    private String filtreVille;
    private Long clientId;

    @PostConstruct
    public void init() {
        loadItems();
    }

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

            // Récupération depuis l'API backend
            List<Map<String, Object>> clientsData = clientService.getAllClients();

            for (Map<String, Object> data : clientsData) {
                Client c = new Client();

                // Mapping des données de l'API vers l'objet Client
                c.setId(data.get("id") != null ? Long.valueOf(data.get("id").toString().hashCode()) : null);

                // Raison sociale : entreprise ou "Particulier" si vide
                String entreprise = (String) data.get("entreprise");
                c.setRaisonSociale(entreprise != null && !entreprise.trim().isEmpty() ?
                    entreprise : "Particulier");

                // Nom complet du contact : prénom + nom
                String prenom = (String) data.get("prenom");
                String nom = (String) data.get("nom");
                c.setNomContact((prenom != null ? prenom + " " : "") + (nom != null ? nom : ""));

                c.setEmail((String) data.get("email"));
                c.setTelephone((String) data.get("telephone"));
                c.setAdresse((String) data.get("adresse"));
                c.setVille((String) data.get("ville"));
                c.setCodePostal((String) data.get("codePostal"));

                // Nombre de chantiers (relation)
                Object chantiersObj = data.get("chantiers");
                if (chantiersObj instanceof List) {
                    c.setNombreChantiers(((List<?>) chantiersObj).size());
                } else {
                    c.setNombreChantiers(0);
                }

                // Chiffre d'affaires total (à calculer ou récupérer)
                // Pour l'instant, on met 0 car cette donnée n'est pas dans l'API
                c.setChiffreAffairesTotal(0.0);

                // Date de création
                if (data.get("dateCreation") != null) {
                    c.setDateCreation(LocalDateTime.parse(data.get("dateCreation").toString()));
                }

                // Date de modification
                if (data.get("dateModification") != null) {
                    c.setDateModification(LocalDateTime.parse(data.get("dateModification").toString()));
                }

                items.add(c);
            }

            LOG.info("Clients chargés depuis l'API : {} élément(s)", items.size());
            applyFilters(items, buildFilters());
        } catch (Exception e) {
            LOG.error("Erreur chargement clients depuis l'API", e);
            // En cas d'erreur, on garde une liste vide
            items = new ArrayList<>();
        } finally {
            loading = false;
        }
    }

    private List<Predicate<Client>> buildFilters() {
        List<Predicate<Client>> filters = new ArrayList<>();
        if (filtreNom != null && !filtreNom.trim().isEmpty()) {
            filters.add(c -> c.getRaisonSociale().toLowerCase().contains(filtreNom.toLowerCase()) ||
                           c.getNomContact().toLowerCase().contains(filtreNom.toLowerCase()));
        }
        if (filtreEmail != null && !filtreEmail.trim().isEmpty()) {
            filters.add(c -> c.getEmail().toLowerCase().contains(filtreEmail.toLowerCase()));
        }
        if (filtreVille != null && !filtreVille.trim().isEmpty()) {
            filters.add(c -> c.getVille().toLowerCase().contains(filtreVille.toLowerCase()));
        }
        return filters;
    }

    @Override
    protected void resetFilterFields() {
        filtreNom = null;
        filtreEmail = null;
        filtreVille = null;
    }

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

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

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

    @Override
    protected Client createNewEntity() {
        Client client = new Client();
        client.setDateCreation(LocalDateTime.now());
        client.setDateModification(LocalDateTime.now());
        client.setNombreChantiers(0);
        client.setChiffreAffairesTotal(0.0);
        return client;
    }

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

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

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

    /**
     * Initialise un nouveau client pour la création.
     */
    @Override
    public String createNew() {
        selectedItem = new Client();
        return getCreatePath() + "?faces-redirect=true";
    }

    /**
     * Sauvegarde un nouveau client.
     */
    public String saveNew() {
        if (selectedItem == null) {
            selectedItem = new Client();
        }
        selectedItem.setId(System.currentTimeMillis());
        selectedItem.setDateCreation(LocalDateTime.now());
        selectedItem.setDateModification(LocalDateTime.now());
        selectedItem.setNombreChantiers(0);
        selectedItem.setChiffreAffairesTotal(0.0);
        items.add(selectedItem);
        LOG.info("Nouveau client créé : {}", selectedItem.getRaisonSociale());
        return "/clients?faces-redirect=true";
    }

    /**
     * Affiche les détails d'un client.
     */
    public String viewDetails(Long id) {
        selectedItem = items.stream()
                .filter(c -> c.getId().equals(id))
                .findFirst()
                .orElse(null);
        if (selectedItem != null) {
            return getDetailsPath() + "details?id=" + id + "&faces-redirect=true";
        }
        return "/clients?faces-redirect=true";
    }

    /**
     * Charge un client par son ID depuis les paramètres de la requête.
     */
    public void loadClientById() {
        if (clientId != null) {
            loadItems(); // S'assurer que les items sont chargés
            selectedItem = items.stream()
                    .filter(c -> c.getId().equals(clientId))
                    .findFirst()
                    .orElse(null);
            if (selectedItem == null) {
                LOG.warn("Client avec ID {} non trouvé", clientId);
            }
        }
    }

    @lombok.Getter
    @lombok.Setter
    public static class Client {
        private Long id;
        private String raisonSociale;
        private String nomContact;
        private String email;
        private String telephone;
        private String adresse;
        private String ville;
        private String codePostal;
        private String pays;
        private int nombreChantiers;
        private double chiffreAffairesTotal;
        private LocalDateTime dateCreation;
        private LocalDateTime dateModification;
    }
}
