var currentWorkItemId = "";
var baseAPIUrl = '';
var azureAuthenticationHeader = '';
let isOrglicenseExpired = false;
var currentWorkItemId = 0;
var timeloggingWorkItemId = 0;
var isTimeLoggingStarted = false;
var areActionButtonsEnabled = false;
const fieldName = "ptUserType";
var defaultWorkTypeId = null;
var defaultWorkTypeTitle = "";

// Buttons start disabled and only turn on once BOTH checks say yes, so there's never a
// flash of an "enabled-looking" button before license checks complete.
var generalLicenseOk = false;
var timesheetLicenseOk = false;

function refreshActionButtonsState() {
    const enabled = generalLicenseOk && timesheetLicenseOk;
    const tooltip = (!enabled && generalLicenseOk && !timesheetLicenseOk)
        ? "You don't have Timesheet License"
        : undefined;
    setActionButtonsEnabled(enabled, tooltip);
}

IndexLibrary.InitializeSDK().then(async function () {
    await Load();
    await applyLogTimePermission();
    if (currentWorkItemId && baseAPIUrl) {
        await IndexLibrary.LoadTimesheets(baseAPIUrl, azureAuthenticationHeader, currentWorkItemId, generalLicenseOk);
    }

    await resolveDefaultWorkTypeId();
    resolveQuickLogButtonMinutes();
});

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 container = $("#quicklogContainer");
    if (!container.length) return;

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

    // New elements start at full opacity/pointer cursor from the template above; reapply
    // whatever the current enabled/disabled + tooltip state is so they don't look clickable
    // if the buttons are actually still license-disabled.
    setButtonState(".quicklog-btn", areActionButtonsEnabled, areActionButtonsEnabled ? undefined : "You don't have Timesheet License");
}

async function resolveQuickLogButtonMinutes() {
    try {
        const orgName = await IndexLibrary.GetAccountNameAsync();
        const response = await IndexLibrary.GetRequest({
            endpoint: `/api/TimesheetSettings/GetSettings/${orgName}`
        });

        if (!response.ok) return;

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

        if (minutes.length === 4) {
            renderQuickLogButtons(minutes);
        }
    } catch (error) {
        console.error("Failed to resolve quick-log button minutes:", error);
    }
}

async function resolveDefaultWorkTypeId() {
    try {
        const orgName = await IndexLibrary.GetAccountNameAsync();
        const response = await IndexLibrary.GetRequest({
            endpoint: `/api/TrackingWorkType/GetAll/${orgName}`
        });

        if (!response.ok) return;

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

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

        if (match) {
            defaultWorkTypeId = match.id;
            defaultWorkTypeTitle = match.trackingWorkTypeTitle || "";
        }
    } catch (error) {
        console.error("Failed to resolve default work type id:", error);
    }
}

function setButtonState(buttonSelector, isEnabled, disabledTooltip) {
    const btn = $(buttonSelector);
    if (!btn.length) return;

    // Buttons stay natively enabled (no `disabled`/`pointer-events:none`) so hover still
    // fires and the tooltip can show; every click handler already checks
    // areActionButtonsEnabled/isEnabled before doing anything, so this is still safe.
    btn.css('opacity', isEnabled ? '1' : '0.5');
    btn.css('cursor', isEnabled ? 'pointer' : 'not-allowed');

    if (!isEnabled && disabledTooltip) {
        if (btn.data('originalTitle') === undefined) {
            btn.data('originalTitle', btn.attr('title') || '');
        }
        btn.attr('title', disabledTooltip);
    } else if (isEnabled && btn.data('originalTitle') !== undefined) {
        btn.attr('title', btn.data('originalTitle'));
        btn.removeData('originalTitle');
    }
}

function setActionButtonsEnabled(isEnabled, disabledTooltip) {
    areActionButtonsEnabled = isEnabled;
    setButtonState("#addTime", isEnabled, disabledTooltip);
    setButtonState("#startLogging", isEnabled, disabledTooltip);
    setButtonState(".quicklog-btn", isEnabled, disabledTooltip);
}

async function PopulateAzureAuthenticationHeader() {
    azureAuthenticationHeader = await IndexLibrary.GetAccessToken();
    // VSS.require(["VSS/Authentication/Services"],
    //     function (VSS_Auth_Service) {
    //         VSS.getAccessToken().then(function (token) {
    //             var authHeader = VSS_Auth_Service.authTokenManager.getAuthorizationHeader(token);
    //             var authHeaderSplit = authHeader.split(' ');
    //             azureAuthenticationHeader = authHeaderSplit[1];
    //         })
    //     })
}

function changeTimeFormat(date) {


    let hours = date.getHours();
    let minutes = date.getMinutes();

    // Check whether AM or PM
    let newformat = hours >= 12 ? 'PM' : 'AM';

    // Find current hour in AM-PM Format
    hours = hours % 12;

    // To display "0" as "12"
    hours = hours ? hours : 12;
    minutes = minutes < 10 ? '0' + minutes : minutes;

    return hours + ':' + minutes + ' ' + newformat;
}

async function CreateTrialLicense() {
    await IndexLibrary.AutoCreateTrialLicense();
}

async function SaveTimesheet() {
    var currentProjectName = await IndexLibrary.GetCurrentProjectName();
    var orgName = await IndexLibrary.GetAccountNameAsync();
    IndexLibrary.PostRequest({
        endpoint: '/api/Timesheet/CreateTimesheet',
        body: {
            organizationName: orgName,
            workItemId: currentWorkItemId,
            userEmail: IndexLibrary.GetUserEmail(),
            workStarted: $("#start-time").val(),
            workEnded: $("#end-time").val(),
            trackingWorkItemTypeId: null,
            description: $("#description").val(),
            projectId: IndexLibrary.GetCurrentProjectId(),
            projectName: currentProjectName
        }
    })
        .then((response) => response.json())
        .then(async function (json) {
            const Toast = Swal.mixin({
                toast: true,
                position: 'top-end',
                showConfirmButton: false,
                timer: 3000,
                didOpen: (toast) => {
                    toast.addEventListener('mouseenter', Swal.stopTimer)
                    toast.addEventListener('mouseleave', Swal.resumeTimer)
                }
            });

            Toast.fire({
                icon: 'success',
                title: 'Time recorded successfully'
            });
            await IndexLibrary.LoadTimesheets(baseAPIUrl, azureAuthenticationHeader, currentWorkItemId, generalLicenseOk);
            $("#start-time").val();
            $("#end-time").val();
            $("#description").val();
            $("#work-type").val();
            $('#create-timesheet-popup').hide();

        });
}

$(document).ready(function () {

    $('#start-time').datetimepicker({
        format: 'm/d/Y h:i A',
        formatTime: 'h:i A',
        autoClose: true,
        todayHighlight: 'TRUE',
        validateOnBlur: false
        // options here

    });

    $('#end-time').datetimepicker({
        format: 'm/d/Y h:i A',
        formatTime: 'h:i A',
        autoClose: true,
        todayHighlight: 'TRUE',
        validateOnBlur: false
        // options here

    });

})

async function Load() {
    var orgName = await IndexLibrary.GetAccountNameAsync();
    //VSS.require(["dist/index"], async function (app) {
    $("#licenseExpired").hide();
    $("#startTrialMessage").hide();
    $("#authorizationErrorMessage").hide();
    try {
        const config = await IndexLibrary.GetExtensionConfig();
        baseAPIUrl = config.apiBaseUrl;
        currentWorkItemId = await IndexLibrary.CurrentWorkItem();
        await PopulateAzureAuthenticationHeader();

        let getLicenseRequest = { organizationName: orgName };
        const getLicenseResponse = await IndexLibrary.PostRequest({
            endpoint: '/api/License/GetLicense',
            body: getLicenseRequest
        });

        if (getLicenseResponse.status == 404) {
            $("#startTrialMessage").show();
            CreateTrialLicense();
            $("#main").hide();
            return;
        }

        const licenseData = await getLicenseResponse.json();
        if (licenseData.status !== undefined && licenseData.status == 404) {
            $("#startTrialMessage").show();
            CreateTrialLicense();
            $("#main").hide();
            return;
        }

        const userLicenseResponse = await IndexLibrary.GetRequest({
            endpoint: `/api/License/IsUserLicensed?organizationName=${orgName}&email=${IndexLibrary.GetUserEmail()}&moduleUserType=ptUserType`
        });
        const userLicenseData = await userLicenseResponse.text();

        if (userLicenseData.toLowerCase() == 'false') {
            $("#startTrialMessage").hide();
            $("#licenseExpired").hide();
            $("#unauthorized").hide();
            $("#authorizationErrorMessage").show();
            $("#authorizationErrorMessage").text("You are not authorized to perform this action. Please contact your organization administrator.");
            generalLicenseOk = false;
            refreshActionButtonsState();
            await IndexLibrary.LoadTimesheets(baseAPIUrl, azureAuthenticationHeader, currentWorkItemId, false);
            return;
        }

        const orgLicenseValidityResponse = await IndexLibrary.GetRequest({
            endpoint: `/api/License/IsOrgLicenseValid?organizationName=${orgName}`
        });
        const orgLicenseValidityData = await orgLicenseValidityResponse.text();

        if (orgLicenseValidityData.toLowerCase() == 'false') {
            $("#startTrialMessage").show();
            $("#startTrialMessage").text("Your license is invalid or expired. Please contact your organization administrator.");
            $("#licenseExpired").hide();
            $("#unauthorized").hide();
            $("#authorizationErrorMessage").hide();
            generalLicenseOk = false;
            refreshActionButtonsState();
            await IndexLibrary.LoadTimesheets(baseAPIUrl, azureAuthenticationHeader, currentWorkItemId, false);
            return;
        }

        if (licenseData.expiryDateTimeUtc) {
            const expiryDate = new Date(licenseData.expiryDateTimeUtc);
            const today = new Date();
            isOrglicenseExpired = today > expiryDate;
            window.isOrglicenseExpired = isOrglicenseExpired;
        }

        if (licenseData.licenseType === 0) {
            $("#startTrialMessage").show();
            const licenseExpiryDate = new Date(licenseData.expiryDateTimeUtc);
            if (isOrglicenseExpired) {
                $("#startTrialMessage").text("Your license is invalid or expired. Please contact your organization administrator.");
                generalLicenseOk = false;
            } else {
                $("#startTrialMessage").text("Devops Assist AI trial license is valid until " + licenseExpiryDate.toLocaleDateString("en-US"));
                generalLicenseOk = true;
            }
        } else {
            $("#startTrialMessage").hide();
            generalLicenseOk = true;
        }

        refreshActionButtonsState();

        $("#main").show();
        $("#licenseExpired").hide();
        $("#unauthorized").hide();
        $("#authorizationErrorMessage").hide();

        await GetTimeTrackingStatus();
        await IndexLibrary.LoadTimesheets(baseAPIUrl, azureAuthenticationHeader, currentWorkItemId, generalLicenseOk);
    } catch (error) {
        $("#startTrialMessage").show();
    }

    //});
}

async function QuickLogTime(minutes, buttonEl) {
    if (!areActionButtonsEnabled || !currentWorkItemId || !baseAPIUrl) {
        return;
    }

    var currentProjectName = await IndexLibrary.GetCurrentProjectName();
    var currentProjectId = await IndexLibrary.GetCurrentProjectId();
    var orgName = await IndexLibrary.GetAccountNameAsync();
    var workStarted = new Date();
    var workEnded = new Date(workStarted.getTime() + minutes * 60000);
    var label = formatQuickLogLabel(minutes);

    if (buttonEl) setButtonState(buttonEl, false);

    IndexLibrary.PostRequest({
        endpoint: '/api/Timesheet/CreateTimesheet',
        body: {
            organizationName: orgName,
            workItemId: currentWorkItemId,
            userEmail: IndexLibrary.GetUserEmail(),
            workStarted: workStarted.toISOString(),
            workEnded: workEnded.toISOString(),
            trackingWorkItemTypeId: defaultWorkTypeId,
            description: "",
            isBillable: false,
            projectId: currentProjectId,
            projectName: currentProjectName
        }
    })
        .then(async (response) => {
            const Toast = Swal.mixin({
                toast: true,
                position: 'top-end',
                showConfirmButton: false,
                timer: 3000,
                didOpen: (toast) => {
                    toast.addEventListener('mouseenter', Swal.stopTimer)
                    toast.addEventListener('mouseleave', Swal.resumeTimer)
                }
            });

            if (response.ok) {
                Toast.fire({
                    icon: 'success',
                    title: `Logged ${label} of ${defaultWorkTypeTitle || "default work type"} time`
                });
                await IndexLibrary.LoadTimesheets(baseAPIUrl, azureAuthenticationHeader, currentWorkItemId, generalLicenseOk);
            } else {
                Toast.fire({
                    icon: 'error',
                    title: 'Failed to log time. Please try again.'
                });
            }
        })
        .catch(() => {
            Swal.fire({
                toast: true,
                position: 'top-end',
                showConfirmButton: false,
                timer: 3000,
                icon: 'error',
                title: 'Failed to log time. Please try again.'
            });
        })
        .finally(() => {
            if (buttonEl && areActionButtonsEnabled) {
                setButtonState(buttonEl, true);
            }
        });
}

$(document)
    .off("click", ".quicklog-btn")
    .on("click", ".quicklog-btn", function () {
        const minutes = parseInt($(this).data("minutes"), 10);
        QuickLogTime(minutes, this);
    });

$(document)
    .off("click", ".logTimeButton")
    .on("click", ".logTimeButton", function () {
        if (!areActionButtonsEnabled) {
            return;
        }
        if (!currentWorkItemId || !baseAPIUrl || !azureAuthenticationHeader) {
            console.warn("Log Time click ignored: required data not ready yet");
            return;
        }

        IndexLibrary.HandleTimeTrackingMenuOptionClick({
            id: currentWorkItemId,
            timesheetTable: $("#timesheetsTable"),
            totalLoggedHoursLabel: $("#workitem-page-logged-hours-button"),
            apiUrl: baseAPIUrl,
            azureAuthenticationHeader: azureAuthenticationHeader
        });
    });

$(document)
    .off("click", ".editTimesheet")
    .on("click", ".editTimesheet", function (e) {
        if (!areActionButtonsEnabled) {
            e.preventDefault();
            e.stopPropagation();
            return false;
        }
    });

window.addEventListener('message', (event) => {
    if (localStorage.getItem("timeSheetChanged") === "true") {
        localStorage.removeItem("timeSheetChanged");
        Load();
    }
});

async function GetTimeTrackingStatus() {
    try {
        const response = await IndexLibrary.PostRequest({
            endpoint: '/api/Timesheet/IsTimeLoggingStarted',
            body: {
                organizationName: await IndexLibrary.GetAccountNameAsync(),
                userEmail: IndexLibrary.GetUserEmail()
            }
        });

        if (!response.ok) {
            throw new Error(`Failed to fetch time tracking status (${response.status})`);
        }

        const result = await response.json();
        isTimeLoggingStarted = Boolean(result?.isStarted);
        timeloggingWorkItemId = isTimeLoggingStarted
            ? Number(result?.workItemId) || 0
            : 0;
    }
    catch (error) {
        console.error("Error getting time tracking status:", error);
        // Graceful fallback so UI doesn’t break
        isTimeLoggingStarted = false;
        timeloggingWorkItemId = 0;
    }
    finally {
        // Always update UI
        renderTimeLoggingButton();
    }
}

async function renderTimeLoggingButton() {

    if (!currentWorkItemId || currentWorkItemId === 0) return;

    const container = $("#timeLoggingContainer");
    const accountName = await IndexLibrary.GetAccountNameAsync();

    // ---------------- Not started ----------------
    if (!isTimeLoggingStarted) {
        container.html(`
            <button id="startLogging" class="timesheet-action-btn" onclick="StartStopTimeLogging();" title="Start time tracking for this work item">
                <i class="bi bi-play"></i>
                Start Time Logging
            </button>
        `);
        setButtonState("#startLogging", areActionButtonsEnabled);
        return;
    }

    // ---------------- Started ----------------
    const workItemUrl =
        `https://dev.azure.com/${accountName}/_workitems/edit/${timeloggingWorkItemId}`;

    container.html(`
        <div class="workitem-pill"
             onclick="window.open(${IndexLibrary.escapeHtml(JSON.stringify(workItemUrl))}, '_blank')" title="Open the work item currently being tracked">
            <i class="bi bi-clock"></i>
            <span>${IndexLibrary.escapeHtml(timeloggingWorkItemId)}</span>
        </div>

        <button id="startLogging" class="timesheet-action-btn" onclick="StartStopTimeLogging();" title="Stop time tracking for this work item">
            <i class="bi bi-stop"></i>
            Stop Time Logging
        </button>
    `);
    setButtonState("#startLogging", areActionButtonsEnabled);
}

async function StartStopTimeLogging() {
    if (!areActionButtonsEnabled) {
        return;
    }
    try {
        var timeLoggingEndpoint = "";
        if (isTimeLoggingStarted) {
            timeLoggingEndpoint = '/api/Timesheet/StopTimeLogging';
        } else {
            timeLoggingEndpoint = '/api/Timesheet/StartTimeLogging';
        }
        var currentProjectName = await IndexLibrary.GetCurrentProjectName();
        var currentProjectId = await IndexLibrary.GetCurrentProjectId();
        const response = await IndexLibrary.PostRequest({
            endpoint: timeLoggingEndpoint,
            body: {
                organizationName: await IndexLibrary.GetAccountNameAsync(),
                workItemId: currentWorkItemId,
                userEmail: IndexLibrary.GetUserEmail(),
                projectId: currentProjectId,
                projectName: currentProjectName
            }
        });

        if (!response.ok) {
            throw new Error(`Time logging request failed (${response.status})`);
        }

        const success = await response.json();
        if (success === true) {
            isTimeLoggingStarted = !isTimeLoggingStarted;
            timeloggingWorkItemId = currentWorkItemId;
            Load();
        }
    }
    catch (error) {
        console.error("Error starting/stopping time logging:", error);
        // Optional: showToast("Unable to update time logging status");
    }
    finally {
        // Always refresh UI
        renderTimeLoggingButton();
    }

}
async function applyLogTimePermission() {

    const section = document.getElementById("timeLoggingSection");
    if (!section) return;

    try {
        const licensedUserType =
            await IndexLibrary.GetUserLicensesType(fieldName, true);

        const disable = !licensedUserType || licensedUserType.trim() === "";

        timesheetLicenseOk = !disable;
        refreshActionButtonsState();

    } catch (err) {
        console.error("License check failed:", err);

    }
}

