var React           = window.React = require('react'), // assign it to window for react chrome extension
    SearchBar       = require('./searchbar.jsx'),
    PluginList      = require('./pluginlist.jsx'),
    App             = {};

var Constants = {
    DownloadCountBatch: 100,
    NpmSearchInitialSize: 500
}

window.addEventListener('popstate', function(e) {
    if(e.state) {
        var appInstance = React.render(<App />, document.getElementById('container'));
        appInstance.loadFilterText(e.state.filterText);
    }
});

var App = React.createClass({
    getInitialState: function() {
        var q = App.getURLParameter('q');
        if (q) {
            return {
                plugins: [],
                filterText: q,
                placeHolderText: 'Loading...'
            }
        } else {
            return {
                plugins: [],
                filterText: '',
                placeHolderText: 'Loading...'
            };
        }
    },
    handleUserInput: function(filterText) {
        this.setState({
            filterText: filterText
        });
    },
    addCondition: function(condition) {
        this.setState(function(previousState, currentProps) {
            if(previousState.filterText.indexOf(condition) > -1) {
                return {
                    filterText: previousState.filterText,
                    plugins: previousState.plugins
                };
            }
            else {
                return {
                    filterText: previousState.filterText.trim() + ' ' + condition + ' ',
                    plugins: previousState.plugins
                };
            }
        });
    },
    loadFilterText : function(filterText) {
        this.setState(function(previousState, currentProps) {
            return {
                filterText: filterText,
                plugins: previousState.plugins
            };
        });
    },
    statics: {
        getURLParameter : function(name) {
            return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)
                ||[,""])[1].replace(/\+/g, '%20'))||null;
        },
        shallowCopy: function(src) {
            var dst = {};
            for(var i in src) {
                if(src.hasOwnProperty(i)) {
                    dst[i] = src[i];
                }
            }
            return dst;
        }
    },
    componentDidMount: function() {
        var plugins = [],
            officialPlugins = require('./official-plugins.json').plugins,
            blacklistedPlugins = require('./blacklisted-plugins.json').plugins,
            pluginCount = 0,
            self = this,
            queryHost = "http://npmsearch.com/query",
            queryFields = "fields=name,keywords,license,description,author,modified,homepage,version",
            queryKeywords = "q=keywords:%22ecosystem:cordova%22",
            queryInitialSize = Constants.NpmSearchInitialSize;

        xhrRequest(queryHost + "?" + queryFields + "&" + queryKeywords + "&size=" + queryInitialSize + "&start=0", function(xhrResult) {
            plugins = xhrResult.results;
            pluginCount = xhrResult.total;
            if (pluginCount <= queryInitialSize) {
                processPlugins.bind(self, officialPlugins, plugins)();
            } else {
                xhrRequest(queryHost + "?" + queryFields + "&" + queryKeywords + "&size=" + (pluginCount - queryInitialSize) + "&start=" + queryInitialSize, function(xhrResult) {
                        plugins = [].concat(plugins, xhrResult.results);
                        processPlugins.bind(self, officialPlugins, plugins)();
                }, function() { console.log('xhr err'); });
            }
        }, function() { console.log('xhr err'); });

        var getDownloadCount = function(plugins, that) {
            var packageNames = "";
            for(var index=0; index < plugins.length; index++) {
                packageNames += plugins[index].name + ",";
                if(index % Constants.DownloadCountBatch === 0 || index === plugins.length -1) {
                    xhrRequest("https://api.npmjs.org/downloads/point/last-month/" + packageNames, function(xhrResult) {
                        for(var j = 0; j < plugins.length; j++) {
                            if(xhrResult[plugins[j].name]) {
                                plugins[j] = App.shallowCopy(plugins[j]);
                                plugins[j].downloadCount = xhrResult[plugins[j].name].downloads;
                            }
                        }
                        that.setState({
                            plugins: plugins
                        });
                    }.bind(self), function() { console.log('xhr err'); });
                    packageNames = "";
                }
            }
        }

        function processPlugins(officialPlugins, plugins) {
            var pluginCount = plugins.length,
                dateNow = new Date(),
                oneDay = 1000*60*60*24;

            officialPlugins.forEach(function(plugin) {
                for (var i = 0; i < plugins.length; i++) {
                    // Check if plugin name is in official list
                    if (plugins[i].name[0] === plugin) {
                        plugins[i].isOfficial = true;
                        return;
                    }
                };
            });

            for(var i = plugins.length -1; i >= 0 ; i--)
            {
                for(var j = 0; j < blacklistedPlugins.length; j++)
                {
                    if(plugins[i].name[0] === blacklistedPlugins[j])
                    {
                        plugins.splice(i, 1);
                        break;
                    }
                }
            }

            for (var i = 0; i < plugins.length; i++) {
                // Calculate last time plugin is modified (in days)
                plugins[i].modified = Math.ceil((dateNow - new Date(plugins[i].modified)) / oneDay);
            };

            if (this.isMounted()) {
                var q = App.getURLParameter('q');
                if(q) {
                    this.setState({
                        plugins: plugins,
                        filterText: q,
                        placeHolderText: 'Search ' + pluginCount + ' plugins...'
                    });
                }
                else {
                    this.setState({
                        plugins: plugins,
                        placeHolderText: 'Search ' + pluginCount + ' plugins...'
                    });
                }
                getDownloadCount(plugins,this);
            }
        }
    },
    render: function() {
        return (
            <div>
                <div id="headblock">
                        <div id="topcontent">
                            <div id="pluggy"></div>
                            <div id="discovermessage"><h1>Search Cordova Plugins</h1></div>
                        </div>
                    <SearchBar
                        initialValue={this.state.filterText}
                        placeHolderText={this.state.placeHolderText}
                        onUserInput={this.handleUserInput}
                    />
                </div>
                <PluginList
                    plugins={this.state.plugins}
                    filterText={this.state.filterText}
                />
            </div>
        );
    }
});

App.start = function() {
    React.render(<App />, document.getElementById('container'));
};

function xhrRequest(url, success, fail) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState == XMLHttpRequest.DONE ) {
            if(xhr.status == 200){
                success(JSON.parse(xhr.responseText));
                return;
            } else {
                fail();
                return;
            }
        }
    }.bind(this)
    xhr.open("GET", url, true);
    xhr.send();
}

module.exports = window.App = App;
