/* BdfServer_HtmlProducers - Copyright (c) 2010-2024 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package fr.exemole.bdfserver.htmlproducers.sphere;

import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.api.interaction.Domains;
import fr.exemole.bdfserver.api.interaction.GetConstants;
import fr.exemole.bdfserver.api.interaction.domains.SphereDomain;
import fr.exemole.bdfserver.api.managers.PermissionManager;
import fr.exemole.bdfserver.html.BdfHtmlConstants;
import fr.exemole.bdfserver.html.BdfHtmlUtils;
import fr.exemole.bdfserver.html.BdfServerHtmlProducer;
import fr.exemole.bdfserver.html.consumers.Button;
import fr.exemole.bdfserver.html.consumers.PageUnit;
import fr.exemole.bdfserver.html.consumers.attributes.Deploy;
import fr.exemole.bdfserver.html.jslib.BdfJsLibs;
import fr.exemole.bdfserver.tools.BH;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.permission.PermissionSummary;
import net.fichotheque.sphere.Redacteur;
import net.fichotheque.sphere.Sphere;
import net.fichotheque.utils.FichothequeUtils;
import net.mapeadores.util.html.HA;


/**
 *
 * @author Vincent Calame
 */
public class SphereHtmlProducer extends BdfServerHtmlProducer {

    private final PermissionSummary permissionSummary;
    private final Sphere sphere;
    private final SortedMap<String, Redacteur> activeMap = new TreeMap<String, Redacteur>();
    private final SortedMap<String, Redacteur> readonlyMap = new TreeMap<String, Redacteur>();
    private final SortedMap<String, Redacteur> inactiveMap = new TreeMap<String, Redacteur>();
    private final boolean isSubsetAdmin;
    private final Button linkButton = Button.link();
    private final PermissionManager permissionManager;

    public SphereHtmlProducer(BdfParameters bdfParameters, Sphere sphere) {
        super(bdfParameters);
        this.permissionSummary = bdfParameters.getPermissionSummary();
        this.isSubsetAdmin = permissionSummary.isSubsetAdmin(sphere.getSubsetKey());
        this.sphere = sphere;
        this.permissionManager = bdfParameters.getBdfServer().getPermissionManager();
        addJsLib(BdfJsLibs.SUBSETCHANGE);
        addThemeCss("sphere.css");
        setBodyCssClass("global-body-ListFrame");
        initMaps();
    }

    @Override
    public void printHtml() {
        start(FichothequeUtils.getTitle(sphere, workingLang), true);
        this
                .__(BdfHtmlUtils.startSubsetUnit(this, bdfParameters, sphere, SphereDomain.SPHERE_PAGE))
                .__(printCommands())
                .__(PageUnit.END)
                .__(printMap(activeMap, "_ title.sphere.userlist_active", "sphere-Active"))
                .__(printMap(readonlyMap, "_ title.sphere.userlist_readonly", "sphere-Readonly"))
                .__(printMap(inactiveMap, "_ title.sphere.userlist_inactive", "sphere-Inactive"));
        end();
    }

    private boolean printCommands() {
        if (!isSubsetAdmin) {
            return false;
        }
        this
                .DETAILS(HA.id("details_commands").open(true).classes("tools-Details").populate(Deploy.DETAILS))
                .SUMMARY()
                .__localize("_ title.global.commands")
                ._SUMMARY()
                .DIV("tools-List")
                .__if(permissionSummary.isFichothequeAdmin(), link("action-New", SphereDomain.REDACTEUR_CREATIONFORM_PAGE, "_ link.sphere.usercreationform"))
                .__(link("action-Metadata", SphereDomain.SPHERE_METADATAFORM_PAGE, "_ link.sphere.spheremetadataform"))
                .__(link("action-Advanced", SphereDomain.SPHERE_ADVANCEDCOMMANDS_PAGE, "_ link.sphere.sphereadvancedcommands"))
                .__(link("action-Refresh", SphereDomain.SPHERE_PAGE, "_ link.global.reload"))
                .__(Button.link(GetConstants.USERS_ROOT + "/" + sphere.getSubsetName() + ".ods").action("action-Ods").textMessage("_ link.global.version", "ODS"))
                ._DIV()
                ._DETAILS();
        return true;
    }

    private Button link(String action, String page, String messageKey) {
        String href = BH.domain(Domains.SPHERE).subset(sphere).page(page).toString();
        String target;
        if (page.equals(SphereDomain.SPHERE_PAGE)) {
            target = null;
        } else {
            target = BdfHtmlConstants.EDITION_FRAME;
        }
        return linkButton.href(href).action(action).textL10nObject(messageKey).target(target);
    }

    private boolean printMap(Map<String, Redacteur> map, String titleKey, String cssClasses) {
        if (map.isEmpty()) {
            return false;
        }
        this
                .__(PageUnit.start().sectionCss("unit-Unit sphere-RedacteurListUnit " + cssClasses).title(() -> {
                    this
                            .SPAN("sphere-RedacteurListTitle")
                            .__localize(titleKey)
                            .__space()
                            .__(BdfHtmlUtils.printItemCount(this, bdfUser, map.size()))
                            ._SPAN();
                    if ((cssClasses.equals("sphere-Active")) && (permissionSummary.isFichothequeAdmin())) {
                        this
                                .__(Button.link().style(Button.TRANSPARENT_STYLE)
                                        .href(BH.domain(Domains.SPHERE).subset(sphere).page(SphereDomain.REDACTEUR_CREATIONFORM_PAGE))
                                        .action("action-New")
                                        .tooltipMessage("_ link.sphere.usercreationform")
                                        .target(BdfHtmlConstants.EDITION_FRAME));
                    }
                }))
                .UL("subsetitem-List")
                .__(printRedacteurList(map))
                ._UL()
                .__(PageUnit.END);
        return true;
    }

    private boolean printRedacteurList(Map<String, Redacteur> map) {
        for (Map.Entry<String, Redacteur> entry : map.entrySet()) {
            this
                    .LI()
                    .__(printRedacteur(entry.getKey(), entry.getValue()))
                    ._LI();
        }
        return true;
    }

    private boolean printRedacteur(String login, Redacteur redacteur) {
        boolean editable = permissionSummary.isFichothequeAdmin();
        this
                .DIV("subsetitem-Title")
                .P()
                .SPAN("sphere-Login")
                .__escape(login)
                ._SPAN()
                .__dash()
                .__escape(redacteur.getCompleteName())
                .__(printAdmin(redacteur))
                ._P()
                .__(printUserEdit(editable, redacteur))
                ._DIV()
                .__(printCommandDetails(editable, redacteur));
        return true;
    }

    private boolean printAdmin(Redacteur redacteur) {
        if (permissionManager.isAdmin(redacteur)) {
            this
                    .__space()
                    .SPAN(HA.classes("sphere-Admin").title(getLocalization("_ label.sphere.admin")))
                    .__escape("🅐")
                    ._SPAN();
            return true;
        } else {
            return false;
        }
    }

    private boolean printUserEdit(boolean editable, Redacteur redacteur) {
        if (!editable) {
            return false;
        }
        this
                .A(HA.href(BH.domain(Domains.SPHERE).subsetItem(redacteur).page(SphereDomain.REDACTEUR_ADMINFORM_PAGE)).target(BdfHtmlConstants.EDITION_FRAME).classes("button-Circle action-UserEdit"))
                .__(Button.ICON)
                ._A();
        return true;
    }

    private boolean printCommandDetails(boolean editable, Redacteur redacteur) {
        if (!editable) {
            return false;
        }
        this
                .DETAILS("tools-Details")
                .SUMMARY()
                .__localize("_ title.global.commands")
                ._SUMMARY()
                .DIV("tools-List")
                .__if((!redacteur.isInactive()), redacteurLink(redacteur, "action-Preferences", SphereDomain.REDACTEUR_PREFERENCES_PAGE, "_ link.sphere.userprefs"))
                .__(redacteurLink(redacteur, "action-UserStats", SphereDomain.REDACTEUR_STATS_PAGE, "_ link.sphere.userstats"))
                .__(redacteurLink(redacteur, "action-Advanced", SphereDomain.REDACTEUR_ADVANCEDCOMMANDS_PAGE, "_ link.sphere.redacteuradvancedcommands"))
                ._DIV()
                ._DETAILS();
        return true;
    }

    private Button redacteurLink(Redacteur redacteur, String action, String page, String locKey) {
        String href = BH.domain(Domains.SPHERE).page(page).subsetItem(redacteur).toString();
        return linkButton.href(href).action(action).textL10nObject(locKey).target(BdfHtmlConstants.EDITION_FRAME);
    }

    private void initMaps() {
        for (Redacteur redacteur : sphere.getRedacteurList()) {
            Map<String, Redacteur> map = getMap(redacteur);
            map.put(redacteur.getLogin(), redacteur);
        }
    }

    private Map<String, Redacteur> getMap(Redacteur redacteur) {
        switch (redacteur.getStatus()) {
            case FichothequeConstants.INACTIVE_STATUS:
                return inactiveMap;
            case FichothequeConstants.READONLY_STATUS:
                return readonlyMap;
            default:
                return activeMap;
        }
    }

}
