(($) => {
    $(document).ready(function () {
        let $dashboard = $(".vidplex__dashboard");
        const toast = $dashboard.find(".toast");
        const errMessage = $dashboard.find(".error");
        const successMessage = $dashboard.find(".success");
        const infoMessage = $dashboard.find(".info");

        // Tabs
        const $tabs = $dashboard.find(".tab__item");
        const $contents = $dashboard.find(".tab__content");
        function setActiveTab(index) {
            $tabs.removeClass("is-active").eq(index).addClass("is-active");
            $contents.removeClass("is-active").eq(index).addClass("is-active");
        }
        $tabs.each(function (index) {
            $(this).on("click", function () {
                setActiveTab(index);
            });
        });

        // Store api key.
        const $saveBtn = $dashboard.find("#vidplex-save-api-key");
        const $apiInput = $dashboard.find(".api-key__input");
        const $showIcon = $dashboard.find("#eye");
        const $hideIcon = $dashboard.find("#eye-off");
        const $spinner = $dashboard.find(".spinner__icon");
        const $check = $dashboard.find(".check__icon");

        $apiInput.on("input", function () {
            const $this = $(this);
            const value = $this.val().trim();

            if (String(value).length > 10) {
                $saveBtn.removeClass("disabled");
            } else {
                $saveBtn.addClass("disabled");
            }
        });
        $showIcon.click(function () {
            $(this).addClass("display__none");
            $hideIcon.removeClass("display__none");
            $apiInput.attr("type", "text");
        });
        $hideIcon.click(function () {
            $(this).addClass("display__none");
            $showIcon.removeClass("display__none");
            $apiInput.attr("type", "password");
        });

        $saveBtn.on("click", function () {
            const $this = $(this);
            const value = $apiInput.val().trim();
            errMessage.text("");
            errMessage.addClass("visibility__hidden");
            successMessage.text("");
            successMessage.addClass("visibility__hidden");

            if (
                !scriptObj.isPremium ||
                $this.hasClass("disabled") ||
                String(value).length <= 10
            ) {
                return;
            }

            $.ajax({
                url: scriptObj.ajaxURL,
                method: "POST",
                data: {
                    action: "vidplex_set_api_key",
                    nonce: scriptObj.apiKeyNonce,
                    key: value,
                },
                beforeSend: function () {
                    toast.text("");
                    toast.addClass("visibility__hidden");
                    // Show spinner
                    $spinner.removeClass("display__none");
                    $check.addClass("display__none");
                    // Prevent further typing
                    $this.addClass("disabled"); // keeps styling but blocks typing
                },
                success: function (res) {
                    // console.log(res);
                },
                error: function () {},
                complete: function (xhr, status) {
                    $spinner.addClass("display__none");

                    successMessage.text("Youtube API key updated.");
                    successMessage.removeClass("visibility__hidden");

                    setTimeout(() => {
                        successMessage.text("");
                        successMessage.addClass("visibility__hidden");
                    }, 3000);
                },
            });
        });
        // Trigger on Enter key in the input field
        $apiInput.keypress(function (e) {
            if (e.which === 13) {
                // 13 is the Enter key
                $saveBtn.click(); // Trigger the same click function
            }
        });

        /* --------------- Channel CRUD ---------------- */
        const $channelInput = $dashboard.find(".channel__input");
        const $addButton = $dashboard.find("#vidplex-add-channel");

        $channelInput.on("input", function () {
            const $this = $(this);

            const value = $this.val().trim();

            if (value !== "") {
                $addButton.removeClass("disabled");
            } else {
                $addButton.addClass("disabled");
            }
        });

        $addButton.click(function () {
            const $this = $(this);
            let value = $channelInput.val().trim();
            $channelInput.removeClass("has-error");

            const youtubeHandleRegex =
                /^(?:https?:\/\/)?(?:www\.)?youtube\.com\/@([a-zA-Z0-9_-]+)(?:[/?].*)?$/;
            const match = String(value).match(youtubeHandleRegex);
            let channelParam;

            if (
                !scriptObj.isPremium ||
                $addButton.hasClass("disabled") ||
                String(value).length <= 2
            ) {
                return;
            }

            if (value.length > 2) {
                // Determine if the value is channel handle or ID
                if (!value.includes("@") && value.length === 24) {
                    channelParam = "id";
                } else if (value.includes("@") && value.charAt(0) === "@") {
                    channelParam = "forHandle";
                } else if (
                    (String(value).startsWith("https://www.youtube.com") ||
                        String(value).startsWith("http://www.youtube.com")) &&
                    match
                ) {
                    value = match[1];
                    channelParam = "forHandle";
                } else {
                    errMessage.removeClass("visibility__hidden");
                    errMessage.text("Invalid channel!");
                    $addButton.addClass("disabled");
                    $channelInput.addClass("has-error");

                    setTimeout(() => {
                        errMessage.text("");
                        errMessage.addClass("visibility__hidden");
                    }, 3000);
                    return;
                }

                if (String(channelParam).length > 0) {
                    // AJAX data
                    const params = {
                        action: "vidplex_set_channel_ID",
                        nonce: scriptObj.channelNonce,
                        channelParam: channelParam,
                        channelValue: value,
                    };
                    $.post({
                        url: scriptObj.ajaxURL,
                        data: params,
                        beforeSend: function () {
                            $this.addClass("disabled");

                            toast.text("");
                            toast.addClass("visibility__hidden");

                            infoMessage.text("Hang on...");
                            infoMessage.removeClass("visibility__hidden");

                            setTimeout(() => {
                                infoMessage.text("");
                                infoMessage.addClass("visibility__hidden");
                            }, 3000);
                        },
                        success: function (response) {
                            toast.text("");
                            toast.addClass("visibility__hidden");

                            if (response.success) {
                                // Render the newly added channel
                                const $newEl = $(response.data.render);
                                $dashboard
                                    .find(".channel__list")
                                    .append($newEl);
                                successMessage.text(
                                    "Channel added to the list.",
                                );
                                successMessage.removeClass(
                                    "visibility__hidden",
                                );

                                setTimeout(() => {
                                    successMessage.text("");
                                    successMessage.addClass(
                                        "visibility__hidden",
                                    );
                                }, 3000);

                                setTimeout(() => {
                                    $newEl
                                        .find(".action__sync")
                                        .trigger("click");
                                }, 500);
                            } else {
                                // Error
                                $channelInput.addClass("has-error");
                                errMessage.text(response.data.message);
                                errMessage.removeClass("visibility__hidden");

                                setTimeout(() => {
                                    errMessage.text("");
                                    errMessage.addClass("visibility__hidden");
                                }, 3000);
                            }
                        },
                        error: function () {
                            toast.text("");
                            toast.addClass("visibility__hidden");

                            // Unable to process request
                            console.log("Unable to process request.");
                            errMessage.text("Oops! Unable to process request.");
                            errMessage.removeClass("visibility__hidden");

                            setTimeout(() => {
                                errMessage.text("");
                                errMessage.addClass("visibility__hidden");
                            }, 3000);
                        },
                        complete: function (xhr, status) {
                            $addButton.addClass("disabled");
                        },
                    });
                }
            }
        });
        // Trigger on Enter key in the input field
        $channelInput.keypress(function (e) {
            if (e.which === 13) {
                // 13 is the Enter key
                $addButton.click(); // Trigger the same click function
            }
        });
        // Delete Channel
        $dashboard.on("click", ".action__unlink", function (e) {
            e.stopImmediatePropagation();
            e.preventDefault();

            const $this = $(this);

            const parent = $this.parent();

            const channelID = $this.attr("data-channel-id");
            const channelHandle = $this.attr("data-channel-handle");

            let message = `Are you sure you want to unlink ${channelHandle} from the list? Deleting the channel will also remove its synced videos.`;

            if (!scriptObj.advancedSettings.cascade_delete_videos) {
                message = `Are you sure you want to unlink ${channelHandle} from the list?`;
            }

            if (confirm(message)) {
                const params = {
                    action: "vidplex_remove_channel",
                    nonce: scriptObj.channelNonce,
                    channelID: channelID,
                };
                $.post({
                    url: scriptObj.ajaxURL,
                    data: params,
                    beforeSend: function () {
                        toast.text("");
                        toast.addClass("visibility__hidden");
                    },
                    success: function (response) {
                        if (response.success) {
                            // Removed channel
                            parent.parent().remove();
                            successMessage.text("Channel removed.");
                            successMessage.removeClass("visibility__hidden");

                            setTimeout(() => {
                                successMessage.text("");
                                successMessage.addClass("visibility__hidden");
                            }, 3000);
                        } else {
                            // Error while removing
                        }
                    },
                    error: function (err) {
                        errMessage.text("Unable to link this channel.");
                        errMessage.removeClass("visibility__hidden");

                        setTimeout(() => {
                            errMessage.text("");
                            errMessage.addClass("visibility__hidden");
                        }, 3000);
                    },
                });
            }
        });

        // Sync channel videos
        $dashboard.on("click", ".action__sync", function (e) {
            e.stopImmediatePropagation();
            e.preventDefault();

            const $this = $(this);

            const channelId = $this.attr("data-channel-id");

            $.post({
                url: scriptObj.ajaxURL,
                data: {
                    action: "vidplex_sync_single_channel_videos",
                    nonce: scriptObj.channelVideosNonce,
                    channelID: channelId,
                },
                beforeSend: function () {
                    $this.addClass("loading");

                    toast.text("");
                    toast.addClass("visibility__hidden");

                    infoMessage.text(
                        "Hold on! We're syncing the channel videos.",
                    );
                    infoMessage.removeClass("visibility__hidden");

                    $this
                        .siblings(".sync__status")
                        .find(".sync__time")
                        .text("Syncing...");
                },
                success: function (res) {
                    if (res.success) {
                        successMessage.text(res.data.message);
                        successMessage.removeClass("visibility__hidden");

                        setTimeout(() => {
                            successMessage.text("");
                            successMessage.addClass("visibility__hidden");
                        }, 3000);

                        const videoCount = Number(res.data.videoCount);

                        const count = `${videoCount} ${
                            videoCount > 1 ? "Videos" : "Video"
                        }`;
                        $this
                            .siblings(".sync__status")
                            .find(".video__count")
                            .text(count);
                    } else {
                        if (res.data.message) {
                            errMessage.text(res.data.message);
                        } else {
                            errMessage.text("Unable to sync videos.");
                        }
                        errMessage.removeClass("visibility__hidden");

                        setTimeout(() => {
                            errMessage.text("");
                            errMessage.addClass("visibility__hidden");
                        }, 3000);
                    }
                },
                error: function () {
                    errMessage.text("Oops! Something went wrong.");
                    errMessage.removeClass("visibility__hidden");

                    setTimeout(() => {
                        errMessage.text("");
                        errMessage.addClass("visibility__hidden");
                    }, 3000);
                },
                complete: function () {
                    $this.removeClass("loading");

                    infoMessage.text("");
                    infoMessage.addClass("visibility__hidden");

                    $this
                        .siblings(".sync__status")
                        .find(".sync__time")
                        .text("Just Now");
                },
            });
        });

        /* -----------Settings------------ */
        const $saveSettingsBtn = $dashboard.find("#save-btn");
        const $refreshBtn = $dashboard.find("#videos-refresh-btn");
        // Toggle Button
        $(".vidplex__page .toggle__btn").click(function () {
            const $this = $(this);

            const checked = $this.attr("data-checked");

            if (checked === "true") {
                $this.attr("data-checked", "false");
            } else {
                $this.attr("data-checked", "true");
            }

            $saveSettingsBtn.removeClass("disabled");
        });
        // Input fields
        $dashboard
            .find(
                ".vidplex__page.settings__page input, .vidplex__page.settings__page select",
            )
            .on("input", function () {
                $saveSettingsBtn.removeClass("disabled");
            });
        // Refresh Videos.
        $refreshBtn.click(function (e) {
            e.preventDefault();

            if ($refreshBtn.hasClass("disabled")) {
                return;
            }

            $.post({
                url: scriptObj.ajaxURL,
                data: {
                    action: "vidplex_refresh_channel_videos",
                    nonce: scriptObj.refreshNonce,
                },
                beforeSend: function () {
                    $refreshBtn.find(".btn__icon").addClass("spin");
                    $refreshBtn.addClass("disabled");

                    toast.text("");
                    toast.addClass("visibility__hidden");

                    infoMessage.text("Hang on...");
                    infoMessage.removeClass("visibility__hidden");

                    setTimeout(() => {
                        infoMessage.text("");
                        infoMessage.addClass("visibility__hidden");
                    }, 3000);
                },
                success: function (res) {
                    toast.text("");
                    toast.addClass("visibility__hidden");

                    if (res.success) {
                        successMessage.text(res.data.message);
                        successMessage.removeClass("visibility__hidden");

                        setTimeout(() => {
                            successMessage.text("");
                            successMessage.addClass("visibility__hidden");
                        }, 3000);
                    } else {
                        errMessage.text(res.data.message);
                        errMessage.removeClass("visibility__hidden");

                        setTimeout(() => {
                            errMessage.text("");
                            errMessage.addClass("visibility__hidden");
                        }, 3000);
                    }
                },
                error: function () {
                    toast.text("");
                    toast.addClass("visibility__hidden");

                    errMessage.text("Unable to sync channel.");
                    errMessage.removeClass("visibility__hidden");

                    setTimeout(() => {
                        errMessage.text("");
                        errMessage.addClass("visibility__hidden");
                    }, 3000);
                },
                complete: function () {
                    $refreshBtn.find(".btn__icon").removeClass("spin");
                    $refreshBtn.removeClass("disabled");
                },
            });
        });
        // Save settings
        $saveSettingsBtn.click(function () {
            const $this = $(this);

            if ($this.hasClass("disabled")) {
                return;
            }

            const $page = $dashboard.find(".vidplex__page.settings__page");

            function isChecked($el) {
                return (
                    $el.attr("data-checked") === true ||
                    $el.attr("data-checked") === "true"
                );
            }

            const settings = {
                video_refresh_interval: $page
                    .find(".video_refresh_interval")
                    .val(),
                videos_per_fetch: Number($page.find(".videos_per_fetch").val()),
                max_videos_per_channel: Number(
                    $page.find(".max_videos_per_channel").val(),
                ),

                long_shorts_as_video: isChecked(
                    $page.find(".long_shorts_as_video"),
                ),

                optimize_db_storage: isChecked(
                    $page.find(".optimize_db_storage"),
                ),
                cascade_delete_videos: isChecked(
                    $page.find(".cascade_delete_videos"),
                ),
                cleanup_multiple_data: isChecked(
                    $page.find(".cleanup_multiple_data"),
                ),
                api_quota_protection: isChecked(
                    $page.find(".api_quota_protection"),
                ),
                log_api_errors: isChecked($page.find(".log_api_errors")),
            };

            $.post({
                url: scriptObj.ajaxURL,
                data: {
                    action: "vidplex_settings",
                    nonce: scriptObj.saveNonce,
                    settings: JSON.stringify(settings),
                },
                beforeSend: function () {
                    toast.text("");
                    toast.addClass("visibility__hidden");
                },
                success: function (res) {
                    if (res.success) {
                        successMessage.text(res.data.message);
                        successMessage.removeClass("visibility__hidden");

                        setTimeout(() => {
                            successMessage.text("");
                            successMessage.addClass("visibility__hidden");
                        }, 3000);

                        $this.addClass("disabled");
                    } else {
                        errMessage.text(res.data.message);
                        errMessage.removeClass("visibility__hidden");

                        setTimeout(() => {
                            errMessage.text("");
                            errMessage.addClass("visibility__hidden");
                        }, 3000);
                    }
                },
                error: function (err) {
                    errMessage.text("Something went wrong.");
                    errMessage.removeClass("visibility__hidden");

                    setTimeout(() => {
                        errMessage.text("");
                        errMessage.addClass("visibility__hidden");
                    }, 3000);
                },
            });
        });
    });

    // Debounce function.
    function debounce(fn, delay) {
        let timer; // store timeout ID
        return function (...args) {
            const context = this; // preserve context
            clearTimeout(timer); // clear previous timer
            timer = setTimeout(() => {
                fn.apply(context, args); // call function after delay
            }, delay);
        };
    }
})(jQuery);
