let projectName = "";
let organizationName = "";

let releaseList = [];
let releaseSearchIndex = [];
let workItemIds = [];
let searchDebounceTimer = null;

function buildReleaseSearchIndex() {
    releaseSearchIndex = releaseList.map(r => ({
        releaseId: r.releaseId,
        releaseName: r.releaseName,
        releaseNameLower: String(r.releaseName || "").toLowerCase(),
        workItems: r.workItems
    }));
}

function renderReleaseList(filter = "") {
    const container = $("#releaseListContainer");
    container.empty();
    const containerEl = container[0];

    const normalizedFilter = String(filter).toLowerCase();
    const filtered = normalizedFilter
        ? releaseSearchIndex.filter(r => r.releaseNameLower.includes(normalizedFilter))
        : releaseSearchIndex;

    if (filtered.length === 0) {
        const emptyMessage = document.createElement("div");
        emptyMessage.className = "px-2 py-1 text-muted";
        emptyMessage.textContent = "No matches";
        containerEl.appendChild(emptyMessage);
        return;
    }

    const fragment = document.createDocumentFragment();
    filtered.forEach(r => {
        const item = document.createElement("li");
        item.className = "dropdown-item release-item";
        item.dataset.id = String(r.releaseId);
        item.dataset.name = r.releaseName;
        item.textContent = r.releaseName;
        fragment.appendChild(item);
    });

    containerEl.appendChild(fragment);
}

function getSelectedWorkItemIdsFromContext() {
    const contextData = IndexLibrary.GetPanelContext();
    if (contextData.workItemIds?.length > 0) {
        return contextData.workItemIds;
    }

    if (contextData.id) {
        return [contextData.id];
    }

    return [];
}

function getCountText(ids) {
    return ids.length === 1
        ? `1 work item selected (ID: ${ids[0]})`
        : `${ids.length} work items selected (IDs: ${ids.join(', ')})`;
}

function findSelectedRelease(selectedReleaseIdText) {
    return releaseList.find(r => String(r.releaseId) === selectedReleaseIdText);
}

function normalizeWorkItemIds(ids) {
    return ids.map(id => String(id).trim()).filter(Boolean);
}

function getUpdatedWorkItems(existingWorkItemsValue, selectedIds) {
    const existingWorkItems = existingWorkItemsValue
        ? normalizeWorkItemIds(existingWorkItemsValue.split(','))
        : [];

    const newWorkItems = normalizeWorkItemIds(selectedIds);
    return Array.from(new Set([...existingWorkItems, ...newWorkItems]));
}

function buildReleaseUpdatePayload(releaseData, updatedWorkItems) {
    return {
        releaseId: releaseData.releaseId,
        releaseName: releaseData.releaseName,
        releaseStartDate: releaseData.releaseStartDate,
        releaseEndDate: releaseData.releaseEndDate,
        monitoringType: releaseData.monitoringType ?? 0,
        manualProgress: releaseData.manualProgress ?? 0,
        releaseStatus: releaseData.releaseStatus ?? 0,
        organizationName: releaseData.organizationName || organizationName,
        organizationId: releaseData.organizationId,
        workItems: updatedWorkItems.join(','),
        releaseState: 0,
        releaseHealth: releaseData.releaseHealth ?? 0,
        projectName: releaseData.projectName || projectName
    };
}

async function handleAddToReleaseClick() {
    const addButton = $('#btnAddToRelease');
    if (addButton.prop('disabled')) {
        return;
    }

    const selectedReleaseId = $('#selectedReleaseId').val();
    const selectedReleaseIdText = String(selectedReleaseId);

    if (!selectedReleaseIdText) {
        await IndexLibrary.ShowToast('warning', 'Please select a release');
        return;
    }

    const releaseData = findSelectedRelease(selectedReleaseIdText);

    if (!releaseData) {
        await IndexLibrary.ShowToast('warning', 'Release does not exist');
        return;
    }

    try {
        addButton.prop('disabled', true);
        const updatedWorkItems = getUpdatedWorkItems(releaseData.workItems, workItemIds);
        const payload = buildReleaseUpdatePayload(releaseData, updatedWorkItems);

        const response = await IndexLibrary.PostRequest({
            endpoint: "/api/Release/Update",
            body: payload
        });

        if (!response.ok) {
            const errorText = await response.text();
            throw new Error(errorText);
        }

        await IndexLibrary.ShowToast('success', `${workItemIds.length} work item(s) added to release "${releaseData.releaseName}"`);
        IndexLibrary.ClosePanel(null);

    } catch (error) {
        console.error("Error updating release:", error);
        const errorMessage = error?.message || 'Failed to update release.';
        await IndexLibrary.ShowToast('error', errorMessage);
    } finally {
        addButton.prop('disabled', false);
    }
}

function handleReleaseItemClick() {
    const id = $(this).data("id");
    const name = $(this).data("name");

    $("#selectedReleaseId").val(id);
    $("#releaseDropdownText").text(name);

    bootstrap.Dropdown.getInstance($("#releaseDropdownBtn")[0]).hide();
}

function handleCancelReleaseClick() {
    IndexLibrary.ClosePanel(null);
}

function handleReleaseSearchInput() {
    const text = $(this).val();

    if (searchDebounceTimer) {
        window.clearTimeout(searchDebounceTimer);
    }

    searchDebounceTimer = window.setTimeout(function () {
        renderReleaseList(text);
    }, 100);
}

$(document).ready(async function () {
    try {
        await IndexLibrary.ensureSdkReady();
        ({ projectName, organizationName } = await initializeIndexLibraryValues());

        const releaseResponse = await IndexLibrary.GetRequest({
            endpoint: `/api/Release/GetReleases/${projectName}`
        });

        if (!releaseResponse.ok) {
            const errorText = await releaseResponse.text();
            throw new Error(errorText || `Failed to load releases (${releaseResponse.status})`);
        }

        releaseList = await releaseResponse.json();
        buildReleaseSearchIndex();
    } catch (e) {
        console.error("Error loading releases:", e);
        await IndexLibrary.ShowToast('error', 'Failed to load releases');
        return;
    }

    renderReleaseList();

    $("#releaseSearchInput").on("input", handleReleaseSearchInput);

    $("#releaseListContainer").on("click", ".release-item", handleReleaseItemClick);

    workItemIds = getSelectedWorkItemIdsFromContext();
    $('#workItemCount').text(getCountText(workItemIds));

    $('#btnCancelRelease').on('click', handleCancelReleaseClick);

    $('#btnAddToRelease').on('click', handleAddToReleaseClick);
});
