(function () {

    function qaEscapeHtml(value) {
        return String(value ?? "")
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#39;");
    }

    function qaSafeUrl(url) {
        const v = String(url ?? "").trim();
        return /^(https?:|data:image\/)/i.test(v) ? qaEscapeHtml(v) : "";
    }

    function qaEscapeJsArg(value) {
        return qaEscapeHtml(JSON.stringify(String(value ?? "")));
    }

    let context = null;
    let currentWorkItemId = 0;
    let timeloggingWorkItemId = 0;
    let isTimeLoggingStarted = false;
    let defaultWorkTypeId = null;
    let defaultWorkTypeTitle = "";
    let hasTimesheetLicense = true;
    const NO_LICENSE_TOOLTIP = "You don't have Timesheet License";
    const DEFAULT_QUICK_LOG_MINUTES = [15, 30, 45, 60];

    async function init() {
        context = await buildContext();
        if (!context.workItemId) return;

        currentWorkItemId = context.workItemId;

        bindUIEvents();
        GetTimeTrackingStatus();
        await resolveDefaultWorkTypeId();
        resolveQuickLogButtonMinutes();

        const ptUserType = await checkTimesheetLicense();
        if (ptUserType === null || ptUserType === undefined) {
            hasTimesheetLicense = false;
            applyLogTimePermission();
        }
    }

    function formatQuickLogLabel(minutes) {
        const hours = Math.floor(minutes / 60);
        const mins = minutes % 60;
        if (hours === 0) return `${mins}m`;
        if (mins === 0) return `${hours}h`;
        return `${hours}h${mins}m`;
    }

    function renderQuickLogButtons(minutesList) {
        const group = document.querySelector(".timesheet-quick-log-group");
        if (!group) return;

        const workTypeLabel = defaultWorkTypeTitle || "default work type";
        group.innerHTML = minutesList.map(minutes => {
            const label = formatQuickLogLabel(minutes);
            const title = hasTimesheetLicense ? `Log ${label} of ${workTypeLabel} time` : NO_LICENSE_TOOLTIP;
            return `<button class="timesheet-action-btn" data-minutes="${minutes}" title="${title}">${label}</button>`;
        }).join("");

        attachQuickLogButtonListeners();
    }

    function attachQuickLogButtonListeners() {
        document.querySelectorAll("[data-minutes]").forEach(btn => {
            btn.addEventListener("click", () => {
                if (!hasTimesheetLicense) return;

                const minutes = parseInt(btn.dataset.minutes, 10);
                QuickLogTime(minutes, btn);
            });
        });
    }

    async function resolveQuickLogButtonMinutes() {
        try {
            const res = await IndexLibrary.GetRequest({
                baseAPIUrl: context.baseAPIUrl,
                endpoint: `/api/TimesheetSettings/GetSettings/${encodeURIComponent(context.organizationName)}`,
                azureAuthenticationHeader: context.accessToken,
                organizationName: context.organizationName,
                organizationId: context.organizationId
            });

            if (!res.ok) return;

            const json = await res.json();
            const minutes = Array.isArray(json.quickLogButtonMinutes)
                ? json.quickLogButtonMinutes.filter(n => Number.isInteger(n) && n > 0)
                : [];

            if (minutes.length === 4) {
                renderQuickLogButtons(minutes);
            }
        } catch {
            // Static default buttons already in the DOM will keep working.
        }
    }

    async function resolveDefaultWorkTypeId() {
        try {
            const res = await IndexLibrary.GetRequest({
                baseAPIUrl: context.baseAPIUrl,
                endpoint: `/api/TrackingWorkType/GetAll/${encodeURIComponent(context.organizationName)}`,
                azureAuthenticationHeader: context.accessToken,
                organizationName: context.organizationName,
                organizationId: context.organizationId
            });

            if (!res.ok) return;

            const types = await res.json();
            if (!Array.isArray(types)) return;

            const match = types.find(t => !t.isDeleted && t.isDefault);

            if (match) {
                defaultWorkTypeId = match.id;
                defaultWorkTypeTitle = match.trackingWorkTypeTitle || "";
            }
        } catch {
            // Quick-log will still work without a resolved work type id.
        }
    }

    async function buildContext() {
        await IndexLibrary.InitializeSDK();

        const [organizationName, project, accessToken, workItemId, config] = await Promise.all([
            IndexLibrary.GetAccountNameAsync(),
            IndexLibrary.GetCurrentProject(),
            IndexLibrary.GetAccessToken(),
            IndexLibrary.CurrentWorkItem().catch(() => ""),
            IndexLibrary.GetExtensionConfig()
        ]);

        return {
            organizationName,
            organizationId: IndexLibrary.GetAccountId(),
            projectId: project?.id,
            projectName: project?.name,
            userEmail: IndexLibrary.GetUserEmail?.(),
            accessToken,
            workItemId,
            baseAPIUrl: config?.apiBaseUrl
        };
    }

    async function checkTimesheetLicense() {
        const endpoint =
            `/api/License/GetUserLicenseType` +
            `?organizationName=${encodeURIComponent(context.organizationName)}` +
            `&email=${encodeURIComponent(context.userEmail)}` +
            `&fieldName=ptUserType`;

        const res = await IndexLibrary.GetRequest({
            baseAPIUrl: context.baseAPIUrl,
            endpoint,
            azureAuthenticationHeader: context.accessToken,
            organizationName: context.organizationName,
            organizationId: context.organizationId
        });

        if (!res.ok) return null;

        const text = await res.text();
        return text && text.trim() !== "" ? JSON.parse(text) : null;
    }

    function applyLogTimePermission() {
        const widget = document.querySelector(".timesheet-quick-widget");
        if (widget) {
            widget.classList.add("license-disabled");
        }

        document.querySelectorAll(".timesheet-quick-toolbar button").forEach(btn => {
            btn.title = NO_LICENSE_TOOLTIP;
        });
    }

    function bindUIEvents() {
        document.getElementById("addTime")?.addEventListener("click", () => {
            if (!hasTimesheetLicense) return;

            if (typeof IndexLibrary?.HandleTimeTrackingMenuOptionClick === "function") {
                IndexLibrary.HandleTimeTrackingMenuOptionClick({
                    id: currentWorkItemId,
                    apiUrl: context.baseAPIUrl
                });
            }
        });

        attachQuickLogButtonListeners();
    }

    function QuickLogTime(minutes, btn) {
        if (!hasTimesheetLicense) return;

        const workStarted = new Date();
        const workEnded = new Date(workStarted.getTime() + minutes * 60000);
        const label = formatQuickLogLabel(minutes);

        if (btn) btn.disabled = true;

        IndexLibrary.PostRequest({
            baseAPIUrl: context.baseAPIUrl,
            endpoint: `/api/Timesheet/CreateTimesheet`,
            azureAuthenticationHeader: context.accessToken,
            organizationName: context.organizationName,
            organizationId: context.organizationId,
            headers: {
                DevOpsProjectId: String(context.projectId)
            },
            body: {
                organizationName: context.organizationName,
                workItemId: currentWorkItemId,
                userEmail: context.userEmail,
                workStarted: workStarted.toISOString(),
                workEnded: workEnded.toISOString(),
                trackingWorkItemTypeId: defaultWorkTypeId,
                description: "",
                isBillable: false,
                projectId: context.projectId,
                projectName: context.projectName
            }
        })
            .then(res => {
                if (res.ok) {
                    showInlineToast("success", `Logged ${label} of ${defaultWorkTypeTitle || "default work type"} time`);
                } else {
                    showInlineToast("error", "Failed to log time. Please try again.");
                }
            })
            .catch(() => {
                showInlineToast("error", "Failed to log time. Please try again.");
            })
            .finally(() => {
                if (btn) btn.disabled = false;
            });
    }

    let toastHideTimeout = null;

    function showInlineToast(type, message) {
        const toast = document.getElementById("quickLogToast");
        const icon = document.getElementById("quickLogToastIcon");
        const text = document.getElementById("quickLogToastText");
        if (!toast || !icon || !text) return;

        clearTimeout(toastHideTimeout);

        icon.className = `bi ${type === "success" ? "bi-check-circle-fill" : "bi-x-circle-fill"}`;
        text.textContent = message;
        toast.className = `timesheet-quick-toast show ${type}`;

        toastHideTimeout = setTimeout(() => {
            toast.classList.remove("show");
        }, 1800);
    }

    function renderTimeLoggingButton() {
        const container = document.getElementById("timeLoggingContainer");
        if (!container || !currentWorkItemId) return;

        if (!isTimeLoggingStarted) {
            const title = hasTimesheetLicense ? "Start time tracking for this work item" : NO_LICENSE_TOOLTIP;
            container.innerHTML = `
                <button class="timesheet-action-btn" onclick="StartStopTimeLoggingQuick()" title="${qaEscapeHtml(title)}">
                    <i class="bi bi-play"></i>
                    Start
                </button>
            `;
            return;
        }

        const workItemUrl = `https://dev.azure.com/${context.organizationName}/_workitems/edit/${timeloggingWorkItemId}`;
        const stopTitle = hasTimesheetLicense ? "Stop time tracking for this work item" : NO_LICENSE_TOOLTIP;

        container.innerHTML = `
            <div style="display:flex; align-items:center; gap:8px;">
                <div class="workitem-pill" onclick="window.open(${qaEscapeJsArg(workItemUrl)}, '_blank')" title="Open the work item currently being tracked">
                    <i class="bi bi-clock"></i>
                    <span id="workItemId">${qaEscapeHtml(timeloggingWorkItemId)}</span>
                </div>
                <button class="timesheet-action-btn" onclick="StartStopTimeLoggingQuick()" title="${qaEscapeHtml(stopTitle)}">
                    <i class="bi bi-stop"></i>
                    Stop
                </button>
            </div>
        `;
    }

    window.StartStopTimeLoggingQuick = async function () {
        if (!hasTimesheetLicense) return;

        const endpoint = isTimeLoggingStarted
            ? `/api/Timesheet/StopTimeLogging`
            : `/api/Timesheet/StartTimeLogging`;

        IndexLibrary.PostRequest({
            baseAPIUrl: context.baseAPIUrl,
            endpoint,
            azureAuthenticationHeader: context.accessToken,
            organizationName: context.organizationName,
            organizationId: context.organizationId,
            headers: {
                DevOpsProjectId: String(context.projectId)
            },
            body: {
                organizationName: context.organizationName,
                workItemId: currentWorkItemId,
                userEmail: context.userEmail,
                projectId: context.projectId,
                projectName: context.projectName
            }
        })
            .then(r => r.json())
            .then(success => {
                if (success === true) {
                    isTimeLoggingStarted = !isTimeLoggingStarted;
                    timeloggingWorkItemId = currentWorkItemId;
                    renderTimeLoggingButton();
                }
            });
    };

    function GetTimeTrackingStatus() {
        IndexLibrary.PostRequest({
            baseAPIUrl: context.baseAPIUrl,
            endpoint: `/api/Timesheet/IsTimeLoggingStarted`,
            azureAuthenticationHeader: context.accessToken,
            organizationName: context.organizationName,
            organizationId: context.organizationId,
            headers: {
                DevOpsProjectId: String(context.projectId)
            },
            body: {
                organizationName: context.organizationName,
                userEmail: context.userEmail
            }
        })
            .then(r => r.json())
            .then(json => {
                isTimeLoggingStarted = json.isStarted === true;
                timeloggingWorkItemId = json.workItemId || 0;
                renderTimeLoggingButton();
            });
    }

    document.addEventListener("DOMContentLoaded", init);

})();
