package dev.lions.user.manager.client.view;

import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import lombok.Data;
import org.primefaces.model.TreeNode;

import java.io.Serializable;
import java.time.LocalDate;
import java.util.*;
import java.util.logging.Logger;

/**
 * Bean JSF pour la showcase Freya Extension
 * Démonstration complète des 46 composants personnalisés
 *
 * @author Lions User Manager
 * @version 1.0.0
 */
@Named("demoBean")
@ViewScoped
@Data
public class FreyaShowcaseBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = Logger.getLogger(FreyaShowcaseBean.class.getName());

    // ============ DONNÉES UTILISATEUR EXEMPLE ============
    private User user = new User();
    private List<SampleUser> sampleUsers;
    private TreeNode<NodeData> treeRoot;

    // ============ DIALOGUES ============
    private FormDialogData dialogData = new FormDialogData();

    // ============ COMPOSANTS ============
    private String requiredField;
    private String inplaceText = "Texte éditable";
    private String chartData;
    private Integer progressValue = 0;

    @PostConstruct
    public void init() {
        LOGGER.info("=== Initialisation du FreyaShowcaseBean ===");

        // Initialiser les données d'exemple
        initSampleUsers();
        initTreeData();
        initChartData();

        // Valeurs par défaut pour les composants
        user.setVolume(50);
        user.setRating(4);
        user.setQuantite(10);
    }

    /**
     * Initialiser les utilisateurs d'exemple pour dataTable et dataView
     */
    private void initSampleUsers() {
        sampleUsers = new ArrayList<>();
        sampleUsers.add(new SampleUser("Jean Dupont", "jean.dupont@example.com", true));
        sampleUsers.add(new SampleUser("Marie Martin", "marie.martin@example.com", true));
        sampleUsers.add(new SampleUser("Pierre Durand", "pierre.durand@example.com", false));
        sampleUsers.add(new SampleUser("Sophie Bernard", "sophie.bernard@example.com", true));
        sampleUsers.add(new SampleUser("Luc Petit", "luc.petit@example.com", false));
        sampleUsers.add(new SampleUser("Anne Dubois", "anne.dubois@example.com", true));
        sampleUsers.add(new SampleUser("Paul Thomas", "paul.thomas@example.com", true));
        sampleUsers.add(new SampleUser("Claire Robert", "claire.robert@example.com", false));
    }

    /**
     * Initialiser l'arborescence pour tree et treeTable
     */
    private void initTreeData() {
        treeRoot = new org.primefaces.model.DefaultTreeNode<>(new NodeData("Racine", "Dossier"), null);

        TreeNode<NodeData> documents = new org.primefaces.model.DefaultTreeNode<>(
            new NodeData("Documents", "Dossier"), treeRoot);
        TreeNode<NodeData> images = new org.primefaces.model.DefaultTreeNode<>(
            new NodeData("Images", "Dossier"), treeRoot);

        new org.primefaces.model.DefaultTreeNode<>(new NodeData("Rapport.pdf", "Fichier"), documents);
        new org.primefaces.model.DefaultTreeNode<>(new NodeData("Facture.xlsx", "Fichier"), documents);
        new org.primefaces.model.DefaultTreeNode<>(new NodeData("Photo1.jpg", "Fichier"), images);
        new org.primefaces.model.DefaultTreeNode<>(new NodeData("Photo2.png", "Fichier"), images);
    }

    /**
     * Initialiser les données du graphique Chart.js (format JSON moderne)
     */
    private void initChartData() {
        // Utilisation de JSON direct pour Chart.js (API moderne, non dépréciée)
        chartData = """
            {
                "type": "bar",
                "data": {
                    "labels": ["Jan", "Fév", "Mar", "Avr", "Mai", "Juin"],
                    "datasets": [{
                        "label": "Statistiques Mensuelles",
                        "data": [65, 59, 80, 81, 56, 55],
                        "backgroundColor": [
                            "rgba(54, 162, 235, 0.2)",
                            "rgba(75, 192, 192, 0.2)",
                            "rgba(255, 206, 86, 0.2)",
                            "rgba(153, 102, 255, 0.2)",
                            "rgba(255, 99, 132, 0.2)",
                            "rgba(255, 159, 64, 0.2)"
                        ],
                        "borderColor": [
                            "rgba(54, 162, 235, 1)",
                            "rgba(75, 192, 192, 1)",
                            "rgba(255, 206, 86, 1)",
                            "rgba(153, 102, 255, 1)",
                            "rgba(255, 99, 132, 1)",
                            "rgba(255, 159, 64, 1)"
                        ],
                        "borderWidth": 1
                    }]
                },
                "options": {
                    "responsive": true,
                    "maintainAspectRatio": false,
                    "plugins": {
                        "legend": {
                            "display": true,
                            "position": "top"
                        }
                    },
                    "scales": {
                        "y": {
                            "beginAtZero": true
                        }
                    }
                }
            }
            """;
    }

    /**
     * Autocomplétion pour fieldAutoComplete
     */
    public List<String> completeCities(String query) {
        List<String> allCities = Arrays.asList(
            "Paris", "Lyon", "Marseille", "Toulouse", "Nice", "Nantes",
            "Strasbourg", "Montpellier", "Bordeaux", "Lille", "Rennes", "Reims"
        );

        return allCities.stream()
            .filter(city -> city.toLowerCase().startsWith(query.toLowerCase()))
            .toList();
    }

    // ============ ACTIONS ============

    public void saveAction() {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_INFO, "Succès", "Données sauvegardées avec succès"));
        LOGGER.info("Action Save executée");
    }

    public void cancelAction() {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_WARN, "Annulé", "Action annulée"));
        LOGGER.info("Action Cancel executée");
    }

    public void refreshAction() {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_INFO, "Rafraîchi", "Données rafraîchies"));
        LOGGER.info("Action Refresh executée");
    }

    public void confirmAction() {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_INFO, "Confirmé", "Action confirmée avec succès"));
        LOGGER.info("Action Confirm executée (actionDialog)");
    }

    public void createUser() {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_INFO, "Utilisateur créé",
                "Utilisateur " + dialogData.getNom() + " créé avec succès"));
        LOGGER.info("Utilisateur créé: " + dialogData.getNom() + " - " + dialogData.getEmail());
        dialogData = new FormDialogData(); // Reset
    }

    public void showSuccessMessage() {
        FacesContext.getCurrentInstance().addMessage("growlDemo",
            new FacesMessage(FacesMessage.SEVERITY_INFO, "Succès", "Opération réussie avec succès"));
    }

    public void showWarningMessage() {
        FacesContext.getCurrentInstance().addMessage("growlDemo",
            new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", "Ceci est un avertissement"));
    }

    public void startProgress() {
        progressValue = 0;
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                progressValue = Math.min(100, progressValue + 10);
                if (progressValue >= 100) {
                    timer.cancel();
                }
            }
        }, 0, 500);
    }

    public void resetProgress() {
        progressValue = 0;
    }

    // ============ CLASSES INTERNES ============

    /**
     * Classe User pour démonstration des champs de formulaire
     */
    @Data
    public static class User implements Serializable {
        private String nom;
        private String password;
        private String description;
        private Integer age;
        private LocalDate dateNaissance;
        private String pays;
        private List<String> competences;
        private Boolean actif;
        private String genre;
        private Boolean newsletter;
        private Boolean modeNuit;
        private Integer volume;
        private Integer rating;
        private List<String> tags;
        private String couleur;
        private String bio;
        private String telephone;
        private String ville;
        private Integer quantite;
    }

    /**
     * Classe SampleUser pour dataTable et dataView
     */
    @Data
    public static class SampleUser implements Serializable {
        private String nom;
        private String email;
        private Boolean actif;

        public SampleUser(String nom, String email, Boolean actif) {
            this.nom = nom;
            this.email = email;
            this.actif = actif;
        }
    }

    /**
     * Classe NodeData pour tree et treeTable
     */
    @Data
    public static class NodeData implements Serializable {
        private String label;
        private String type;

        public NodeData(String label, String type) {
            this.label = label;
            this.type = type;
        }
    }

    /**
     * Classe FormDialogData pour formDialog
     */
    @Data
    public static class FormDialogData implements Serializable {
        private String nom;
        private String email;
    }
}
