import downloadjs from 'downloadjs';
import lodash, { concat } from 'lodash';
import cleandeep from 'clean-deep';
import { XmlConverter } from "@/libs/xml-converter/xml-converter";

import { get } from 'svelte/store';
import { storeThemeKeywords, storeInspireKeywords } from "@/stores/mdjs.store";
const converter = new XmlConverter();

function downloadXml(data, filename) {
    downloadjs(data, filename, 'text/xml');
}

function formatDate(value, type) {

    if (type=="datetime") {
        // console.log(value.toISOString());
        return value.toISOString();
    } else {
        var dd = value.getDate();
        var mm = value.getMonth() + 1;
        var yyyy = value.getFullYear();
        if (dd < 10) {
            dd = '0' + dd;
        }
        if (mm < 10) {
            mm = '0' + mm;
        }
        return yyyy + '-' + mm + '-' + dd;
    }
}

function mergeKeywords(keywordsList, isGeoData) {
    isGeoData = isGeoData || false;
    var keywords = [];
    if (keywordsList.length) {
        var thesaurusDone = [];
        for (var i = 0; i < keywordsList.length; i++) {
            // Use concatenation as code for 'block'
            const thesaurusName1 = converter.getValue(keywordsList[i], "thesaurusName")[0] ? converter.getValue(keywordsList[i], "thesaurusName")[0].toLowerCase() : "";
            const thesaurusDatePublication1 = converter.getValue(keywordsList[i], "thesaurusDatePublication")[0];
            const keywordType1 = converter.getValue(keywordsList[i], "keywordType")[0];
            const block1 = thesaurusName1 + thesaurusDatePublication1 + keywordType1;
            if (!thesaurusDone.includes(block1)) {
                var keywords1 = converter.getValue(keywordsList[i], "keyword");
                for (var j = 0; j < keywordsList.length; j++) {
                    const thesaurusName2 = converter.getValue(keywordsList[j], "thesaurusName")[0] ? converter.getValue(keywordsList[j], "thesaurusName")[0].toLowerCase() : "";
                    const thesaurusDatePublication2 = converter.getValue(keywordsList[j], "thesaurusDatePublication")[0];
                    const keywordType2 = converter.getValue(keywordsList[j], "keywordType")[0];
                    const block2 = thesaurusName2 + thesaurusDatePublication2 + keywordType2;
                    if (
                        i !== j &&
                        lodash.isEqual(block1, block2)
                    ) {
                        var keywords2 = converter.getValue(keywordsList[j], "keyword");
                        keywords1 = keywords1.concat(keywords2);
                    }
                }
                // Get unique keywords from list
                keywords1.map((val) => val.trim());
                keywords1 = keywords1.filter(
                    (v, i) => v && keywords1.indexOf(v) === i
                );
                // If Inspire thesaurus keep it only if isGeoData = true
                if ((isGeoData) || (!isGeoData && !thesaurusName1.includes("inspire"))) {
                    keywords.push(
                        converter.setValue(keywordsList[i], "keyword", keywords1)
                    );
                }
                thesaurusDone.push(block1);
            }
        }
    } else if (!keywordsList.length) {
        keywords.push({});
    }
    return keywords;
}

function checkOtherRestrictions() {
    // TODO:
    // Récupérer les 'dataLegalOtherConstraints' et si 'dataLegalAccessInspireConstraints' existe (non vide ou null) vérifier qu'il y ait une fois et qu'une fois "otherRestrictions".
}

function checkTopicCategories(mdjs, inspireKeywords, inspireToIsoCode) {
    // Define topicCategory according to InspireKeyword value => add topicCategory from MD_InspireToIsoCode list
    // Récupérer topicCategories
    // Récupérer inspireKeywords (list)
    // si inspireKeywords non vide (~~et topicCategories vide~~) => ajouter dans topiccategories MD_InspireToIsoCode[inspireKeyword]
    // var inspireKeywordList = converter.getValue(inspireKeywords, 'dataInspireKeywordsList').filter(el => el);
    var inspireKeywordList = inspireKeywords.reduce((result, current) => {
        let newValues = converter.getValue(current, 'dataInspireKeywordsList').filter(el => el);
        return concat(result, newValues);
    }, []);
    var hasInspireKeywords = inspireKeywordList.length !== 0;
    // var hasTopicCategories = converter.getValue(mdjs, 'dataTopicCategories').filter(el => el).length !== 0;
    // if (hasInspireKeywords && !hasTopicCategories) {
    if (hasInspireKeywords) {
        var topicCategories = [];
        for (var i = 0; i < inspireKeywordList.length; i++) {
            topicCategories.push(inspireToIsoCode[inspireKeywordList[i]]);
        }
        converter.setValue(mdjs, "dataTopicCategories", topicCategories);
    }
    return mdjs;
}

function updateDateStamp(mdjs, date) {
    return converter.setValue(mdjs, "mdDateStamp", [date]);
}

function generateXml(mdjs, isGeoData, api, org, localesView, isModel) {

    const themeKeywords = get(storeThemeKeywords);
    const inspireKeywords = get(storeInspireKeywords);

    isGeoData = isGeoData || false;
    const directory = api.url_base + org + "/";
    // Complérer les thèmes Inspire à partir de l'ISO
    const inspireToIsoCode = localesView.codelists.MD_InspireToIsoCode || [];
    mdjs = checkTopicCategories(mdjs, inspireKeywords, inspireToIsoCode);
    
    // Generate XML file
    // Define dataIdentiifer and mdFileIdentifier
    // var now = lodash.now();
    // const dataIdentifiersCodes = converter.getValue(mdjs, 'dataIdentifiersCodes').filter(el => el);
    // var dataId = dataIdentifiersCodes[0];
    // var fileId = converter.getValue(mdjs, 'mdFileIdentifier')[0];
    // if (dataId) {
    //     var newFileId = dataId;
    //     if (dataId.startsWith('http')) {
    //         newFileId = dataId.split('?')[0];
    //         newFileId = dataId.replace(/\/$/, '');
    //         newFileId = dataId.substr(dataId.lastIndexOf('/') + 1);
    //     }
    //     fileId = fileId || newFileId;
    // } else {
    //     if (fileId) {
    //         dataId = fileId
    //     } else {
    //         dataId = org + "-" + lodash.uniqueId(now + '-');
    //         fileId = dataId;
    //     }
    // }
    // mdjs = converter.setValue(mdjs, 'mdFileIdentifier', [fileId]);

    let oldFileId = null;
    if (isModel) {
        mdjs = converter.setValue(mdjs, 'mdFileIdentifier', [""]);
        fileId = "";
    } else {
        var now = lodash.now();
        const dataIdentifiersCodes = converter.getValue(mdjs, 'dataIdentifiersCodes').filter(el => el);
        var dataId = dataIdentifiersCodes[0];
        var fileId = converter.getValue(mdjs, 'mdFileIdentifier')[0];
        oldFileId = lodash.cloneDeep(fileId);
        if (dataId) {
            var fileId = dataId;
            if (dataId.startsWith('http')) {
                fileId = dataId.split('?')[0];
                fileId = dataId.replace(/\/$/, '');
                fileId = dataId.substr(dataId.lastIndexOf('/') + 1);
            }
        } else {
            if (fileId) {
                dataId = fileId
            } else {
                dataId = lodash.uniqueId(now + '-');
                fileId = dataId;
            }
        }
        mdjs = converter.setValue(mdjs, 'mdFileIdentifier', [fileId]);
        // console.log(124, fileId, converter.getValue(mdjs, "mdFileIdentifier"));
    
        // Get dataIdentifiers and check if contents "uuid" value, else add it (to empty value if exist)
        if (!dataIdentifiersCodes.includes(dataId)) {
            var newCode = converter.setValue({}, 'mdCode', [dataId]);
            var dataIdentifiers = converter.getValue(mdjs, 'dataIdentifiers')
            if (dataIdentifiersCodes.includes('')) {
                for (var i = 0; i < dataIdentifiers.length; i++) {
                    var code = converter.getValue(dataIdentifiers[i], 'code')
                    if (code == '') {
                        dataIdentifiers[i] = newCode;
                    }
                }
            } else {
                dataIdentifiers.unshift(newCode);
            }
            mdjs = converter.setValue(mdjs, 'dataIdentifiers', dataIdentifiers);
        }
    }


    // update URL path for uploaded files
    if (directory) {
        // browsegraphic URL
        let dataBrowseGraphics = converter.getValue(mdjs, localesView.fields.dataBrowseGraphics.name);
        for (let i=0, n=dataBrowseGraphics.length; i<n; i++) {
            let url = converter.getValue(dataBrowseGraphics[i], "fileName")[0];
            if (url) {
                url = url.replace('file:///', directory + fileId + "/" );
                if (oldFileId != fileId) {
                    url = url.replace(directory + oldFileId, directory + fileId);
                }
                dataBrowseGraphics[i] = converter.setValue(dataBrowseGraphics[i], 'fileName', [url]);
            }
        }
        mdjs = converter.setValue(mdjs, localesView.fields.dataBrowseGraphics.name, dataBrowseGraphics);

        // dataPointOfContacts logo URL
        var dataPointOfContacts = converter.getValue(mdjs, localesView.fields.dataPointOfContacts.name);
        for (let i=0, n=dataPointOfContacts.length; i<n; i++) {
            var url = converter.getValue(dataPointOfContacts[i], "logoUrl")[0];
            url = Array.isArray(url) ? url[0] : url;
            if (url) {
                url = url.replace('file:///', directory + fileId + "/" );
                if (oldFileId != fileId) {
                    url = url.replace(directory + oldFileId, directory + fileId);
                }
                dataPointOfContacts[i] = converter.setValue(dataPointOfContacts[i], 'logoUrl', [url]);
            }
        }
        mdjs = converter.setValue(mdjs, localesView.fields.dataPointOfContacts.name, dataPointOfContacts);

        // mdContacts logo URL
        let mdContacts = converter.getValue(mdjs, localesView.fields.mdContacts.name);
        for (let i=0, n=mdContacts.length; i<n; i++) {
            let url = converter.getValue(mdContacts[i], "logoUrl")[0];
            url = Array.isArray(url) ? url[0] : url;
            if (url) {
                url = url.replace('file:///', directory + fileId + "/" );
                if (oldFileId != fileId) {
                    url = url.replace(directory + oldFileId, directory + fileId);
                }
                mdContacts[i] = converter.setValue(mdContacts[i], 'logoUrl', [url]);
            }
        }
        mdjs = converter.setValue(mdjs, localesView.fields.mdContacts.name, mdContacts);

        // dataLinkages URL
        var dataLinkages = converter.getValue(mdjs, localesView.fields.dataLinkages.name);
        for (let i=0, n=dataLinkages.length; i<n; i++) {
            var url = converter.getValue(dataLinkages[i], "linkageUrl")[0];
            if (url) {
                url = url.replace('file:///', directory + fileId + "/" );
                if (oldFileId != fileId) {
                    url = url.replace(directory + oldFileId, directory + fileId);
                }
                dataLinkages[i] = converter.setValue(dataLinkages[i], 'linkageUrl', [url]);
            }
        }
        mdjs = converter.setValue(mdjs, localesView.fields.dataLinkages.name, dataLinkages);
    }

    // remove spatial informations if not geo data
    if (!isGeoData) {
        mdjs = converter.setValue(mdjs, 'dataSpatialRepresentationType', "");
        mdjs = converter.setValue(mdjs, 'dataScaleDenominator', "");
        mdjs = converter.setValue(mdjs, 'dataScaleDistance', "");
        mdjs = converter.setValue(mdjs, 'dataReferenceSystems', [{}]);
        mdjs = converter.setValue(mdjs, 'dataIdentifiers', [{}]);
        // converter.setValue(mdjs, 'dataInspireKeywords', [""]);
        // converter.setValue(mdjs, 'dataLegalAccessInspireConstraints', [""]);
    }

    // remove Inspire restriction code if not geo data
    // if (!isGeoData) {
    //     const inspireRestrictionCodes = localesView.codelists.MD_InspireRestrictionCode.map((value) => {
    //         return value.value;
    //     });
    //     var dataResourceConstraints = converter.getValue(mdjs, "dataResourceConstraints");
    //     for (var i = 0, n = dataResourceConstraints.length; i < n; i++) {
    //         var dataLegalAccessInspireConstraints = converter.getValue(
    //             dataResourceConstraints[i],
    //             "dataLegalAccessInspireConstraints"
    //         );
    //         var legalAccessInspireConstraints = [];
    //         for (var j = 0, m = dataLegalAccessInspireConstraints.length; j < m; j++) {
    //             if (!inspireRestrictionCodes.includes(dataLegalAccessInspireConstraints[j])) {
    //                 legalAccessInspireConstraints.push(dataLegalAccessInspireConstraints[j]);
    //             }
    //         }
    //     }
    //     converter.setValue(mdjs, 'dataIdentifiers', dataIdentifiers);
    // }


    // Merge keywords by thesaurus and type and remove inspire keywords if not isGeoData
    var keywords = converter.getValue(mdjs, 'dataKeywords');
    // keywords = mergeKeywords(keywords, isGeoData);
    keywords = mergeKeywords(concat(keywords, themeKeywords, inspireKeywords), isGeoData);
    mdjs = converter.setValue(mdjs, 'dataKeywords', keywords);

    // Update dateStamp
    mdjs = updateDateStamp(mdjs, formatDate(new Date(), "datetime"));

    //  Convert mdjs to xml
    const xml = converter.js2xml(cleandeep(mdjs), {compact: true, spaces: 4});

    return {
        mdjs: mdjs,
        uuid: fileId,
        oldFileId: oldFileId,
        isModel: isModel,
        xml: xml
    };
}

export default {
    downloadXml: downloadXml,
    generateXml: generateXml
}