"use strict";
// ==UserScript==
// @name         Atlassian
// @namespace    Ascendcorp
// @version      1.0.0
// @description  automation script for Ascendcorp Atlassian
// @author       Lumi
// @match        https://truemoney.atlassian.net/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=atlassian.net
// @downloadURL  https://raw.githubusercontent.com/Ascendcorp/userscripts/main/dist/atlassian/atlassian.user.js
// @updateURL    https://raw.githubusercontent.com/Ascendcorp/userscripts/main/dist/atlassian/atlassian.user.js
// @grant        GM_setClipboard
// ==/UserScript==
// ─── Selectors ───────────────────────────────────────────────────────────────
const idSection = 'div[data-testid="issue.views.issue-base.foundation.breadcrumbs.breadcrumb-current-issue-container"]';
const nameSection = 'h1[data-testid="issue.views.issue-base.foundation.summary.heading"]';
const toolbarSection = 'span[data-testid="issue-view-foundation.quick-add.link-button.wrapper"]';
(() => {
    'use strict';
    // ─── Utilities ───────────────────────────────────────────────────────────────
    const log = (message) => console.log(`🤖 ${message}`);
    const waitForElement = async (selector) => {
        return new Promise((resolve) => {
            const targetNode = document.querySelector(selector);
            if (targetNode) {
                resolve(targetNode);
                return;
            }
            const isElement = (item) => {
                return item instanceof Element;
            };
            const observer = new MutationObserver((mutationsList, observer) => {
                for (let mutation of mutationsList) {
                    const isMatched = Array.from(mutation.addedNodes).some((node) => {
                        if (!isElement(node)) {
                            return false;
                        }
                        return node.matches && node.matches(selector);
                    });
                    if (mutation.type === 'childList' && isMatched) {
                        observer.disconnect();
                        const target = document.querySelector(selector);
                        resolve(target);
                        break;
                    }
                }
            });
            observer.observe(document.documentElement, {
                childList: true,
                subtree: true,
            });
        });
    };
    // ─── Core ────────────────────────────────────────────────────────────────────
    const getTicketCode = async () => {
        const section = await waitForElement(idSection);
        // NOTE: risky to change by Atlassian
        const type = (section?.firstElementChild?.firstElementChild?.firstElementChild?.firstElementChild?.firstElementChild?.getAttribute('alt') ?? '').toLowerCase();
        const id = section?.children[1]?.firstElementChild?.firstElementChild?.firstElementChild?.innerHTML ?? '';
        return { type, id };
    };
    const getTicketName = async () => {
        const section = await waitForElement(nameSection);
        // NOTE: risky to change by Atlassian
        const name = section?.innerHTML ?? '';
        return name;
    };
    const injectToolbar = async (branchName) => {
        const buttonId = 'copy-branch-name-btn';
        if (document.getElementById(buttonId)) {
            return;
        }
        const onCopy = () => {
            GM_setClipboard(branchName);
        };
        const controllerElement = `
    <button id="${buttonId}" style="margin-left: 8px;">Copy Git Branch</button>
`;
        const section = await waitForElement(toolbarSection);
        section?.parentElement?.insertAdjacentHTML('beforeend', controllerElement);
        const copyButton = await waitForElement(`button[id="${buttonId}"]`);
        copyButton?.addEventListener('click', onCopy);
    };
    const generateBranchName = (type, id, name) => {
        const prefix = type === 'bug' ? 'fix' : 'feature';
        const symbolRegex = /[^\w\s]/gi;
        const title = name
            .replace(/(\[.*?\])/g, '') // NOTE: replace bracket contents
            .replace(symbolRegex, ' ')
            .trim()
            .split(' ')
            .filter((word) => word)
            .map((word) => word.toLowerCase())
            .join('-');
        return `${prefix}/${id}-${title}`;
    };
    window.addEventListener('load', async () => {
        // NOTE: polling for ticket changing because Atlassian not reload the page after changed branch
        setInterval(async () => {
            const { type, id } = await getTicketCode();
            const name = await getTicketName();
            const branchName = generateBranchName(type, id, name);
            log(branchName);
            await injectToolbar(branchName);
        }, 1000);
    });
})();