const render_all_messages_sidebar_actions = require('../templates/all_messages_sidebar_actions.hbs');
const render_delete_topic_modal = require('../templates/delete_topic_modal.hbs');
const render_starred_messages_sidebar_actions = require('../templates/starred_messages_sidebar_actions.hbs');
const render_stream_sidebar_actions = require('../templates/stream_sidebar_actions.hbs');
const render_topic_sidebar_actions = require('../templates/topic_sidebar_actions.hbs');
const render_unstar_messages_modal = require("../templates/unstar_messages_modal.hbs");

// We handle stream popovers and topic popovers in this
// module.  Both are popped up from the left sidebar.
let current_stream_sidebar_elem;
let current_topic_sidebar_elem;
let all_messages_sidebar_elem;
let starred_messages_sidebar_elem;

function elem_to_stream_id(elem) {
    const stream_id = parseInt(elem.attr('data-stream-id'), 10);

    if (stream_id === undefined) {
        blueslip.error('could not find stream id');
    }

    return stream_id;
}

function topic_popover_stream_id(e) {
    return elem_to_stream_id($(e.currentTarget));
}

exports.stream_popped = function () {
    return current_stream_sidebar_elem !== undefined;
};

exports.topic_popped = function () {
    return current_topic_sidebar_elem !== undefined;
};

exports.all_messages_popped = function () {
    return all_messages_sidebar_elem !== undefined;
};

exports.starred_messages_popped = function () {
    return starred_messages_sidebar_elem !== undefined;
};

exports.hide_stream_popover = function () {
    if (exports.stream_popped()) {
        $(current_stream_sidebar_elem).popover("destroy");
        current_stream_sidebar_elem = undefined;
    }
};

exports.hide_topic_popover = function () {
    if (exports.topic_popped()) {
        $(current_topic_sidebar_elem).popover("destroy");
        current_topic_sidebar_elem = undefined;
    }
};

exports.hide_all_messages_popover = function () {
    if (exports.all_messages_popped()) {
        $(all_messages_sidebar_elem).popover("destroy");
        all_messages_sidebar_elem = undefined;
    }
};

exports.hide_starred_messages_popover = function () {
    if (exports.starred_messages_popped()) {
        $(starred_messages_sidebar_elem).popover("destroy");
        starred_messages_sidebar_elem = undefined;
    }
};

// These are the only two functions that is really shared by the
// two popovers, so we could split out topic stuff to
// another module pretty easily.
exports.show_streamlist_sidebar = function () {
    $(".app-main .column-left").addClass("expanded");
    resize.resize_page_components();
};

exports.hide_streamlist_sidebar = function () {
    $(".app-main .column-left").removeClass("expanded");
};


function stream_popover_sub(e) {
    const elem = $(e.currentTarget).parents('ul');
    const stream_id = elem_to_stream_id(elem);
    const sub = stream_data.get_sub_by_id(stream_id);
    if (!sub) {
        blueslip.error('Unknown stream: ' + stream_id);
        return;
    }
    return sub;
}

// This little function is a workaround for the fact that
// Bootstrap popovers don't properly handle being resized --
// so after resizing our popover to add in the spectrum color
// picker, we need to adjust its height accordingly.
function update_spectrum(popover, update_func) {
    const initial_height = popover[0].offsetHeight;

    const colorpicker = popover.find('.colorpicker-container').find('.colorpicker');
    update_func(colorpicker);
    const after_height = popover[0].offsetHeight;

    const popover_root = popover.closest(".popover");
    const current_top_px = parseFloat(popover_root.css('top').replace('px', ''));
    const height_delta = after_height - initial_height;
    let top = current_top_px - height_delta / 2;

    if (top < 0) {
        top = 0;
        popover_root.find("div.arrow").hide();
    } else if (top + after_height > $(window).height() - 20) {
        top = $(window).height() - after_height - 20;
        if (top < 0) {
            top = 0;
        }
        popover_root.find("div.arrow").hide();
    }

    popover_root.css('top', top + "px");
}

function build_stream_popover(opts) {
    const elt = opts.elt;
    const stream_id = opts.stream_id;

    if (exports.stream_popped()
        && current_stream_sidebar_elem === elt) {
        // If the popover is already shown, clicking again should toggle it.
        exports.hide_stream_popover();
        return;
    }

    popovers.hide_all();
    exports.show_streamlist_sidebar();

    const content = render_stream_sidebar_actions({
        stream: stream_data.get_sub_by_id(stream_id),
    });

    $(elt).popover({
        content: content,
        html: true,
        trigger: "manual",
        fixed: true,
        fix_positions: true,
    });

    $(elt).popover("show");
    const popover = $('.streams_popover[data-stream-id=' + stream_id + ']');

    update_spectrum(popover, function (colorpicker) {
        colorpicker.spectrum(stream_color.sidebar_popover_colorpicker_options);
    });

    current_stream_sidebar_elem = elt;
}

function build_topic_popover(opts) {
    const elt = opts.elt;
    const stream_id = opts.stream_id;
    const topic_name = opts.topic_name;

    if (exports.topic_popped()
        && current_topic_sidebar_elem === elt) {
        // If the popover is already shown, clicking again should toggle it.
        exports.hide_topic_popover();
        return;
    }

    const sub = stream_data.get_sub_by_id(stream_id);
    if (!sub) {
        blueslip.error('cannot build topic popover for stream: ' + stream_id);
        return;
    }

    popovers.hide_all();
    exports.show_streamlist_sidebar();

    const is_muted = muting.is_topic_muted(sub.stream_id, topic_name);
    const can_mute_topic = !is_muted;
    const can_unmute_topic = is_muted;

    const content = render_topic_sidebar_actions({
        stream_name: sub.name,
        stream_id: sub.stream_id,
        topic_name: topic_name,
        can_mute_topic: can_mute_topic,
        can_unmute_topic: can_unmute_topic,
        is_admin: sub.is_admin,
    });

    $(elt).popover({
        content: content,
        html: true,
        trigger: "manual",
        fixed: true,
    });

    $(elt).popover("show");

    current_topic_sidebar_elem = elt;
}

function build_all_messages_popover(e) {
    const elt = e.target;

    if (exports.all_messages_popped()
        && all_messages_sidebar_elem === elt) {
        exports.hide_all_messages_popover();
        e.stopPropagation();
        return;
    }

    popovers.hide_all();

    const content = render_all_messages_sidebar_actions();

    $(elt).popover({
        content: content,
        html: true,
        trigger: "manual",
        fixed: true,
    });

    $(elt).popover("show");
    all_messages_sidebar_elem = elt;
    e.stopPropagation();

}

function build_starred_messages_popover(e) {
    const elt = e.target;

    if (exports.starred_messages_popped()
        && starred_messages_sidebar_elem === elt) {
        exports.hide_starred_messages_popover();
        e.stopPropagation();
        return;
    }

    popovers.hide_all();

    const content = render_starred_messages_sidebar_actions({
        starred_message_counts: page_params.starred_message_counts,
    });

    $(elt).popover({
        content: content,
        html: true,
        trigger: "manual",
        fixed: true,
    });

    $(elt).popover("show");
    starred_messages_sidebar_elem = elt;
    e.stopPropagation();

}

exports.register_click_handlers = function () {
    $('#stream_filters').on('click', '.stream-sidebar-arrow', function (e) {
        e.stopPropagation();

        const elt = e.target;
        const stream_li = $(elt).parents('li');
        const stream_id = elem_to_stream_id(stream_li);

        build_stream_popover({
            elt: elt,
            stream_id: stream_id,
        });
    });

    $('#stream_filters').on('click', '.topic-sidebar-arrow', function (e) {
        e.stopPropagation();

        const elt = $(e.target).closest('.topic-sidebar-arrow').expectOne()[0];
        const stream_li = $(elt).closest('.narrow-filter').expectOne();
        const stream_id = elem_to_stream_id(stream_li);
        const topic_name = $(elt).closest('li').expectOne().attr('data-topic-name');

        build_topic_popover({
            elt: elt,
            stream_id: stream_id,
            topic_name: topic_name,
        });
    });

    $('#global_filters').on('click', '.all-messages-arrow', build_all_messages_popover);

    $('#global_filters').on('click', '.starred-messages-sidebar-arrow', build_starred_messages_popover);

    exports.register_stream_handlers();
    exports.register_topic_handlers();
};

exports.register_stream_handlers = function () {
    // Stream settings
    $('body').on('click', '.open_stream_settings', function (e) {
        const sub = stream_popover_sub(e);
        exports.hide_stream_popover();

        const stream_edit_hash = hash_util.stream_edit_uri(sub);
        hashchange.go_to_location(stream_edit_hash);
    });

    // Pin/unpin
    $('body').on('click', '.pin_to_top', function (e) {
        const sub = stream_popover_sub(e);
        exports.hide_stream_popover();
        subs.toggle_pin_to_top_stream(sub);
        e.stopPropagation();
    });

    // Mark all messages in stream as read
    $('body').on('click', '.mark_stream_as_read', function (e) {
        const sub = stream_popover_sub(e);
        exports.hide_stream_popover();
        unread_ops.mark_stream_as_read(sub.stream_id);
        e.stopPropagation();
    });

    // Mark all messages as read
    $('body').on('click', '#mark_all_messages_as_read', function (e) {
        exports.hide_all_messages_popover();
        pointer.fast_forward_pointer();
        e.stopPropagation();
    });

    // Unstar all messages
    $('body').on('click', '#unstar_all_messages', function (e) {
        exports.hide_starred_messages_popover();
        e.preventDefault();
        e.stopPropagation();
        $(".left-sidebar-modal-holder").empty();
        $(".left-sidebar-modal-holder").html(render_unstar_messages_modal());
        $("#unstar-messages-modal").modal("show");
    });

    $('body').on('click', '#do_unstar_messages_button', function (e) {
        $("#unstar-messages-modal").modal("hide");
        message_flags.unstar_all_messages();
        e.stopPropagation();
    });

    // Toggle displaying starred message count
    $('body').on('click', '#toggle_display_starred_msg_count', function (e) {
        exports.hide_starred_messages_popover();
        e.preventDefault();
        e.stopPropagation();
        const starred_msg_counts = page_params.starred_message_counts;
        const data = {};
        data.starred_message_counts = JSON.stringify(!starred_msg_counts);
        channel.patch({
            url: '/json/settings/display',
            data: data,
        });
    });
    // Mute/unmute
    $('body').on('click', '.toggle_home', function (e) {
        const sub = stream_popover_sub(e);
        exports.hide_stream_popover();
        subs.toggle_home(sub);
        e.stopPropagation();
    });

    // Unsubscribe
    $('body').on("click", ".popover_sub_unsub_button", function (e) {
        $(this).toggleClass("unsub");
        $(this).closest(".popover").fadeOut(500).delay(500).remove();

        const sub = stream_popover_sub(e);
        subs.sub_or_unsub(sub);
        e.preventDefault();
        e.stopPropagation();
    });

    // Choose custom color
    $('body').on('click', '.custom_color', function (e) {
        update_spectrum($(e.target).closest('.streams_popover'), function (colorpicker) {
            colorpicker.spectrum("destroy");
            colorpicker.spectrum(stream_color.sidebar_popover_colorpicker_options_full);
            // In theory this should clean up the old color picker,
            // but this seems a bit flaky -- the new colorpicker
            // doesn't fire until you click a button, but the buttons
            // have been hidden.  We work around this by just manually
            // fixing it up here.
            colorpicker.parent().find('.sp-container').removeClass('sp-buttons-disabled');
            $(e.target).hide();
        });

        $('.streams_popover').on('click', 'a.sp-cancel', function () {
            exports.hide_stream_popover();
        });
    });

};

function topic_popover_sub(e) {
    const stream_id = topic_popover_stream_id(e);
    if (!stream_id) {
        blueslip.error('cannot find stream id');
        return;
    }

    const sub = stream_data.get_sub_by_id(stream_id);
    if (!sub) {
        blueslip.error('Unknown stream: ' + stream_id);
        return;
    }
    return sub;
}

exports.register_topic_handlers = function () {
    // Narrow to topic
    $('body').on('click', '.narrow_to_topic', function (e) {
        exports.hide_topic_popover();

        const sub = topic_popover_sub(e);
        if (!sub) {
            return;
        }

        const topic = $(e.currentTarget).attr('data-topic-name');

        const operators = [
            {operator: 'stream', operand: sub.name},
            {operator: 'topic', operand: topic},
        ];
        narrow.activate(operators, {trigger: 'sidebar'});

        e.stopPropagation();
    });

    // Mute the topic
    $('body').on('click', '.sidebar-popover-mute-topic', function (e) {
        const stream_id = topic_popover_stream_id(e);
        if (!stream_id) {
            return;
        }

        const topic = $(e.currentTarget).attr('data-topic-name');
        muting_ui.mute(stream_id, topic);
        e.stopPropagation();
        e.preventDefault();
    });

    // Unmute the topic
    $('body').on('click', '.sidebar-popover-unmute-topic', function (e) {
        const stream_id = topic_popover_stream_id(e);
        if (!stream_id) {
            return;
        }

        const topic = $(e.currentTarget).attr('data-topic-name');
        muting_ui.unmute(stream_id, topic);
        e.stopPropagation();
        e.preventDefault();
    });

    // Mark all messages as read
    $('body').on('click', '.sidebar-popover-mark-topic-read', function (e) {
        const stream_id = topic_popover_stream_id(e);
        if (!stream_id) {
            return;
        }

        const topic = $(e.currentTarget).attr('data-topic-name');
        exports.hide_topic_popover();
        unread_ops.mark_topic_as_read(stream_id, topic);
        e.stopPropagation();
    });

    // Deleting all message in a topic
    $('body').on('click', '.sidebar-popover-delete-topic-messages', function (e) {
        const stream_id = topic_popover_stream_id(e);
        if (!stream_id) {
            return;
        }

        const topic = $(e.currentTarget).attr('data-topic-name');
        const args = {
            topic_name: topic,
        };

        exports.hide_topic_popover();

        $('#delete-topic-modal-holder').html(render_delete_topic_modal(args));

        $('#do_delete_topic_button').on('click', function () {
            message_edit.delete_topic(stream_id, topic);
        });

        $('#delete_topic_modal').modal('show');

        e.stopPropagation();
    });
};

window.stream_popover = exports;
