(function () {

    let loadingEl;
    let suggestionsEl;
    let currentProjectId = 0;
    let allWorkItemTypes = [];
    let orgWorkItemTypes = [];
    let selectedSuggestionWorkItemTypes = [];
    let cachedWorkItem = null;
    let suggestions = [];
    let acceptedSuggestions = [];
    let previousSuggestions = [];
    const NEW_CHAT_VALUE = "__new__";

    const EA_NON_FORM_FIELDS = new Set([
        'System.Id', 'System.AreaId', 'System.IterationId', 'System.Rev',
        'System.AuthorizedDate', 'System.RevisedDate', 'System.Watermark',
        'System.TeamProject', 'System.PersonId', 'System.AttachedFileCount',
        'System.ExternalLinkCount', 'System.HyperLinkCount', 'System.CommentCount',
        'System.AuthorizedAs', 'System.BoardColumn', 'System.BoardColumnDone',
        'System.BoardLane', 'System.ChangedDate', 'System.NodeName',
        'System.Title', 'System.State'
    ]);

    function hasUsableDefaultValue(value) {
        if (value === null || value === undefined) return false;
        if (typeof value === 'string') return value.trim() !== '';
        return true;
    }

    function getFieldValueCaseInsensitive(obj, key) {
        if (!obj || typeof obj !== 'object') return undefined;
        const matchedKey = Object.keys(obj).find(k => k.toLowerCase() === key.toLowerCase());
        return matchedKey ? obj[matchedKey] : undefined;
    }

    function normalizeKey(value) {
        return String(value || '').trim().toLowerCase();
    }

    function getByNormalizedKey(sourceObj, rawKey) {
        if (!sourceObj || typeof sourceObj !== 'object') return undefined;
        const normalizedTarget = normalizeKey(rawKey);
        const matchedKey = Object.keys(sourceObj).find((key) => normalizeKey(key) === normalizedTarget);
        return matchedKey ? sourceObj[matchedKey] : undefined;
    }

    function parseDefaultFieldsFromResponse(data) {
        if (!Array.isArray(data)) return {};

        const defaultsByWit = {};
        data.forEach((field) => {
            const workItemTypeName = getFieldValueCaseInsensitive(field, 'workItemTypeName');
            const fieldReferenceName = getFieldValueCaseInsensitive(field, 'fieldReferenceName');
            const defaultValue = getFieldValueCaseInsensitive(field, 'defaultValue');

            if (!workItemTypeName || !fieldReferenceName || !hasUsableDefaultValue(defaultValue)) {
                return;
            }

            if (!defaultsByWit[workItemTypeName]) {
                defaultsByWit[workItemTypeName] = {};
            }

            defaultsByWit[workItemTypeName][fieldReferenceName] = defaultValue;
        });

        return defaultsByWit;
    }

    async function resolveProcessIdFromProject(projectId, ctx) {
        if (!projectId) return null;
        try {
            const orgName = ctx.organizationName;

            const projectRes = await fetch(
                `https://dev.azure.com/${orgName}/_apis/projects/${encodeURIComponent(projectId)}?includeCapabilities=true&api-version=7.0`,
                {
                    headers: {
                        'Authorization': `Bearer ${ctx.accessToken}`,
                        'Content-Type': 'application/json'
                    }
                }
            );

            if (projectRes.ok) {
                const projectData = await projectRes.json();
                if (projectData.capabilities && projectData.capabilities.processTemplate && projectData.capabilities.processTemplate.templateTypeId) {
                    return projectData.capabilities.processTemplate.templateTypeId;
                }
            }

            const res = await fetch(
                `https://dev.azure.com/${orgName}/_apis/projects/${encodeURIComponent(projectId)}/properties?api-version=7.1-preview.1`,
                {
                    headers: {
                        'Authorization': `Bearer ${ctx.accessToken}`,
                        'Content-Type': 'application/json'
                    }
                }
            );
            if (!res.ok) return null;
            const data = await res.json();
            const prop = (data.value || []).find(p => p.name === 'System.ProcessTemplateType');
            return prop ? prop.value : null;
        } catch (e) {
            console.error('Error resolving process ID:', e);
            return null;
        }
    }

    async function fetchDefaultFieldsByWorkItemType(projectId, ctx) {
        if (!projectId || !ctx.organizationId) {
            return {};
        }

        try {
            const processId = await resolveProcessIdFromProject(projectId, ctx);
            if (!processId) {
                return {};
            }

            const response = await IndexLibrary.GetRequest({
                baseAPIUrl: ctx.baseAPIUrl,
                endpoint: `/api/Settings/GetWorkItemDefaultFieldsByProcess/${ctx.organizationId}/${processId}`,
                azureAuthenticationHeader: ctx.accessToken,
                organizationName: ctx.organizationName,
                organizationId: ctx.organizationId,
                headers: {
                    'Content-Type': 'application/json'
                }
            });

            if (!response.ok) {
                return {};
            }

            const data = await response.json();
            return parseDefaultFieldsFromResponse(data);
        } catch (e) {
            return {};
        }
    }

    async function fetchDefaultFieldsByChatId(chatId, ctx) {
        if (!chatId || chatId <= 0) {
            return {};
        }

        try {
            const response = await IndexLibrary.GetRequest({
                baseAPIUrl: ctx.baseAPIUrl,
                endpoint: `/api/Settings/GetWorkItemDefaultFieldsByChat/${ctx.organizationId}/${chatId}`,
                azureAuthenticationHeader: ctx.accessToken,
                organizationName: ctx.organizationName,
                organizationId: ctx.organizationId,
                headers: {
                    'Content-Type': 'application/json'
                }
            });

            if (!response.ok) {
                return {};
            }

            const data = await response.json();
            return parseDefaultFieldsFromResponse(data);
        } catch (e) {
            return {};
        }
    }

    function mergeDefaultsByWit(projectDefaultsByWit, chatDefaultsByWit) {
        const merged = {};

        Object.keys(projectDefaultsByWit || {}).forEach((witName) => {
            merged[witName] = {
                ...(projectDefaultsByWit[witName] || {})
            };
        });

        Object.keys(chatDefaultsByWit || {}).forEach((witName) => {
            if (!merged[witName]) {
                merged[witName] = {};
            }

            merged[witName] = {
                ...merged[witName],
                ...(chatDefaultsByWit[witName] || {})
            };
        });

        return merged;
    }

    async function fetchConfigurableFieldsByWitFromProjectDb(projectId, witNames, ctx) {
        if (!projectId || !witNames || witNames.length === 0) return {};
        const classification = await rfFetchFieldClassification(ctx.organizationName, ctx.accessToken);
        const fieldsByWit = {};
        await Promise.all([...new Set(witNames)].map(async (wit) => {
            try {
                const res = await fetch(`https://dev.azure.com/${ctx.organizationName}/${encodeURIComponent(projectId)}/_apis/wit/workitemtypes/${encodeURIComponent(wit)}/fields?$expand=allowedValues&api-version=7.0`,
                    { headers: { Authorization: `Bearer ${ctx.accessToken}` } });
                if (!res.ok) return;
                const fields = ((await res.json()).value || []).filter((f) => {
                    const meta = classification[f.referenceName];
                    return f.alwaysRequired && !(meta && meta.readOnly) && !EA_NON_FORM_FIELDS.has(f.referenceName);
                });
                if (fields.length) {
                    fieldsByWit[wit] = fields.map((f) => {
                        const meta = classification[f.referenceName];
                        return {
                            name: f.name,
                            referenceName: f.referenceName,
                            type: rfResolveFieldType(meta),
                            isIdentity: !!(meta && meta.isIdentity),
                            alwaysRequired: true,
                            readOnly: !!(meta && meta.readOnly),
                            allowedValues: Array.isArray(f.allowedValues) ? f.allowedValues : []
                        };
                    });
                }
            } catch (e) { }
        }));
        if (Object.keys(fieldsByWit).some((w) => fieldsByWit[w].some((f) => f.type === 'identity'))) {
            await rfFetchIdentityPeople(ctx.organizationName, ctx.accessToken);
        }
        return fieldsByWit;
    }

    async function getAllRequiredFieldsByWit(witNames, ctx) {
        if (!Array.isArray(witNames) || witNames.length === 0) {
            return {};
        }

        return await fetchConfigurableFieldsByWitFromProjectDb(ctx.projectId, witNames, ctx);
    }

    async function createWorkItemWithRequiredFields(ctx, suggestion, defaultsByWit) {
        const witType = suggestion.category || 'Task';
        const defaultsForWit = getByNormalizedKey(defaultsByWit, witType) || {};

        const payload = [
            {
                op: "add",
                path: "/fields/System.Title",
                value: suggestion.title || ""
            },
            {
                op: "add",
                path: "/fields/System.Description",
                value: suggestion.description || ""
            }
        ];

        // Add default values
        Object.keys(defaultsForWit).forEach((fieldRef) => {
            const value = defaultsForWit[fieldRef];
            if (hasUsableDefaultValue(value)) {
                payload.push({
                    op: "add",
                    path: `/fields/${fieldRef}`,
                    value: value
                });
            }
        });

        let parentWorkItemId = ctx.workItemId;
        if (!parentWorkItemId) {
            try {
                parentWorkItemId = await IndexLibrary.CurrentWorkItem();
            } catch (e) {
                parentWorkItemId = "";
            }
        }

        if (parentWorkItemId) {
            payload.push({
                op: "add",
                path: "/relations/-",
                value: {
                    rel: "System.LinkTypes.Hierarchy-Reverse",
                    url: `https://dev.azure.com/${await IndexLibrary.GetAccountNameAsync()}/_apis/wit/workItems/${parentWorkItemId}`
                }
            });
        } else {
            console.warn("[evolve] No host work item id resolved; created item will NOT be linked as a child. Save the host work item first.");
        }

        const project = await IndexLibrary.GetCurrentProjectName();
        const wi = await IndexLibrary.CreateWorkItemsInDevops(payload, project, witType);
        return wi.id;
    }

    async function init() {
        const root = document.querySelector(".qa-evolve-root");
        if (!root) {
            console.warn("qa-evolve-root not found yet");
            return;
        }

        loadingEl = document.getElementById("qa-evolve-loading");
        suggestionsEl = document.getElementById("evolve-suggestions-list");

        root.classList.remove("qa-evolve--has-results");
        root.classList.add("qa-evolve--prompt");
        document.getElementById("evolve-footer").classList.add("hidden");
        wireEvents();

        try {
            const ctx = await getContext();
            cachedWorkItem = await IndexLibrary.GetWorkItemWithRelations(ctx.workItemId);
            await loadWorkItemTypes(ctx);
            await initExistingChats(ctx);
            updateCreateButtonState();
            renderTypeSelector();

        } catch (e) {
            console.error("Failed to init evolve:", e);
        }
    }

    function dispose() {
        // optional later: remove listeners, cancel fetch, etc.
    }

    function wireEvents() {
        document
            .getElementById("evolve-generate-btn")
            .addEventListener("click", onGenerate);

        document
            .getElementById("evolve-select-all")
            .addEventListener("change", onSelectAll);

        document
            .getElementById("evolve-create-btn")
            .addEventListener("click", onCreate);

        document
            .getElementById("evolve-create-custom-settings")
            .addEventListener("click", (e) => {
                e.preventDefault();
                onCreateWithCustomSettings();
            });

        const dropdownBtn = document.getElementById("evolve-create-dropdown-btn");
        if (dropdownBtn && typeof bootstrap !== 'undefined') {
            new bootstrap.Dropdown(dropdownBtn);
        }

        document
            .getElementById("evolve-type-toggle")
            .addEventListener("click", () => {
                document
                    .getElementById("evolve-type-panel")
                    .classList.toggle("hidden");
            });
        document.addEventListener("click", (e) => {
            const panel = document.getElementById("evolve-type-panel");
            const toggle = document.getElementById("evolve-type-toggle");

            if (
                !panel.contains(e.target) &&
                !toggle.contains(e.target)
            ) {
                panel.classList.add("hidden");
            }
        });
        document
            .getElementById("evolve-open-chat")
            .addEventListener("click", async () => {
                if (!currentProjectId) return;
                const url = buildEvolveAssistChatUrl(await getContext(), currentProjectId);
                window.open(url, "_blank");
            });
        document
            .getElementById("evolve-previous-header")
            ?.addEventListener("click", () => {
                const content = document.getElementById("evolve-previous-content");
                const toggle = document.getElementById("evolve-prev-toggle");

                const isHidden = content.classList.contains("hidden");
                content.classList.toggle("hidden", !isHidden);
                toggle.classList.toggle("bi-caret-down-fill", !isHidden);
                toggle.classList.toggle("bi-caret-up-fill", isHidden);
            });

    }

    function isEvolveReadOnlyUser() {
        const userType =
            window.QALicenseContext?.productUserTypes?.evolve;
        return userType === 0;
    }

    function buildEvolveAssistChatUrl(ctx, projectId) {
        const hubId = "release-groups-hub-group.create-evolve-assist";

        return (
            `https://dev.azure.com/${ctx.organizationName}/` +
            `${ctx.projectName}/_apps/hub/` +
            `${ctx.publisherId}.${ctx.extensionId}.${hubId}` +
            `?eId=${projectId}`
        );
    }

    async function getContext() {
        if (!window.ensureSDKReady) {
            throw new Error("ensureSDKReady not found. index.js not loaded?");
        }

        await window.ensureSDKReady();
        return window.QAContext;
    }

    async function buildWorkItemContext(ctx) {
        if (!ctx.workItemId) return null;

        const projectName = await IndexLibrary.GetCurrentProjectName();
        const wi = await IndexLibrary.GetWorkItemWithRelations(ctx.workItemId);
        cachedWorkItem = wi;
        const fields = wi.fields || {};

        let relatedWorkItems = [];

        if (wi.relations && wi.relations.length > 0) {
            const groups = {};

            const mapLinkType = (rel = "") => {
                const normalized = rel.replace("System.LinkTypes.", "").toLowerCase();
                if (normalized.includes("hierarchy-reverse")) return "Parent";
                if (normalized.includes("hierarchy-forward")) return "Child";
                if (normalized.includes("dependency-reverse")) return "Predecessor";
                if (normalized.includes("dependency-forward")) return "Successor";
                if (normalized.includes("related")) return "Related";
                return "Other";
            };

            for (const rel of wi.relations) {
                if (!rel.url?.includes("/_apis/wit/workItems/")) continue;
                const id = parseInt(rel.url.split("/").pop());
                const group = mapLinkType(rel.rel);
                if (!groups[group]) groups[group] = [];
                groups[group].push(id);
            }

            const allIds = Object.values(groups).flat();
            if (allIds.length > 0) {
                const relatedItems = await IndexLibrary.GetWorkItemsInDevops(
                    allIds,
                    projectName,
                    [
                        "System.Id",
                        "System.Title",
                        "System.State",
                        "System.WorkItemType",
                        "System.Description",
                        "Microsoft.VSTS.Common.AcceptanceCriteria"
                    ]
                );

                relatedWorkItems = relatedItems.map(r => ({
                    id: String(r.id),
                    title: r.fields["System.Title"] || "",
                    state: r.fields["System.State"] || "",
                    type: r.fields["System.WorkItemType"] || "",
                    description: r.fields["System.Description"] || "",
                    acceptanceCriteria: r.fields["Microsoft.VSTS.Common.AcceptanceCriteria"] || "",
                    linkType: r.linkType || "Related"

                }));
            }
        }

        return {
            Id: ctx.workItemId,
            Title: fields["System.Title"] || "",
            Type: fields["System.WorkItemType"] || "",
            State: fields["System.State"] || "",
            Description: fields["System.Description"] || "",
            AcceptanceCriteria: fields["Microsoft.VSTS.Common.AcceptanceCriteria"] || "",
            Project: ctx.projectName,
            RelatedWorkItems: relatedWorkItems
        };
    }

    function getPromptInput() {
        return document.getElementById("evolve-prompt-input");
    }

    function setGenerateEnabled(enabled) {
        const input = getPromptInput();
        const btn = document.getElementById("evolve-generate-btn");

        input.disabled = !enabled;
        btn.disabled = !enabled;
        btn.style.opacity = enabled ? "1" : "0.6";
    }

    function showSuggestionsLoading() {
        if (!loadingEl) return;

        loadingEl.classList.remove("hidden");
        const textEl = loadingEl.querySelector(".qa-loading-text");
        if (textEl) {
            textEl.textContent = "Generating suggestions…";
        }

        suggestionsEl.innerHTML = "";
        setGenerateEnabled(false);
        setFooterEnabled(false);
    }

    function hideSuggestionsLoading() {
        if (!loadingEl) return;

        loadingEl.classList.add("hidden");

        const textEl = loadingEl.querySelector(".qa-loading-text");
        if (textEl) {
            textEl.textContent = "";
        }

        setGenerateEnabled(true);
    }

    function showChatLoading() {
        if (!loadingEl) return;
        loadingEl.classList.remove("hidden");
        loadingEl.querySelector(".qa-loading-text").textContent =
            "Loading previous chats…";
        setGenerateEnabled(false);
        setFooterEnabled(false);
    }

    function hideChatLoading() {
        if (!loadingEl) return;

        loadingEl.classList.add("hidden");

        const textEl = loadingEl.querySelector(".qa-loading-text");
        if (textEl) {
            textEl.textContent = "";
        }

        setGenerateEnabled(true);
    }

    function resetEvolveState() {
        suggestions = [];
        acceptedSuggestions = [];
        previousSuggestions = [];

        clearInlineError();
        if (suggestionsEl) {
            suggestionsEl.innerHTML = "";
        }

        const root = document.querySelector(".qa-evolve-root");
        if (root) {
            root.classList.remove("qa-evolve--has-results");
            root.classList.add("qa-evolve--prompt");
        }
        const selectAll = document.getElementById("evolve-select-all");
        if (selectAll) {
            selectAll.checked = false;
        }

        const footer = document.getElementById("evolve-footer");
        if (footer) {
            footer.classList.add("hidden");
        }

        const prevWrapper = document.getElementById("evolve-previous-suggestions");
        const prevContent = document.getElementById("evolve-previous-content");
        const prevToggle = document.getElementById("evolve-prev-toggle");

        if (prevWrapper) {
            prevWrapper.classList.add("hidden");
        }

        if (prevContent) {
            prevContent.innerHTML = "";
            prevContent.classList.add("hidden");
        }

        if (prevToggle) {
            prevToggle.classList.remove("bi-caret-up-fill");
            prevToggle.classList.add("bi-caret-down-fill");
        }

    }
    function normalizeSuggestion(raw) {
        return {
            title: normalizeTitle(raw.title ?? raw.Title ?? ""),
            description: raw.description ?? raw.Description ?? "",
            category:
                raw.category ??
                raw.Category ??
                raw.type ??
                raw.Type ??
                "Task"
        };
    }

    async function onGenerate() {

        const input = getPromptInput();
        const prompt = input.value.trim();

        clearInlineError();

        if (!prompt) {
            showInlineError("Please describe what you want to create.");
            return;
        }

        showSuggestionsLoading();
        try {
            const ctx = await getContext();

            let workItemContext = null;
            try {
                workItemContext = await buildWorkItemContext(ctx);
            } catch (e) {
                console.warn("Failed to build WorkItemContext, continuing without it", e);
            }

            const res = await IndexLibrary.PostRequest({
                baseAPIUrl: ctx.baseAPIUrl,
                endpoint: `/api/EvolveAssist/GetSuggestions`,
                azureAuthenticationHeader: ctx.accessToken,
                organizationName: ctx.organizationName,
                organizationId: ctx.organizationId,
                body: buildGeneratePayload(ctx, prompt, workItemContext)
            });

            if (!res.ok) {
                const text = await res.text();
                showInlineError(text || "Failed to generate suggestions.");
                return;
            }

            const data = await res.json();
            const wasNewChat = currentProjectId === 0;

            if (data.projectId && currentProjectId === 0) {
                currentProjectId = data.projectId;
            }


            let apiSuggestions = [];

            if (data.needsMoreContext) {
                showInlineError(data.message);
                return;
            }

            if (data.suggestions?.Suggestions && Array.isArray(data.suggestions.Suggestions)) {
                apiSuggestions = data.suggestions.Suggestions;
            } else if (Array.isArray(data.suggestions)) {
                // fallback if BE changes shape later
                apiSuggestions = data.suggestions;
            }


            if (!apiSuggestions.length) {
                showInlineError("No suggestions were generated. Please provide more detail.");
                return;
            }

            if (suggestions.length) {
                previousSuggestions.unshift(suggestions);
            }

            suggestions = apiSuggestions.map(s =>
                normalizeSuggestion(s)
            );

            renderSuggestions();
            renderPreviousSuggestions();
            document
                .getElementById("evolve-open-chat")
                .classList.remove("hidden");

            updateCreateButtonState();
            switchToResultsMode();
            await saveEvolveState(ctx);

            if (wasNewChat) {
                await refreshChatDropdown(ctx);
            }

            showSuccess("Suggestions generated successfully");
        }
        catch (err) {
            console.error(err);
            showInlineError("Unexpected error while generating suggestions.");
        } finally {
            hideSuggestionsLoading();
        }
    }

    async function saveEvolveState(ctx) {
        if (!currentProjectId || !ctx) return;

        const payload = await buildSaveStatePayload(ctx);

        try {
            await IndexLibrary.PostRequest({
                baseAPIUrl: ctx.baseAPIUrl,
                endpoint: `/api/EvolveAssist/SaveEvolveAssistState`,
                azureAuthenticationHeader: ctx.accessToken,
                organizationName: ctx.organizationName,
                organizationId: ctx.organizationId,
                body: payload
            });
        } catch (err) {
            console.warn("SaveEvolveState failed", err);
            // intentionally non-blocking
        }
    }


    async function buildSaveStatePayload(ctx) {
        return {
            ProjectId: String(currentProjectId),
            QueryContext: getPromptInput().value || "",
            LinkedItem: await buildLinkedItem(ctx),
            Suggestions: suggestions.length
                ? JSON.stringify(suggestions)
                : JSON.stringify([]),

            AcceptedSuggestion: acceptedSuggestions.length
                ? JSON.stringify(acceptedSuggestions)
                : JSON.stringify([]),

            FilterTypes: "",
            FilterStates: "",

            SuggestionsHistory: previousSuggestions.length
                ? JSON.stringify(previousSuggestions)
                : null
        };
    }


    async function buildLinkedItem(ctx) {
        if (!ctx?.workItemId) return null;

        if (!cachedWorkItem) {
            cachedWorkItem = await IndexLibrary.GetWorkItemWithRelations(ctx.workItemId);

        }

        const fields = cachedWorkItem.fields || {};

        return JSON.stringify({
            id: String(ctx.workItemId),
            title: fields["System.Title"] || "",
            type: fields["System.WorkItemType"] || ""
        });
    }

    function normalizeTitle(title) {
        if (!title) return "";
        const idx = title.indexOf(":");
        return idx > -1 ? title.substring(idx + 1).trim() : title;
    }

    function getSelectableSuggestionTypes() {
        return orgWorkItemTypes.map(w => w.name);
    }

    function getEffectiveSelectedTypes() {
        return selectedSuggestionWorkItemTypes.length
            ? selectedSuggestionWorkItemTypes
            : getSelectableSuggestionTypes();
    }

    function areAllSuggestionTypesConsidered() {
        if (!selectedSuggestionWorkItemTypes.length) return true;

        const allowedNames = getSelectableSuggestionTypes();
        if (!allowedNames.length) return true;

        return allowedNames.every(name =>
            selectedSuggestionWorkItemTypes.includes(name)
        );
    }

    function collectPreviouslyGeneratedSuggestions() {
        const flatHistory = (previousSuggestions || []).reduce(
            (acc, batch) => acc.concat(Array.isArray(batch) ? batch : []),
            []
        );

        const combined = [...suggestions, ...acceptedSuggestions, ...flatHistory];

        const seen = new Set();
        const deduped = [];
        combined.forEach(s => {
            const key = getSuggestionKey(s);
            if (seen.has(key)) return;
            seen.add(key);
            deduped.push(s);
        });
        return deduped;
    }

    function buildExclusionSuggestions() {
        const all = collectPreviouslyGeneratedSuggestions();

        if (areAllSuggestionTypesConsidered()) {
            return all;
        }

        const selectedSet = new Set(
            selectedSuggestionWorkItemTypes.map(t => normalizeKey(t))
        );
        return all.filter(s => selectedSet.has(normalizeKey(getSuggestionType(s))));
    }

    function buildGeneratePayload(ctx, prompt, workItemContext) {

        return {
            ProjectId: currentProjectId || 0,
            OrganizationId: ctx.organizationId,
            DevOpsProjectId: ctx.projectId,
            DevOpsProjectName: ctx.projectName,
            CreatedBy: ctx.userEmail,
            Suggestions: prompt,
            ConversationHistory: [],
            WorkItemContext: workItemContext || null,
            ExistingSuggestions: JSON.stringify(buildExclusionSuggestions()),
            AcceptedSuggestions: JSON.stringify(acceptedSuggestions),
            SelectedSuggestionWorkItemTypes: getEffectiveSelectedTypes()
        };
    }

    async function initExistingChats(ctx) {
        const dropdown = document.getElementById("evolve-existing-chat-dropdown");
        if (!dropdown || !ctx?.workItemId) return;

        dropdown.classList.add("hidden");
        dropdown.innerHTML = "";

        showChatLoading();

        try {
            const result = await fetchExistingChatsByWorkItem(ctx);
            if (!result || result.totalCount === 0) {
                renderNoSuggestionsState();
                return;
            }

            result.records.forEach(r => {
                const opt = document.createElement("option");
                opt.value = r.projectId;
                opt.textContent = r.title;
                dropdown.appendChild(opt);
            });

            const newChatOpt = document.createElement("option");
            newChatOpt.value = NEW_CHAT_VALUE;
            newChatOpt.textContent = "+ New chat";
            dropdown.appendChild(newChatOpt);

            currentProjectId = result.records[0].projectId;
            dropdown.value = currentProjectId;

            await loadAndRenderChat(currentProjectId, ctx);
            dropdown.classList.remove("hidden");

            bindChatDropdownChange(dropdown, ctx);

        } finally {
            hideChatLoading();
        }
    }

    function bindChatDropdownChange(dropdown, ctx) {
        if (dropdown.dataset.changeBound === "true") return;
        dropdown.dataset.changeBound = "true";

        dropdown.addEventListener("change", async () => {
            const selectedId = dropdown.value;
            if (!selectedId) return;
            if (selectedId === NEW_CHAT_VALUE) {
                currentProjectId = 0;
                startNewChat();
                return;
            }
            currentProjectId = selectedId;
            await loadAndRenderChat(selectedId, ctx);
        });
    }
    async function refreshChatDropdown(ctx) {
        const dropdown = document.getElementById("evolve-existing-chat-dropdown");
        if (!dropdown || !ctx?.workItemId) return;

        const result = await fetchExistingChatsByWorkItem(ctx);
        if (!result || result.totalCount === 0) return;

        dropdown.innerHTML = "";

        result.records.forEach(r => {
            const opt = document.createElement("option");
            opt.value = r.projectId;
            opt.textContent = r.title;
            dropdown.appendChild(opt);
        });

        const newChatOpt = document.createElement("option");
        newChatOpt.value = NEW_CHAT_VALUE;
        newChatOpt.textContent = "+ New chat";
        dropdown.appendChild(newChatOpt);

        if (currentProjectId) {
            dropdown.value = currentProjectId;
        }

        dropdown.classList.remove("hidden");
        bindChatDropdownChange(dropdown, ctx);
    }


    async function loadAndRenderChat(projectId, ctx) {
        resetEvolveState();
        showChatLoading();

        try {
            const chat = await fetchChatStateByProjectId(projectId, ctx);
            hydrateEvolveStateFromChat(chat);
            renderFromState();
            showSuccess("Chat loaded");

        } finally {
            hideChatLoading();
        }
    }

    function getSuggestionKey(suggestion) {
        return (
            `${getSuggestionTitle(suggestion)}|${getSuggestionType(suggestion)}`
                .trim()
                .toLowerCase()
        );
    }

    async function fetchExistingChatsByWorkItem(ctx) {
        try {
            const response = await IndexLibrary.GetRequest({
                baseAPIUrl: ctx.baseAPIUrl,
                endpoint: `/api/EvolveAssist/GetChatsByWorkItem?workItemId=${ctx.workItemId}`,
                azureAuthenticationHeader: ctx.accessToken,
                organizationName: ctx.organizationName,
                organizationId: ctx.organizationId,
                headers: {
                    "Content-Type": "application/json",
                    "DevOpsProjectId": String(ctx.projectId),
                    "UserEmail": ctx.userEmail
                }
            });

            if (!response.ok) {
                return null;
            }

            return await response.json();
        } catch {
            return null;
        }
    }

    async function fetchChatStateByProjectId(projectId, ctx) {
        try {
            const response = await IndexLibrary.GetRequest({
                baseAPIUrl: ctx.baseAPIUrl,
                endpoint: `/api/EvolveAssist/GetEvolveAssistState/${projectId}`,
                azureAuthenticationHeader: ctx.accessToken,
                organizationName: ctx.organizationName,
                organizationId: ctx.organizationId,
                headers: {
                    "Content-Type": "application/json"
                }
            });

            if (!response.ok) return null;
            return await response.json();
        } catch (err) {
            console.error("Error fetching chat by project ID:", err);
            return null;
        }
    }

    function hydrateEvolveStateFromChat(chat) {
        if (!chat) return;

        // Prompt
        getPromptInput().value = chat.queryContext || "";

        // Suggestions
        suggestions = chat.suggestions
            ? JSON.parse(chat.suggestions).map(normalizeSuggestion)
            : [];

        // Accepted
        acceptedSuggestions = chat.acceptedSuggestion
            ? JSON.parse(chat.acceptedSuggestion).map(normalizeSuggestion)
            : [];

        // History 
        previousSuggestions = chat.suggestionsHistory
            ? JSON.parse(chat.suggestionsHistory).map(batch =>
                batch.map(normalizeSuggestion)
            )
            : [];
    }

    function setOpenChatVisible(visible) {
        const btn = document.getElementById("evolve-open-chat");
        if (!btn) return;

        btn.classList.toggle("hidden", !visible);
    }

    function startNewChat() {
        resetEvolveState();
        currentProjectId = 0;

        const input = getPromptInput();
        if (input) {
            input.value = "";
            input.disabled = false;
            input.focus();
        }

        const dropdown = document.getElementById("evolve-existing-chat-dropdown");
        if (dropdown) {
            dropdown.value = "New Chat";
        }

        setOpenChatVisible(false);
        renderNoSuggestionsState();
        const footer = document.getElementById("evolve-footer");
        footer?.classList.remove("hidden");
        setFooterEnabled(false);

        const root = document.querySelector(".qa-evolve-root");
        root?.classList.remove("qa-evolve--has-results");
        root?.classList.add("qa-evolve--prompt");
    }

    function renderPreviousSuggestions() {
        const wrapper = document.getElementById("evolve-previous-suggestions");
        const content = document.getElementById("evolve-previous-content");

        const hasData = previousSuggestions?.some(b => b?.length);
        if (!hasData) {
            wrapper.classList.add("hidden");
            content.innerHTML = "";
            return;
        }

        wrapper.classList.remove("hidden");
        content.innerHTML = "";

        previousSuggestions.forEach(batch => {
            if (!batch || !batch.length) return;

            const batchEl = document.createElement("div");
            batchEl.className = "qa-prev-batch";

            batch.forEach(s => {
                renderSuggestionCheckboxItem(s, batchEl);
            });

            content.appendChild(batchEl);
        });
    }


    function renderSuggestionCheckboxItem(s, container) {
        const item = document.createElement("div");
        item.className = "qa-suggestion-item";

        const type = getSuggestionType(s);
        const iconUrl = getIconUrlByType(type) || "";
        const title = getSuggestionTitle(s);
        const description = getSuggestionDescription(s);

        const checked = isAcceptedSuggestion(s);

        item.innerHTML = `
                                <div class="qa-evolve-header">
                                    <label class="qa-checkbox">
                                        <input type="checkbox"
                                            class="qa-suggestion-checkbox"
                                            data-key="${escapeHtml(getSuggestionKey(s))}"
                                            ${checked ? "checked" : ""}
                                        />
                                    </label>

                                    <img
                                        src="${safeUrl(iconUrl)}"
                                        class="qa-suggestion-icon"
                                        alt="${escapeHtml(type)}"
                                    />

                                    <span class="qa-evolve-title qa-evolve-toggle">
                                        ${escapeHtml(title)}
                                    </span>

                                    <i class="bi bi-caret-down-fill qa-evolve-arrow"></i>
                                </div>

                                <div class="qa-evolve-description hidden">
                                    ${sanitizeRichText(description || "")}
                                </div>
                            `;


        const toggleEls = item.querySelectorAll(
            ".qa-evolve-toggle, .qa-evolve-arrow"
        );
        const descEl = item.querySelector(".qa-evolve-description");
        const arrowEl = item.querySelector(".qa-evolve-arrow");

        toggleEls.forEach(el => {
            el.addEventListener("click", (e) => {
                e.stopPropagation();

                const isHidden = descEl.classList.contains("hidden");
                descEl.classList.toggle("hidden");
                arrowEl.classList.toggle("bi-caret-down-fill", !isHidden);
                arrowEl.classList.toggle("bi-caret-up-fill", isHidden);

            });
        });

        const cb = item.querySelector(".qa-suggestion-checkbox");
        cb.addEventListener("change", () => {
            if (cb.checked) {
                if (!acceptedSuggestions.some(a => getSuggestionKey(a) === getSuggestionKey(s))) {
                    acceptedSuggestions.push(s);
                }
            } else {
                acceptedSuggestions = acceptedSuggestions.filter(
                    a => getSuggestionKey(a) !== getSuggestionKey(s)
                );
            }
            updateCreateButtonState();
        });

        container.appendChild(item);
    }

    function setFooterEnabled(enabled) {
        const selectAll = document.getElementById("evolve-select-all");
        const createBtn = document.getElementById("evolve-create-btn");
        const dropdownBtn = document.getElementById("evolve-create-dropdown-btn");

        if (selectAll) {
            selectAll.disabled = !enabled;
            selectAll.checked = false;
        }

        if (createBtn) {
            createBtn.disabled = !enabled;
            createBtn.style.opacity = enabled ? "1" : "0.6";
            createBtn.style.cursor = enabled ? "pointer" : "not-allowed";
        }

        if (dropdownBtn) {
            dropdownBtn.disabled = !enabled;
            dropdownBtn.style.opacity = enabled ? "1" : "0.6";
            dropdownBtn.style.cursor = enabled ? "pointer" : "not-allowed";
        }
    }


    function renderNoSuggestionsState() {
        suggestionsEl.innerHTML = `
                                <div class="qa-evolve-empty-state">
                                    <div class="qa-evolve-empty-title">
                                        No suggestions exist
                                    </div>
                                    <div class="qa-evolve-empty-text">
                                        Please add more context and click
                                        <strong>Generate Suggestions</strong> to get started.
                                    </div>
                                </div>
                            `;
        const footer = document.getElementById("evolve-footer");
        if (footer) {
            footer.classList.remove("hidden");
        }
        setFooterEnabled(false);

    }

    function renderFromState() {
        suggestionsEl.innerHTML = ""
        if (suggestions.length || acceptedSuggestions.length) {
            renderSuggestions();
            switchToResultsMode();
            document.getElementById("evolve-open-chat").classList.remove("hidden");
            setFooterEnabled(true);
        } else {
            // empty state
            const root = document.querySelector(".qa-evolve-root");
            root.classList.remove("qa-evolve--has-results");
            root.classList.add("qa-evolve--prompt");

            renderNoSuggestionsState();
        }

        updateCreateButtonState();
        renderPreviousSuggestions();

    }

    function isAcceptedSuggestion(suggestion) {
        if (!acceptedSuggestions || !acceptedSuggestions.length) return false;

        const key = getSuggestionTitle(suggestion)?.trim().toLowerCase();
        if (!key) return false;

        return acceptedSuggestions.some(a =>
            getSuggestionTitle(a)?.trim().toLowerCase() === key
        );
    }

    async function loadWorkItemTypes(ctx) {
        const res = await IndexLibrary.GetRequest({
            baseAPIUrl: ctx.baseAPIUrl,
            endpoint: `/api/AzureDevOps/GetWorkItemTypesByProject?projectId=${ctx.projectId}`,
            azureAuthenticationHeader: ctx.accessToken,
            organizationName: ctx.organizationName,
            organizationId: ctx.organizationId,
            headers: {
                "Accept": "*/*"
            }
        });

        if (!res.ok) {
            throw new Error(`Failed to load work item types: ${res.status}`);
        }

        allWorkItemTypes = await res.json();

        const evolveConfig = await loadOrgEvolveConfigurations(ctx);
        const allowedTypesCsv = evolveConfig?.evolveWorkItemTypes || "";
        const allowedTypes = allowedTypesCsv.split(",").map(t => t.trim()).filter(Boolean);


        orgWorkItemTypes = allowedTypes.length
            ? allWorkItemTypes.filter(w => allowedTypes.includes(w.name))
            : allWorkItemTypes;

        selectedSuggestionWorkItemTypes = orgWorkItemTypes.map(w => w.name);

    }

    async function loadOrgEvolveConfigurations(ctx) {
        const res = await IndexLibrary.GetRequest({
            baseAPIUrl: ctx.baseAPIUrl,
            endpoint: `/api/Settings/GetEvolveConfigurations`,
            azureAuthenticationHeader: ctx.accessToken,
            organizationName: ctx.organizationName,
            organizationId: ctx.organizationId
        });

        if (!res.ok) {
            throw new Error("Failed to load org evolve configurations");
        }

        return await res.json();
    }

    function renderTypeSelector() {

        const panel = document.getElementById("evolve-type-panel");
        panel.innerHTML = "";

        orgWorkItemTypes.forEach(w => {
            const label = document.createElement("label");
            label.className = "qa-checkbox";

            const cb = document.createElement("input");
            cb.type = "checkbox";
            cb.checked = true;

            cb.onchange = () => {
                if (cb.checked) {
                    if (!selectedSuggestionWorkItemTypes.includes(w.name)) {
                        selectedSuggestionWorkItemTypes.push(w.name);
                    }
                } else {
                    selectedSuggestionWorkItemTypes =
                        selectedSuggestionWorkItemTypes.filter(x => x !== w.name);
                }
            };

            const icon = document.createElement("img");
            icon.src = w.iconUrl || "";
            icon.alt = w.name;
            icon.style.width = "14px";
            icon.style.height = "14px";
            icon.style.marginRight = "6px";

            const text = document.createElement("span");
            text.textContent = w.name;

            label.appendChild(cb);
            label.appendChild(icon);
            label.appendChild(text);

            panel.appendChild(label);

        });
    }

    function getSuggestionType(suggestion) {
        return (
            suggestion?.type ||
            suggestion?.Type ||
            suggestion?.category ||
            suggestion?.Category ||
            ""
        );
    }

    function getSuggestionTitle(suggestion) {
        return (
            suggestion?.title ||
            suggestion?.Title ||
            ""
        );
    }

    function getSuggestionDescription(suggestion) {
        return (
            suggestion?.description ||
            suggestion?.Description ||
            ""
        );
    }

    function getIconUrlByType(typeName) {
        const match = allWorkItemTypes.find(w => w.name === typeName);
        return match ? match.iconUrl : "";
    }

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

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

    function sanitizeRichText(html) {
        return typeof DOMPurify !== "undefined"
            ? DOMPurify.sanitize(String(html ?? ""), { USE_PROFILES: { html: true } })
            : escapeHtml(html);
    }

    function switchToResultsMode() {
        const root = document.querySelector(".qa-evolve-root");

        root.classList.remove("qa-evolve--prompt");
        root.classList.add("qa-evolve--has-results");

        document.getElementById("evolve-footer").classList.remove("hidden");
        setFooterEnabled(true);
    }

    function showInlineError(message) {
        const errorEl = document.getElementById("evolve-prompt-error");
        errorEl.textContent = message;
        errorEl.classList.remove("hidden");

        getPromptInput().classList.add("qa-input-error");
    }

    function clearInlineError() {
        const errorEl = document.getElementById("evolve-prompt-error");
        errorEl.textContent = "";
        errorEl.classList.add("hidden");

        getPromptInput().classList.remove("qa-input-error");
    }

    function renderSuggestions() {
        const container = document.getElementById("evolve-suggestions-list");
        container.innerHTML = "";
        const allSuggestions = [...acceptedSuggestions, ...suggestions]
            .sort((a, b) => getSuggestionTitle(a).localeCompare(getSuggestionTitle(b)));

        allSuggestions.forEach((s, index) => {
            const item = document.createElement("div");
            item.className = "qa-suggestion-item";

            const type = getSuggestionType(s);
            const iconUrl = getIconUrlByType(type) || "";
            const title = getSuggestionTitle(s);
            const description = getSuggestionDescription(s);
            const isAccepted = isAcceptedSuggestion(s);
            item.innerHTML = `
                                <div class="qa-evolve-header">
                                    <label class="qa-checkbox">
                                        <input type="checkbox"
                                            class="qa-suggestion-checkbox"
                                            data-key="${escapeHtml(getSuggestionKey(s))}"
                                            ${isAccepted ? "checked" : ""}
                                        />
                                    </label>

                                    <img
                                        src="${safeUrl(iconUrl)}"
                                        class="qa-suggestion-icon"
                                        alt="${escapeHtml(type)}"
                                    />

                                    <span class="qa-evolve-title qa-evolve-toggle">
                                        ${escapeHtml(title)}
                                    </span>

                                    <i class="bi bi-caret-down-fill qa-evolve-arrow"></i>
                                </div>

                                <div class="qa-evolve-description hidden">
                                    ${sanitizeRichText(description || "")}
                                </div>
                            `;


            const toggleEls = item.querySelectorAll(
                ".qa-evolve-toggle, .qa-evolve-arrow"
            );
            const descEl = item.querySelector(".qa-evolve-description");
            const arrowEl = item.querySelector(".qa-evolve-arrow");

            toggleEls.forEach(el => {
                el.addEventListener("click", (e) => {
                    e.stopPropagation();

                    const isHidden = descEl.classList.contains("hidden");
                    descEl.classList.toggle("hidden");
                    arrowEl.classList.toggle("bi-caret-down-fill", !isHidden);
                    arrowEl.classList.toggle("bi-caret-up-fill", isHidden);
                });
            });

            const checkbox = item.querySelector(".qa-suggestion-checkbox");
            checkbox.addEventListener("change", async () => {
                const ctx = await getContext();

                if (checkbox.checked) {
                    if (!isAcceptedSuggestion(s)) {
                        acceptedSuggestions.push(s);
                        suggestions = suggestions.filter(x => x !== s);
                    }
                } else {
                    acceptedSuggestions = acceptedSuggestions.filter(x => x !== s);
                    suggestions.push(s);
                }

                renderSuggestions();

                await saveEvolveState(ctx);
            });
            container.appendChild(item);
        });

        updateCreateButtonState();

    }

    async function onSelectAll(e) {
        const checked = e.target.checked;
        const ctx = await getContext();

        if (checked) {
            // Move everything to accepted
            acceptedSuggestions = [
                ...acceptedSuggestions,
                ...suggestions
            ];
            suggestions = [];
        } else {
            // Move everything back to suggestions
            suggestions = [
                ...acceptedSuggestions,
                ...suggestions
            ];
            acceptedSuggestions = [];
        }

        renderSuggestions();
        updateCreateButtonState();

        await saveEvolveState(ctx);
    }

    async function persistCreatedItems(ctx, workItemIds) {
        await IndexLibrary.PatchRequest({
            baseAPIUrl: ctx.baseAPIUrl,
            endpoint: "/api/EvolveAssist/AppendWorkItems",
            azureAuthenticationHeader: ctx.accessToken,
            organizationName: ctx.organizationName,
            organizationId: ctx.organizationId,
            body: {
                ProjectId: currentProjectId,
                OrganizationId: ctx.organizationId,
                DevOpsProjectId: ctx.projectId,
                ModifiedBy: ctx.userEmail,
                NewWorkItemIds: workItemIds
            }
        });
    }

    function updateCreateButtonState() {
        const btn = document.getElementById("evolve-create-btn");
        const dropdownBtn = document.getElementById("evolve-create-dropdown-btn");

        if (isEvolveReadOnlyUser()) {
            btn.disabled = true;
            if (dropdownBtn) dropdownBtn.disabled = true;
            btn.title = "You do not have permission to create work items";
            return;
        }
        const hasSelection = acceptedSuggestions.length > 0;

        btn.disabled = !hasSelection;
        if (dropdownBtn) dropdownBtn.disabled = !hasSelection;
        btn.style.opacity = hasSelection ? "1" : "0.6";
        if (dropdownBtn) dropdownBtn.style.opacity = hasSelection ? "1" : "0.6";
    }

    async function getProcessName(processId) {
        try {
            const ctx = await getContext();
            const response = await fetch(
                `https://dev.azure.com/${ctx.organizationName}/_apis/process/processes/${processId}?api-version=7.1-preview.1`,
                {
                    headers: {
                        'Authorization': `Bearer ${ctx.accessToken}`,
                        'Content-Type': 'application/json'
                    }
                }
            );
            if (response.ok) {
                const data = await response.json();
                return data.name || 'Process';
            }
        } catch (e) {
        }
        return 'Process';
    }

    async function saveCustomDefaultsForChat(userProvidedByWit, requiredFieldsByWit, chatId, effectiveDefaultsByWit = {}) {
        if (!userProvidedByWit || Object.keys(userProvidedByWit).length === 0) {
            return;
        }

        if (!chatId || chatId <= 0) {
            return;
        }

        const ctx = await getContext();
        const currentProjectId = ctx.projectId;

        const processId = await resolveProcessIdFromProject(currentProjectId, ctx);
        if (!processId) {
            throw new Error('Could not resolve process ID for project');
        }

        const processName = await getProcessName(processId);

        const saveCalls = [];

        Object.keys(userProvidedByWit || {}).forEach((witName) => {
            const fieldValues = userProvidedByWit[witName] || {};
            const requiredFields = getByNormalizedKey(requiredFieldsByWit, witName) || [];
            const existingDefaults = getByNormalizedKey(effectiveDefaultsByWit, witName) || {};

            Object.keys(fieldValues).forEach((fieldRef) => {
                const newValue = fieldValues[fieldRef];
                const existingValue = getByNormalizedKey(existingDefaults, fieldRef);

                if (existingValue === newValue) {
                    return;
                }

                const fieldMeta = requiredFields.find((field) => normalizeKey(field.referenceName) === normalizeKey(fieldRef)) || {};
                const payload = {
                    OrganizationId: ctx.organizationId,
                    DevOpsProcessId: processId,
                    DevOpsProcessName: processName,
                    WorkItemTypeName: witName,
                    FieldReferenceName: fieldRef,
                    FieldName: fieldMeta.name || fieldRef,
                    FieldType: fieldMeta.type || 'string',
                    DefaultValue: newValue,
                    CreatedBy: ctx.userEmail
                };

                if (chatId && chatId > 0) {
                    payload.ChatId = chatId;
                }

                const apiCall = IndexLibrary.PostRequest({
                    baseAPIUrl: ctx.baseAPIUrl,
                    endpoint: `/api/Settings/UpsertWorkItemDefaultField`,
                    azureAuthenticationHeader: ctx.accessToken,
                    organizationName: ctx.organizationName,
                    organizationId: ctx.organizationId,
                    body: payload
                }).then(async (response) => {
                    if (!response.ok) {
                        throw new Error(`API call failed with status ${response.status}`);
                    }
                    return response;
                });

                saveCalls.push(apiCall);
            });
        });

        if (saveCalls.length === 0) {
            return;
        }

        const responses = await Promise.all(saveCalls);
        const failedCount = responses.filter((response) => !response.ok).length;
        if (failedCount > 0) {
            throw new Error(`Failed to save ${failedCount} custom field value(s).`);
        }
    }

    async function onCreateWithCustomSettings() {
        const ctx = await getContext();
        const btn = document.getElementById("evolve-create-btn");

        // Single source of truth
        const selected = [...acceptedSuggestions];

        if (!selected.length) {
            showWarning("Select at least one suggestion");
            return;
        }

        btn.disabled = true;

        try {
            const witNames = [...new Set(selected.map(s => s.category || 'Task'))];

            console.log('Creating with custom settings for WIT types:', witNames);

            const [projectDefaultsByWit, chatDefaultsByWit, requiredFieldsByWit] = await Promise.all([
                fetchDefaultFieldsByWorkItemType(ctx.projectId, ctx),
                currentProjectId > 0 ? fetchDefaultFieldsByChatId(currentProjectId, ctx) : Promise.resolve({}),
                getAllRequiredFieldsByWit(witNames, ctx)
            ]);

            const mergedDefaultsByWit = mergeDefaultsByWit(projectDefaultsByWit, chatDefaultsByWit);

            const allRequiredFieldsByWit = {};
            Object.keys(requiredFieldsByWit || {}).forEach((witName) => {
                const requiredFields = requiredFieldsByWit[witName] || [];
                const filteredFields = requiredFields.filter((field) => {
                    if (!field || !field.referenceName) return false;
                    return !EA_NON_FORM_FIELDS.has(field.referenceName);
                });

                if (filteredFields.length > 0) {
                    allRequiredFieldsByWit[witName] = filteredFields;
                }
            });

            console.log('Showing popup for all required fields (custom settings)');

            const witGroups = {};
            Object.keys(allRequiredFieldsByWit).forEach(witName => {
                witGroups[witName] = {
                    fields: allRequiredFieldsByWit[witName],
                    defaultsMap: getByNormalizedKey(mergedDefaultsByWit, witName) || {}
                };
            });

            const popupResult = await showRequiredFieldsPopupForMultipleWITs(witGroups, allWorkItemTypes, true);

            if (!popupResult) {
                btn.disabled = false;
                btn.textContent = "Create Work Items";
                return;
            }

            try {
                await saveCustomDefaultsForChat(popupResult, requiredFieldsByWit, currentProjectId, mergedDefaultsByWit);
                console.log('Custom defaults saved successfully');
            } catch (saveErr) {
                console.error('Failed to save custom defaults:', saveErr);
            }

            Object.keys(popupResult).forEach(witName => {
                if (!mergedDefaultsByWit[witName]) {
                    mergedDefaultsByWit[witName] = {};
                }
                Object.assign(mergedDefaultsByWit[witName], popupResult[witName]);
            });

            const failedItems = [];
            const createdIds = [];
            const successfulSuggestions = [];
            const total = selected.length;

            for (let i = 0; i < total; i++) {
                btn.textContent = `Creating ${i + 1}/${total}...`;

                const s = selected[i];
                const suggestion = {
                    title: s.title,
                    description: s.description,
                    category: s.category
                };

                try {
                    const id = await createWorkItemWithRequiredFields(ctx, suggestion, mergedDefaultsByWit);
                    if (id != null && id !== undefined) {
                        createdIds.push(id);
                        successfulSuggestions.push(s);
                    } else {
                        throw new Error('Work item created but no valid ID returned');
                    }
                } catch (err) {
                    console.error(`Failed to create work item "${suggestion.title}":`, err);
                    failedItems.push({
                        title: suggestion.title,
                        witType: suggestion.category || 'Task',
                        rawError: err.message || String(err)
                    });
                }
            }

            // Persist created work items
            if (createdIds.length > 0) {
                await persistCreatedItems(ctx, createdIds);
                await refreshChatDropdown(ctx);
            }

            // Only remove successfully created items from the list
            if (successfulSuggestions.length > 0) {
                const successfulKeys = new Set(
                    successfulSuggestions.map(s => getSuggestionKey(s))
                );

                acceptedSuggestions = acceptedSuggestions.filter(
                    s => !successfulKeys.has(getSuggestionKey(s))
                );

                suggestions = suggestions.filter(
                    s => !successfulKeys.has(getSuggestionKey(s))
                );

                renderSuggestions();
                await saveEvolveState(ctx);
            }

            document.getElementById("evolve-select-all").checked = false;

            // Handle results
            if (failedItems.length === 0) {
                showSuccess(`Created ${createdIds.length} work items successfully`);
            } else if (createdIds.length === 0) {
                showError("Failed to create work items. Please check field requirements.");
            } else {
                showWarning(`Created ${createdIds.length} of ${total} work items. ${failedItems.length} failed.`);
            }
        } catch (err) {
            console.error('Error in onCreateWithCustomSettings:', err);
            showError("Failed to create one or more work items.");
        } finally {
            btn.disabled = false;
            btn.textContent = "Create Work Items";
            updateCreateButtonState();
        }
    }

    async function onCreate() {
        const ctx = await getContext();
        const btn = document.getElementById("evolve-create-btn");

        // Single source of truth
        const selected = [...acceptedSuggestions];

        if (!selected.length) {
            showWarning("Select at least one suggestion");
            return;
        }

        btn.disabled = true;

        try {
            const witNames = [...new Set(selected.map(s => s.category || 'Task'))];

            console.log('Checking default values for WIT types:', witNames);

            const [projectDefaultsByWit, chatDefaultsByWit, requiredFieldsByWit] = await Promise.all([
                fetchDefaultFieldsByWorkItemType(ctx.projectId, ctx),
                currentProjectId > 0 ? fetchDefaultFieldsByChatId(currentProjectId, ctx) : Promise.resolve({}),
                getAllRequiredFieldsByWit(witNames, ctx)
            ]);

            const mergedDefaultsByWit = mergeDefaultsByWit(projectDefaultsByWit, chatDefaultsByWit);

            const missingFieldsByWit = {};
            Object.keys(requiredFieldsByWit || {}).forEach((witName) => {
                const requiredFields = requiredFieldsByWit[witName] || [];
                const defaults = getByNormalizedKey(mergedDefaultsByWit, witName) || {};
                const missingFields = requiredFields.filter((field) => {
                    if (!field || !field.referenceName) return false;
                    if (EA_NON_FORM_FIELDS.has(field.referenceName)) return false;
                    const value = getByNormalizedKey(defaults, field.referenceName);
                    return value === undefined || value === null || String(value).trim() === '';
                });
                if (missingFields.length > 0) {
                    missingFieldsByWit[witName] = missingFields;
                }
            });

            if (Object.keys(missingFieldsByWit).length > 0) {

                const witGroups = {};
                Object.keys(missingFieldsByWit).forEach(witName => {
                    witGroups[witName] = {
                        fields: missingFieldsByWit[witName],
                        defaultsMap: {}
                    };
                });

                const popupResult = await showRequiredFieldsPopupForMultipleWITs(witGroups, allWorkItemTypes, true);

                if (!popupResult) {
                    btn.disabled = false;
                    btn.textContent = "Create Work Items";
                    return;
                }

                Object.keys(popupResult).forEach(witName => {
                    if (!mergedDefaultsByWit[witName]) {
                        mergedDefaultsByWit[witName] = {};
                    }
                    Object.assign(mergedDefaultsByWit[witName], popupResult[witName]);
                });
            } else {
                console.log('No missing fields, proceeding with creation');
            }

            const failedItems = [];
            const createdIds = [];
            const successfulSuggestions = [];
            const total = selected.length;

            for (let i = 0; i < total; i++) {
                btn.textContent = `Creating ${i + 1}/${total}...`;

                const s = selected[i];
                const suggestion = {
                    title: s.title,
                    description: s.description,
                    category: s.category
                };

                try {
                    const id = await createWorkItemWithRequiredFields(ctx, suggestion, mergedDefaultsByWit);
                    if (id != null && id !== undefined) {
                        createdIds.push(id);
                        successfulSuggestions.push(s);
                    } else {
                        throw new Error('Work item created but no valid ID returned');
                    }
                } catch (err) {
                    console.error(`Failed to create work item "${suggestion.title}":`, err);
                    failedItems.push({
                        title: suggestion.title,
                        witType: suggestion.category || 'Task',
                        rawError: err.message || String(err)
                    });
                }
            }

            if (createdIds.length > 0) {
                await persistCreatedItems(ctx, createdIds);
                await refreshChatDropdown(ctx);
            }

            if (successfulSuggestions.length > 0) {
                const successfulKeys = new Set(
                    successfulSuggestions.map(s => getSuggestionKey(s))
                );

                acceptedSuggestions = acceptedSuggestions.filter(
                    s => !successfulKeys.has(getSuggestionKey(s))
                );

                suggestions = suggestions.filter(
                    s => !successfulKeys.has(getSuggestionKey(s))
                );

                renderSuggestions();
                await saveEvolveState(ctx);
            }

            document.getElementById("evolve-select-all").checked = false;

            if (failedItems.length === 0) {
                showSuccess(`Created ${createdIds.length} work items successfully`);
            } else if (createdIds.length === 0) {
                showError("Failed to create work items. Please check field requirements.");
            } else {
                showWarning(`Created ${createdIds.length} of ${total} work items. ${failedItems.length} failed.`);
            }
        } catch (err) {
            console.error('Error in onCreate:', err);
            showError("Failed to create one or more work items.");
        } finally {
            btn.disabled = false;
            btn.textContent = "Create Work Items";
            updateCreateButtonState();
        }
    }


    ScreenManager.register("evolve", {
        init,
        dispose
    });

})();
