var autosize = require('autosize');
require('whatwg-fetch');
require('element-closest');
require('classlist.js');
if (!('remove' in Element.prototype)) { // Firefox <23
    Element.prototype.remove = function() {
        if (this.parentNode) {
            this.parentNode.removeChild(this);
        }
    };
}

NodeList.prototype.forEach = Array.prototype.forEach;
HTMLCollection.prototype.forEach = Array.prototype.forEach;
    
var ws,
    pageTitle;

function initWS() {
    var content = document.getElementById('content');
    if (!content) { return }
    var pageMID = content.getAttribute('data-mid');
    if (!pageMID) { return }

    var url = (window.location.protocol === 'https:' ? 'wss' : 'ws') + ':'
            + (typeof juickDebug !== 'undefined' ?
                '//ws.juick.com/_replies' : ('//ws.juick.com/' + pageMID)),
        hash = document.getElementById('body').getAttribute('data-hash');

    if (hash) {
        url += '?hash=' + hash;
    }

    ws = new WebSocket(url);
    ws.onopen = function () {
        console.log('online');
        if (!document.querySelector('#wsthread')) {
            var d = document.createElement('div');
            d.id = 'wsthread';
            d.addEventListener('click', nextReply);
            document.querySelector('body').appendChild(d);
            pageTitle = document.title;
        }
    };
    ws.onclose = function () {
        console.log('offline');
        ws = false;
        setTimeout(function () {
            initWS();
        }, 2000);
    };
    ws.onmessage = function (msg) {
        if (msg.data == ' ') {
            ws.send(' ');
        } else {
            try {
                var jsonMsg = JSON.parse(msg.data);
                console.log('data: ' + msg.data);
                wsIncomingReply(jsonMsg);
            } catch (err) {
                console.log(err);
            }
        }
    };
    setInterval(wsSendKeepAlive, 90000);
}

function wsSendKeepAlive() {
    if (ws) {
        ws.send(' ');
    }
}

function wsShutdown() {
    if (ws) {
        ws.onclose = function () { };
        ws.close();
    }
}

function isTreeMode() {
    // relies on UserThread.printReplies implementation TODO keep this in cookie or something
    return document.querySelector('.title2-right > a').href.match(/\?view=(\w+)/)[1] == 'list';
}

function wsIncomingReply(msg) {
    var li = document.createElement('li');
    li.setAttribute('class', 'msg reply-new');
    li.setAttribute('id', msg.rid);
    li.addEventListener('click', newReply);
    li.addEventListener('mouseover', newReply);
    var msgAvatar = document.createElement('div');
    msgAvatar.setAttribute('class', 'msg-avatar');
    var msgAvatarLink = document.createElement('a');
    msgAvatarLink.setAttribute('href', '/' + msg.user.uname + '/');
    var msgAvatarImg = document.createElement('img');
    msgAvatarImg.setAttribute('src', '//i.juick.com/a/' + msg.user.uid + '.png');
    msgAvatarLink.appendChild(msgAvatarImg);
    msgAvatar.appendChild(msgAvatarLink);

    var msgCont = document.createElement('div');
    msgCont.setAttribute('class', 'msg-cont');
    var msgMenu = document.createElement('div');
    msgMenu.setAttribute('class', 'msg-menu');
    msgCont.appendChild(msgMenu);
    var msgMenuLink = document.createElement('a');
    msgMenuLink.setAttribute('href', '#');
    msgMenuLink.addEventListener('click', function (e) {
        showMessageLinksDialog(msg.mid, msg.rid);
        e.preventDefault();
    });
    msgMenu.appendChild(msgMenuLink);
    var msgHeader = document.createElement('div');
    msgHeader.setAttribute('class', 'msg-header');
    var msgHeaderLink = document.createElement('a');
    msgHeaderLink.setAttribute('href', '/' + msg.user.uname + '/');
    msgHeaderLink.textContent = '@' + msg.user.uname + ':';
    msgHeader.appendChild(msgHeaderLink);
    var msgTimestamp = document.createElement('div');
    msgTimestamp.setAttribute('class', 'msg-ts');
    var msgTimestampLink = document.createElement('a');
    msgTimestampLink.setAttribute('href', '/' + msg.mid + '#' + msg.rid);
    msgTimestampLink.setAttribute('title', msg.timestamp + ' GMT');
    msgTimestampLink.textContent = msg.timestamp;
    msgTimestamp.appendChild(msgTimestampLink);
    var msgTxt = document.createElement('div');
    msgTxt.setAttribute('class', 'msg-txt');
    var msgLinks = document.createElement('div');
    msgLinks.setAttribute('class', 'msg-links');
    var msgNum = '/' + msg.rid;
    if (msg.replyto > 0) {
        msgNum += ' в ответ на <a href="#' + msg.replyto + '">/' + msg.replyto + '</a>';
    }
    msgLinks.innerHTML = msgNum + ' &middot; ';
    var msgLinksLink = document.createElement('a');
    msgLinksLink.setAttribute('href', '#');
    msgLinksLink.textContent = 'Ответить';
    msgLinksLink.addEventListener('click', function (e) {
        showCommentForm(msg.mid, msg.rid);
        e.preventDefault();
    });
    msgLinks.appendChild(msgLinksLink);
    var msgComment = document.createElement('div');
    msgComment.setAttribute('class', 'msg-comment');
    msgComment.style.display = 'none';
    msgHeader.appendChild(msgAvatar);
    msgHeader.appendChild(msgMenu);
	msgHeader.appendChild(msgTimestamp);
    msgCont.appendChild(msgHeader);
    msgCont.appendChild(msgTxt);
    msgCont.appendChild(msgLinks);
    msgCont.appendChild(msgComment);
    li.appendChild(msgCont);        

    li.querySelector('.msg-txt').textContent = msg.body;

    if (isTreeMode() && (msg.replyto > 0)) {
        var p = document.getElementById(msg.replyto);
        var m = parseInt(p.style.marginLeft) + 20;
        while (p.nextElementSibling && (parseInt(p.nextElementSibling.style.marginLeft) >= m)) p = p.nextElementSibling;
        li.style.marginLeft = m + 'px';
        p.parentNode.insertBefore(li, p.nextSibling);
    } else {
        document.getElementById('replies').appendChild(li);
    }

    updateRepliesCounter();
}

function newReply(e) {
    var li = e.target;
    li.classList.remove('reply-new');
    li.removeEventListener('click', e);
    li.removeEventListener('mouseover', e);
    updateRepliesCounter();
}

function nextReply() {
    var li = document.querySelector('#replies>li.reply-new');
    if (li) {
        li.classList.remove('reply-new');
        li.removeEventListener('click', this);
        li.childNodes[0].scrollIntoView();
        updateRepliesCounter();
    }
}

function updateRepliesCounter() {
    var replies = document.querySelectorAll('#replies>li.reply-new').length;
    var wsthread = document.getElementById('wsthread');
    if (replies) {
        wsthread.textContent = replies;
        wsthread.style.display = 'block';
        document.title = '[' + replies + '] ' + pageTitle;
    } else {
        wsthread.style.display = 'none';
        document.title = pageTitle;
    }
}

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/

function postformListener(formEl, ev) {
    var form = formEl.closest('form');
    if (ev.ctrlKey && (ev.keyCode == 10 || ev.keyCode == 13)) {
        if (!form.onsubmit || form.onsubmit()) {
            form.submit();
        }
    }
}

function unfoldPostForm() {
    if (window.location.pathname === '/' && window.location.hash === '#post') {
        document.querySelector('#newmessage>div').style.display = 'block';
        var ta = document.querySelector('#newmessage textarea');
        ta.style.minHeight = '70px';
        ta.focus();
    }
}

function newMessage() {
    if (document.querySelector('#newmessage textarea').value.length == 0) {
        openDialog('<p class="dialogtxt">Пожалуйста, введите текст сообщения</p>');
        return false;
    }
    return true;
}

function showMoreReplies(el, id) {
    var foldedReplies = el.closest('li').querySelector('.msg-comments');
    if (!foldedReplies) { return }
    foldedReplies.style.display = 'none';

    var replies = document.querySelectorAll('#replies>li'),
        flagshow = 0,
        i = 0;
    for (; i < replies.length; i += 1) {
        if (flagshow == 1) {
            if (replies[i].style.display == 'none') {
                replies[i].style.display = 'block';
            } else {
                break;
            }
        }
        if (replies[i].id == id) {
            flagshow = 1;
        }
    }
    return false;
}

function replyForm(mid, rid) {
    var form = document.createElement('form');
    form.setAttribute('action', '/comment');
    form.setAttribute('method', 'POST');
    form.setAttribute('enctype', 'multipart/form-data');
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', 'mid');
    input.setAttribute('value', mid);
    form.appendChild(input);
    if (rid) {
        var inputRid = document.createElement('input');
        inputRid.setAttribute('type', 'hidden');
        inputRid.setAttribute('name', 'rid');
        inputRid.setAttribute('value', rid);
        form.appendChild(inputRid);
    }
    return form;
}

function taWrapper() {
    var txtarea = document.createElement('textarea');
    txtarea.setAttribute('name', 'body');
    txtarea.setAttribute('rows', 1);
    txtarea.setAttribute('class', 'reply narrow');
    txtarea.setAttribute('placeholder', 'Написать комментарий...');
    var txtKeypress = function (e) {
        postformListener(e.target, e);
    };
    txtarea.addEventListener('keypress', txtKeypress);
    var wrapper = document.createElement('div');
    wrapper.setAttribute('class', 'ta-wrapper');
    wrapper.appendChild(txtarea);
    var att = document.createElement('div');
    att.setAttribute('class', 'attach-photo');
    att.addEventListener('click', function () {
        attachCommentPhoto(this);
    });
    wrapper.appendChild(att);
    return wrapper;
}

function showCommentForm(mid, rid) {
    var reply = document.getElementById(rid);
    if (reply && !reply.querySelector('textarea')) {
        var c = reply.querySelector('div.msg-cont > .msg-comment'),
            newNode = c.cloneNode(true),
            form = replyForm(mid, rid);
        form.appendChild(newNode);
        newNode.appendChild(taWrapper());
        var subm = document.createElement('input');
        subm.setAttribute('type', 'submit');
        subm.setAttribute('value', 'OK');
        newNode.appendChild(subm);
        c.parentNode.insertBefore(form, c);
        c.remove();
    }

    var commentBlock = reply.querySelector('div.msg-cont > form > div.msg-comment');
    commentBlock.style.display = 'block';
    var commentText = commentBlock.querySelector('textarea');
    if (commentText) {
        autosize(commentText);
        commentText.focus();
    }
}

function showCommentFooter(e, mid, rid) {
    var a = e.closest('article');
    if (!a.querySelector('footer.comm')) {
        var form = replyForm(mid, rid),
            footer = document.createElement('footer');
        footer.setAttribute('class', 'comm');
        footer.appendChild(taWrapper());
        var subm = document.createElement('input');
        subm.setAttribute('type', 'submit');
        subm.setAttribute('value', 'OK');
        footer.appendChild(subm);
        form.appendChild(footer);
        a.appendChild(form);
        autosize(a.querySelector('textarea'));
    }
    a.querySelector('textarea').focus();
}

function attachInput() {
    var inp = document.createElement('input');
    inp.setAttribute('type', 'file');
    inp.setAttribute('name', 'attach');
    inp.setAttribute('accept', 'image/jpeg,image/png');
    inp.style.visibility = 'hidden';
    return inp;
}

function attachCommentPhoto(div) {
    if (div.children.length === 0) {
        var inp = attachInput();
        inp.addEventListener('change', function () {
            inp.parentNode.classList.add('attach-photo-active');
        });
        inp.click();
        div.appendChild(inp);
    } else {
        div.innerHTML = null;
        div.classList.add('attach-photo');
    }
}

function attachMessagePhoto(div) {
    var f = div.closest('form'),
        finput = f.querySelector('input[type="file"]');
    if (!finput) {
        var inp = attachInput();
        inp.style.float = 'left';
        inp.style.width = 0;
        inp.style.height = 0;
        inp.addEventListener('change', function () {
            div.textContent = 'загрузить (✓)';
        });
        f.appendChild(inp);
        inp.click();
    } else {
        finput.remove();
        div.textContent = 'загрузить';
    }
}

function unfoldReply() {
    var anchor = window.location.hash.substring(1);
    if ((0 + anchor) > 0) {
        var el = document.getElementById(anchor);
        if (!el) { return }
        while (el.style.display === 'none') {
            el = el.previousElementSibling;
        }
        showMoreReplies(el, el.getAttribute('id'));
        window.location.replace(window.location.hash);
    }
}

function showMessageLinksDialog(mid, rid) {
    var hlink = window.location.protocol + '//juick.com/' + mid,
        mlink = '#' + mid;
    if (rid > 0) {
        hlink += '#' + rid;
        mlink += '/' + rid;
    }
    var hlinkenc = encodeURIComponent(hlink),
        html = '<div class="dialogshare">Ссылка на сообщение:'
    + '<div onclick="this.selectText()" class="dialogl">' + hlink + '</div>'
    + 'Номер сообщения:'
    + '<div onclick="this.selectText()" class="dialogl">' + mlink + '</div>'
    + 'Поделиться:<ul>'
    + '<li><a href="https://www.facebook.com/sharer/sharer.php?u=' + hlinkenc + '" onclick="return openSocialWindow(this)"></a></li>'
    + '<li><a href="https://twitter.com/intent/tweet?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -32px 0;"></a></li>'
    + '<li><a href="https://vk.com/share.php?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -64px 0;"></a></li>'
    + '<li><a href="https://plus.google.com/share?url=' + hlinkenc + '" onclick="return openSocialWindow(this)" style="background-position: -96px 0;"></a></li>'
    + '</ul></div>';

    openDialog(html);
}

function showPhotoDialog(fname) {
    var width = window.innerWidth,
        height = window.innerHeight * 0.9;
    if (width < 640) {
        return true;
    } else if (width < 1280) {
        openDialog('<a href="//i.juick.com/photos-1024/' + fname + '"><img src="//i.juick.com/photos-512/' + fname + '"/></a>');
        document.querySelector('#dialogw img').style.maxHeight = height + 'px';
        return false;
    } else {
        openDialog('<a href="//i.juick.com/p/' + fname + '"><img src="//i.juick.com/photos-1024/' + fname + '"/></a>');
        document.querySelector('#dialogw img').style.maxHeight = height + 'px';
        return false;
    }
}

function openDialog(html) {
    var dhtml = '<table id="dialogt"><tr><td><div id="dialogb"></div><div id="dialogw"><div id="dialogc"></div>' + html + '</div></td></tr></table>';
    document.querySelector('body').insertAdjacentHTML('afterbegin', dhtml);
    document.querySelector('#dialogb').addEventListener('click', closeDialog);
    document.querySelector('#dialogc').addEventListener('click', closeDialog);
}

function closeDialog() {
    document.querySelector('#dialogb').remove();
    document.querySelector('#dialogt').remove();
}

function openSocialWindow(a) {
    var w = window.open(a.href, 'juickshare', 'width=640,height=400');
    if (window.focus) w.focus();
    return false;
}

function checkUsername() {
    var uname = document.querySelector('#username').textContent,
        style = document.querySelector('#username').style;
    fetch('//api.juick.com/users?uname=' + uname)
        .then(function () {
            style.background = '#FFCCCC';
        })
        .catch(function () {
            style.background = '#CCFFCC';
        });
}

/******************************************************************************/

function openDialogLogin() {
    var html = '<div class="dialoglogin"><p>Пожалуйста, представьтесь:'
        + '<a href="/_fblogin" id="signfb">Facebook</a> '
        + '<a href="/_vklogin" id="signvk">ВКонтакте</a></p>'
        + '<p>Уже зарегистрированы?</p>'
        + '<form action="/login" method="POST">'
        + '<input class="signinput" type="text" name="username" placeholder="Имя пользователя"/><br/>'
        + '<input class="signinput" type="password" name="password" placeholder="Пароль"/><br/>'
        + '<input class="signsubmit" type="submit" value="OK"/>'
        + '</form></div>';
    openDialog(html);
    return false;
}

/******************************************************************************/

function resultMessage(str) {
    var result = document.createElement('p');
    result.textContent = str;
    return result;
}

function likeMessage(e, mid) {
    if (confirm('Are you sure?')) {
        fetch('//juick.com/like?mid=' + mid, {
            method: 'POST',
            credentials: 'same-origin'
        })
            .then(function (response) {
                if (response.ok) {
                    e.closest('article').appendChild(resultMessage('OK!'));
                }
            })
            .catch(function () {
                e.closest('article').appendChild(resultMessage('Ошибка'));
            });
    }
    return false;
}

/******************************************************************************/

function setPopular(e, mid, popular) {
    fetch('//api.juick.com/messages/set_popular?mid=' + mid
        + '&popular=' + popular
        + '&hash=' + document.getElementById('body').getAttribute('data-hash'), {
        credentials: 'same-origin'
    })
        .then(function () {
            e.closest('article').append(resultMessage('OK!'));
        });
    return false;
}

function setPrivacy(e, mid) {
    fetch('//api.juick.com/messages/set_privacy?mid=' + mid
        + '&hash=' + document.getElementById('body').getAttribute('data-hash'), {
        credentials: 'same-origin'
    })
        .then(function () {
            e.closest('article').append(resultMessage('OK!'));
        });
    return false;
}
/******************************************************************************/

Element.prototype.selectText = function () {
    var d = document;
    if (d.body.createTextRange) {
        var range = d.body.createTextRange();
        range.moveToElementText(this);
        range.select();
    } else if (window.getSelection) {
        var selection = window.getSelection();
        var rangeSel = d.createRange();
        rangeSel.selectNodeContents(this);
        selection.removeAllRanges();
        selection.addRange(rangeSel);
    }
};

function ready(fn) {
    if (document.readyState != 'loading') {
        fn();
    } else {
        document.addEventListener('DOMContentLoaded', fn);
    }
}

ready(function () {
    autosize(document.querySelectorAll('textarea'));

    var insertButtons = function (e) {
        var textarea = e.target;
        textarea.classList.add('narrow');
        var att = document.createElement('div');
        att.classList.add('attach-photo');
        att.addEventListener('click', function(e) {
            attachCommentPhoto(e.target);
        });
        textarea.parentNode.insertBefore(att, textarea.nextSibling);
        textarea.parentNode.insertAdjacentHTML('afterend', '<input type="submit" value="OK"/>');
        textarea.removeEventListener('click', insertButtons);
        e.preventDefault();
    };
    document.querySelectorAll('textarea.reply').forEach(function(e) {
        e.addEventListener('click', insertButtons);
        e.addEventListener('keypress', function(e) {
            postformListener(e.target, e);
        });
    });

    var insertPMButtons = function (e) {
        e.target.classList.add('narrowpm');
        e.target.parentNode.insertAdjacentHTML('afterend', '<input type="submit" value="OK"/>');
        e.target.removeEventListener('click', insertPMButtons);
        e.preventDefault();
    };
    document.querySelectorAll('textarea.replypm').forEach(function(e) {
        e.addEventListener('click', insertPMButtons);
    });

    var content = document.getElementById('content');
    if (content) {
        var pageMID = content.getAttribute('data-mid');
        if (pageMID > 0) {
            document.querySelectorAll('.msg-comments').forEach(function(e) {
                e.addEventListener('click', function (e) {
                    var rid = e.target.closest('li').id;
                    showMoreReplies(e.target, rid);
                    e.preventDefault();
                });
            });
            document.querySelectorAll('.a-thread-comment').forEach(function(e) {
                e.addEventListener('click', function (e) {
                    var rid = e.target.closest('li').id;
                    showCommentForm(pageMID, rid);
                    e.preventDefault();
                });
            });
        }
    }

    document.querySelectorAll('.msg-menu a').forEach(function(el) {
        el.addEventListener('click', function(e) {
            showMessageLinksDialog(
                e.target.closest('section').getAttribute('data-mid'),
                parseInt(e.target.closest('li').id)); // rid
            e.preventDefault();
        });
    });
    document.querySelectorAll('.l .a-comment').forEach(function(e) {
        e.addEventListener('click', function (e) {
            showCommentFooter(
                e.target,
                e.target.closest('article').getAttribute('data-mid'));
            e.preventDefault();
        });
    });
    document.querySelectorAll('.l .a-privacy').forEach(function(e) {
        e.addEventListener('click', function (e) {
            setPrivacy(
                e.target,
                e.target.closest('article').getAttribute('data-mid'));
            e.preventDefault();
        });
    });
    document.querySelectorAll('.l .a-popular-plus').forEach(function(e) {
        e.addEventListener('click', function (e) {
            setPopular(
                e.target,
                e.target.closest('article').getAttribute('data-mid'),
                2);
            e.preventDefault();
        });
    });
    document.querySelectorAll('.l .a-popular-minus').forEach(function(e) {
        e.addEventListener('click', function (e) {
            setPopular(
                e.target,
                e.target.closest('article').getAttribute('data-mid'),
                -1);
            e.preventDefault();
        });
    });
    document.querySelectorAll('.l .a-popular-delete').forEach(function(e) {
        e.addEventListener('click', function (e) {
            setPopular(
                e.target,
                e.target.closest('article').getAttribute('data-mid'),
                -2);
            e.preventDefault();
        });
    });
    document.querySelectorAll('.ir a').forEach(function(e) {
        e.addEventListener('click', function (e) {
            var fname = e.target.closest('[data-fname]').getAttribute('data-fname');
            if (!showPhotoDialog(fname)) {
                e.preventDefault();
            }
        });
    });
    document.querySelectorAll('.social a').forEach(function(e) {
        e.addEventListener('click', function (e) {
            openSocialWindow(e.target);
            e.preventDefault();
        });
    });
    var username = document.getElementById('username');
    if (username) {
        username.addEventListener('blur', function () {
            checkUsername();
        });
    }

    document.querySelectorAll('.l .a-like').forEach(function(e) {
        e.addEventListener('click', function (e) {
            likeMessage(
                e.target,
                e.target.closest('article').getAttribute('data-mid'));
            e.preventDefault();
        });
    });
    document.querySelectorAll('.a-login').forEach(function(el) {
        el.addEventListener('click', function(e) {
            openDialogLogin();
            e.preventDefault();
        });
    });
    document.querySelectorAll('.attach-photo').forEach(function(el) {
        el.addEventListener('click', function(e) {
            attachCommentPhoto(e.target);
        });
    });
    var unfoldall = document.getElementById('unfoldall');
    if (unfoldall) {
        unfoldall.addEventListener('click', function(e) {
            document.querySelectorAll('#replies>li').forEach(function(e) {
                e.style.display = 'block';
            });
            document.querySelectorAll('#replies .msg-comments').forEach(function(e) {
                e.style.display = 'none';
            });
            e.preventDefault();
        });
    }
    var newMessageBlock = document.getElementById('newmessage');
    if (newMessageBlock) {
        var form = newMessageBlock.parentNode;
        form.addEventListener('submit', newMessage);
        newMessageBlock.querySelector('textarea').addEventListener('click', function(e) {
            var parent = e.target.parentNode;
            parent.querySelector('div').style.display = 'block';
            e.target.style.minHeight = '70px';
            e.target.addEventListener('keypress', function(e) {
                postformListener(e.target, e);
            });
        });
        newMessageBlock.querySelector('a').addEventListener('click', function(e) {
            attachMessagePhoto(e.target);
        });
    }
    document.querySelectorAll('article').forEach(function(article) {
        if (Array.prototype.some.call(
            article.querySelectorAll('.u a'),
            function (a) {
                return a.textContent === 'NSFW';
            }
        )) {
            var img = article.querySelector('.ir img');
            if (img) {
                img.style.opacity = 0.05;
                img.addEventListener('mouseover', function(e) {
                    e.target.style.opacity = 1;
                });
                img.addEventListener('mouseout', function(e) {
                    e.target.style.opacity = 0.05;
                });
            }
        }
    });

    unfoldPostForm();
    unfoldReply();
    initWS();
    window.addEventListener('hashchange', unfoldPostForm);
    window.addEventListener('hashchange', unfoldReply);

    window.addEventListener('pagehide', wsShutdown);
});