<template>
    <div>
        <!-- Meta form -->
        <fieldset class="ie-fieldset">
            <legend>{{ messages.get("importexport", "ie_conv_datastructure_definition") }}</legend>
            <div class="row ie-row">
                <div class="colonne25">
                    <label for="dsName">{{ messages.get('importexport', 'ie_ds_name') }}</label>
                </div>
                <div class="colonne75">
                    <input required type="text" id="dsName" class="saisie-50em" v-model="localDs.dataStructureName" />
                </div>
            </div>
            <div class="row ie-row">
                <div class="colonne25">
                    <label for="dsComment">{{ messages.get('importexport', 'ie_ds_comment') }}</label>
                </div>
                <div class="colonne75">
                    <textarea id="dsComment" v-model="localDs.dataStructureComment" cols="62" rows="3"></textarea>
                </div>
            </div>
            <div class="row ie-row">
                <div class="colonne25">
                    <label>{{ messages.get('importexport', 'ie_ds_format') }}</label>
                </div>
                <div class="colonne75">
                    <select class="ie-select" v-model="localDs.dataStructureFormat">
                        <option v-for="fmt in formats" :key="fmt.id" :value="fmt.id">{{ fmt.label }}</option>
                    </select>
                </div>
            </div>
            <div class="ie-ds-import-btn-bar">
                <button type="button" class="bouton" @click="openImportModal">
                    {{ messages.get('importexport', 'ie_ds_import_structure') }}
                </button>
            </div>
        </fieldset>


        <!-- Structure hi�rarchique -->
        <div class="ie-ds-card">
            <div class="ie-ds-card-header">
                <span>{{ messages.get('importexport', 'ie_ds_tree_card') }}</span>
                <span class="ie-ds-tree-stats">
                    {{ nodeCount }} {{ messages.get('importexport', 'ie_ds_stats_nodes') }}
                    - {{ treeDepth }} {{ messages.get('importexport', 'ie_ds_stats_depth') }}
                </span>
            </div>
            <div class="ie-ds-card-body">
                <!-- Toolbar -->
                <div class="ie-ds-tree-toolbar">
                    <button type="button" class="bouton"
                        @click="expandAll">{{ messages.get('importexport', 'ie_ds_expand_all') }}</button>
                    <button type="button" class="bouton"
                        @click="collapseAll">{{ messages.get('importexport', 'ie_ds_collapse_all') }}</button>
                    <label class="ie-ds-expert-label">
                        <input type="checkbox" v-model="expertMode" />
                        {{ messages.get('importexport', 'ie_ds_expert_mode') }}
                    </label>
                </div>

                <!-- Tree -->
                <div class="ie-ds-tree" v-if="tree.length">
                    <tree-node v-for="node in tree" :key="node.id" :node="node" :selected-id="selectedId"
                        :format="localDs.dataStructureFormat" :expert-mode="expertMode" :is-root="true"
                        @select="selectNode" @add-child="addChild" @delete="deleteNode"></tree-node>
                </div>
            </div>
        </div>

        <!-- Modale import de structure -->
        <div class="ie-ds-modal-overlay" v-if="showImportModal" @click.self="showImportModal = false">
            <div class="ie-ds-modal">
                <div class="ie-ds-modal-header">
                    <span>{{ messages.get('importexport', 'ie_ds_import_structure') }}</span>
                    <button type="button" class="ie-ds-modal-close" @click="showImportModal = false">
                        <i class="fa fa-times" aria-hidden="true"></i>
                    </button>
                </div>
                <div class="ie-ds-modal-body">
                    <div class="ie-ds-source-tabs">
                        <div class="ie-ds-source-tab" :class="{ active: sourceMode === 'file' }"
                            @click="sourceMode = 'file'">
                            {{ messages.get('importexport', 'ie_ds_source_file') }}
                        </div>
                        <div class="ie-ds-source-tab" :class="{ active: sourceMode === 'template' }"
                            @click="sourceMode = 'template'" v-if="filteredTemplates.length">
                            {{ messages.get('importexport', 'ie_ds_source_template') }}
                        </div>
                    </div>
                    <div class="ie-ds-modal-content">
                        <file-analyzer v-if="sourceMode === 'file'" :format="localDs.dataStructureFormat"
                            @analyzed="applyTree"></file-analyzer>
                        <template-selector v-if="sourceMode === 'template'" :templates="filteredTemplates"
                            @selected="applyTree"></template-selector>
                    </div>
                </div>
            </div>
        </div>

        <!-- Action buttons : a gauche Annuler/Enregistrer, a droite Supprimer. -->
        <div class="row ie-row">
            <div class="left">
                <input type="button" class="bouton" :value="messages.get('common', 'cancel')" @click="cancel" />
                <input type="button" class="bouton" :value="messages.get('common', 'submit')" @click="save" />
            </div>
            <div class="right" v-if="localDs.id">
                <input type="button" class="bouton" :value="messages.get('common', 'remove')" @click="remove" />
            </div>
        </div>
    </div>
</template>

<script>
import treeNode from "./treeNode.vue";
import fileAnalyzer from "./fileAnalyzer.vue";
import templateSelector from "./templateSelector.vue";

function uuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
        const r = Math.random() * 16 | 0;
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
}

function makeNode(name = '', parentId = '', position = 0) {
    return { id: uuid(), name, description: '', repeatable: false, required: false, isAttribute: false, position, parentId, children: [] };
}

function countNodes(nodes) {
    return nodes.reduce((acc, n) => acc + 1 + countNodes(n.children || []), 0);
}

function calcDepth(nodes, level = 0) {
    if (!nodes || !nodes.length) return level;
    return Math.max(...nodes.map(n => calcDepth(n.children || [], level + 1)));
}

function findNode(nodes, id) {
    for (const n of nodes) {
        if (n.id === id) return n;
        const f = findNode(n.children || [], id);
        if (f) return f;
    }
    return null;
}

function findParent(nodes, id) {
    for (const n of nodes) {
        if (n.children) {
            const idx = n.children.findIndex(c => c.id === id);
            if (idx !== -1) return { parent: n, index: idx };
            const r = findParent(n.children, id);
            if (r) return r;
        }
    }
    return null;
}

function setCollapsed(vm, nodes, value) {
    nodes.forEach(n => {
        vm.$set(n, '_collapsed', value);
        if (n.children && n.children.length) setCollapsed(vm, n.children, value);
    });
}

export default {
    components: { treeNode, fileAnalyzer, templateSelector },
    props: {
        dataStructure: { type: Object, required: true },
        initialTree: { type: Array, default: () => [] },
        formats: { type: Array, default: () => [] },
        templates: { type: Array, default: () => [] },
        initialExpertMode: { type: Boolean, default: false }
    },
    data() {
        return {
            localDs: { ...this.dataStructure },
            tree: this.initialTree.length
                ? JSON.parse(JSON.stringify(this.initialTree))
                : [makeNode('racine', '', 0)],
            selectedId: '',
            showImportModal: false,
            sourceMode: 'file',
            expertMode: this.initialExpertMode
        };
    },
    computed: {
        nodeCount() { return countNodes(this.tree); },
        treeDepth() { return calcDepth(this.tree); },
        /**
         * @returns {Array} Modeles dont formats inclut le format de la structure
         */
        filteredTemplates() {
            if (!this.localDs.dataStructureFormat) return this.templates;
            return this.templates.filter(t => Array.isArray(t.formats) && t.formats.includes(this.localDs.dataStructureFormat));
        }
    },
    methods: {
        selectNode(id) {
            this.selectedId = (this.selectedId === id) ? '' : id;
        },

        addChild(parentId) {
            const parent = findNode(this.tree, parentId);
            if (!parent) return;
            const child = makeNode('', parentId, parent.children.length);
            parent.children.push(child);
            this.selectedId = child.id;
        },


        deleteNode(nodeId) {
            if (this.selectedId === nodeId) this.selectedId = '';
            const result = findParent(this.tree, nodeId);
            if (!result) return;
            result.parent.children.splice(result.index, 1);
        },

        openImportModal() {
            this.sourceMode = 'file';
            this.showImportModal = true;
        },

        applyTree(newTree) {
            this.tree = JSON.parse(JSON.stringify(newTree));
            this.selectedId = '';
            this.showImportModal = false;
        },

        expandAll() { setCollapsed(this, this.tree, false); },
        collapseAll() { setCollapsed(this, this.tree, true); },

        cancel() {
            document.location = './import_export.php?categ=data_structures';
        },

        async save() {
            this.showLoader();

            // 1. Enregistrement des m�tadonn�es (cr�e ou met � jour)
            const metaRes = await this.ws.post('dataStructures', 'save', this.localDs);
            if (metaRes.error) {
                this.hiddenLoader();
                this.notif.error(metaRes.errorMessage);
                return;
            }

            const isNew = !this.localDs.id;
            if (isNew) {
                this.localDs.id = metaRes.id;
            }
            // Resynchronise la version (verrou optimiste E3, incrementee cote
            // serveur) : cet ecran reste actif apres un enregistrement reussi
            // (pas de rechargement pour une structure existante).
            this.localDs.version = metaRes.version;

            // 2. Enregistrement de l'arbre dans le store RDF (avec l'id d�sormais connu)
            const treeRes = await this.ws.post('dataStructures', 'saveTree', {
                id: this.localDs.id,
                tree: this.tree,
                mode: this.expertMode ? 'expert' : 'simple'
            });
            this.hiddenLoader();

            if (treeRes.error) {
                this.notif.error(this.messages.get('common', 'failed_save'));
                return;
            }

            if (isNew) {
                document.location = './import_export.php?categ=data_structures&action=edit&id=' + this.localDs.id;
            } else {
                this.notif.info(this.messages.get('common', 'success_save'));
            }
        },

        async remove() {
            if (!confirm(this.messages.get('importexport', 'ie_ds_remove_confirm'))) return;
            this.showLoader();
            const res = await this.ws.post('dataStructures', 'remove', { id: this.localDs.id, version: this.localDs.version });
            this.hiddenLoader();
            if (!res.error) {
                document.location = './import_export.php?categ=data_structures';
            } else {
                this.notif.error(res.errorMessage);
            }
        }
    }
}
</script>
