import Reflux from 'reflux';
import WikiActions from './WikiActions.jsx';
import _ from 'lodash';

import dataAccess from '../service/dataAccess.jsx';
import {urls} from '../constants.jsx';

import utilMethods from '../utils/util.jsx';
import urlSyncer from '../utils/url-syncer.jsx';

import {ScrollActions as SA} from './sidebar-scroll-position-store.jsx';

var util = {
    setExpanded(target, isExpanded, childCallback) {
        target.expanded = isExpanded;
        target.children && target.children.forEach(
                child => {
                if (typeof child == 'object') {
                    childCallback && childCallback(child);
                }
            }
        );
    },

    traverseNodes(treeNode, traverseCallback, index = 0, list = [treeNode], parent = {}) {
        traverseCallback(treeNode, index, list, parent);

        treeNode.children && treeNode.children.forEach(
            (child, index) =>
                this.traverseNodes(child, traverseCallback,
                    index, treeNode.children, treeNode)
        );
    },

    traverseParents(treeNode, traverseCallback) {
        traverseCallback(treeNode.parent, treeNode);

        if (treeNode.parent) {
            this.traverseParents(treeNode.parent, traverseCallback);
        }
    }
};

_.extend(util, utilMethods);

dataAccess.checkBuildTime();


var rawQueryActions = Reflux.createActions({
    queryTree: 1,
    queryTags: 1,
    queryBackLinks: 1,
});

var fileTreeStore = Reflux.createStore({
    listenables: [WikiActions],

    // whole app share the same store ... ??
    _store: {},
    treeHash: {},
    backLinks: {},

    // START of ACTION ZONE: on actions triggered
    onToggleExpandingStatus(node) {
        node.expanded = !node.expanded;

        this.update();
    },
    // END of ACTIONS ZONE

    /**
     *
     * @param path
     * @returns {fileNode}
     */
    selectFileNodeViaPath(path) {
        // 控制点击后的高亮
        path = path && path.replace(/^\//, '');
        var currNode = this.treeHash[path];

        util.traverseNodes(this._store.fileTree,
                currNode => currNode.selected = false
        );
        currNode.selected = true;

        util.traverseParents(currNode, parent => parent && (parent.expanded = true));

        SA.scrollTo(path);

        this.update();
    },

    switchToFileViaTag(tag) {
        var targetTag = this._store.tags[tag];
        if (targetTag) {
            console.log(targetTag);

            //<<[ #数据结构 定义跳转页面的对象格式 ]{jzrxj_esbwddvt_ihx1h0sw}>>
            this._store.currentContentUrl = {
                path: targetTag.path,
                hash: {
                    tag: tag
                }
            };

            this.selectFileNodeViaPath(targetTag.path);

            this.update();
        } else {
            alert('木有找到对应的标记.');
        }
    },

    switchToFileViaLink(linkTag, linkSeq) {
        var backLinkGroup = this.backLinks[linkTag];

        if (backLinkGroup) {
            var backLink = backLinkGroup[linkSeq];
            if (backLink) {
                this._store.currentContentUrl = {
                    path: backLink.path,
                    hash: {
                        linkTag: linkTag,
                        linkSeq: linkSeq,
                    }
                };

                this.selectFileNodeViaPath(backLink.path);

                this.update();
                return
            }
        }
        alert('木有找到对应的链接.');
    },

    switchToFileViaPath(path) {
        this._store.currentContentUrl = path;
        this.selectFileNodeViaPath(path);

        this.update();
    },
    // START of WIKI ACTIONS

    // 内容跳转的入口在这下面的几个Clicked方法中 @[  wiki url 同步  ]{jzrxj_zeuhpxrb_ii2rfkic}@
    onSelectFileNode(node) {
        if (!node.index) {
            // node 没有 index时, 说明它没有可以供阅读的页面入口
            return;
        }

        urlSyncer.updateUrlHash({
            path: node.path + '/' + node.index
        });
    },

    onWikiLinkClicked(params) {
        urlSyncer.updateUrlHash({
            tag: params.tag
        });
    },

    onWikiBackLinkClicked(params) {
        urlSyncer.updateUrlHash({
            linkTag: params.tag,
            linkSeq: params.seq,
        });
    },

    // END of WIKI ACTIONS
    init() {

        this._store = {
            tags: {},
            fileTree: {
                children: []
            },
            currentContentUrl: // '', //'%E4%BB%BB%E5%8A%A1/%E5%AD%90%E4%BB%BB%E5%8A%A1/requirements.md',
                urls.homePage,
            buildTime: dataAccess.getBuildTime()
        };

        this.joinLeading(
            rawQueryActions.queryBackLinks,
            rawQueryActions.queryTags,
            rawQueryActions.queryTree,
            this.handleUrlHashChangedInitial
        );

        this.initStoreData();

        urlSyncer.onUrlHashChanged(paramObject => this.handleUrlHashChanged(paramObject));
    },
    update(store) {
        if (store) {
            this._store = store;
        }
        this.trigger(this._store);
    },
    updateFileTree(fileTree) {
        this._store.fileTree = fileTree;
        this.update();
    },

    // 第一次, 需要考虑path这个问题
    handleUrlHashChangedInitial() {
        var paramObject = util.parseHashParams();
        this.handleUrlHashChanged(paramObject);
    },

    handleUrlHashChanged(paramObject) {
        if (paramObject.tag) {
            // 需要更新文件树 @[  wiki url 同步  ]{jzrxj_zeuhpxrb_ii2rfkic}@
            this.switchToFileViaTag(paramObject.tag);
        } else if (paramObject.linkTag) {
            this.switchToFileViaLink(paramObject.linkTag, paramObject.linkSeq);
        } else if (paramObject.path) {
            this.switchToFileViaPath(paramObject.path);
        } else {
            this.switchToFileViaPath(urls.homePage);
        }
    },

    initFileTree() {
        dataAccess.getFileTree()
            .done(fileTree => {
                fileTree.isRoot = true;
                fileTree.path = '/';
                fileTree.selected = true;

                util.setExpanded(fileTree, true,
                        child => {
                        var allOthers = other => util.setExpanded(other, false, allOthers);
                        util.setExpanded(child, true, allOthers);
                    }
                );

                util.traverseNodes(fileTree,
                    (currNode, index, list, parent) => {
                        if (typeof currNode == 'string') {
                            currNode = list[index] = {
                                isFile: true,
                                name: currNode.replace(/\.md$/, ''),
                                dirpath: parent.path,
                                path: parent.path,
                                index: currNode
                            };
                        } else {
                            currNode.path = currNode.path ? currNode.path.replace(/^\//, '') : '';
                        }

                        currNode.parent = parent;

                        this.treeHash[(currNode.path ? currNode.path + '/' : '') + currNode.index] = currNode;
                    }
                );

                console.log(fileTree);

                this.updateFileTree(fileTree);

                rawQueryActions.queryTree();
            });
    },
    initBackLinks() {
        dataAccess.getBackLinks()
            .done(backLinks => {
                this.backLinks = backLinks;
                rawQueryActions.queryBackLinks();
            });
    },
    initTags() {
        dataAccess.getTags()
            .done(tags => {
                this._store.tags = tags;
                rawQueryActions.queryTags();
            });
    },
    initStoreData() {
        this.initFileTree();
        this.initTags();
        this.initBackLinks();
    },
    getInitialState() {
        return this._store
    }
});

export default fileTreeStore;