let _rfFieldClassification = null;
async function rfFetchFieldClassification(orgName, authHeader) {
    if (_rfFieldClassification) return _rfFieldClassification;
    _rfFieldClassification = {};
    try {
        const res = await fetch(`https://dev.azure.com/${orgName}/_apis/wit/fields?api-version=7.0`,
            { headers: { Authorization: `Bearer ${authHeader}` } });
        if (res.ok) ((await res.json()).value || []).forEach(f => { _rfFieldClassification[f.referenceName] = f; });
    } catch (e) { }
    return _rfFieldClassification;
}

function rfResolveFieldType(meta) {
    if (!meta) return 'string';
    if (meta.isIdentity) return 'identity';
    let t = String(meta.type || 'string');
    if (t.indexOf('picklist') === 0) {
        const b = t.slice(8).toLowerCase();
        return (b === 'integer' || b === 'double') ? b : 'string';
    }
    return t;
}

let _rfIdentityPeople = null;
async function rfFetchIdentityPeople(orgName, authHeader) {
    if (_rfIdentityPeople) return _rfIdentityPeople;
    try {
        const allUsers = await IndexLibrary.getAllUsers();
        const lookup = IndexLibrary.buildUserLookup(allUsers);
        _rfIdentityPeople = Object.values(lookup)
            .filter(u => u && u.name && u.email)
            .map(u => ({ displayName: u.name, mail: u.email }))
            .sort((a, b) => a.displayName.localeCompare(b.displayName));
    } catch (e) {
        _rfIdentityPeople = [];
    }
    return _rfIdentityPeople;
}

function rfWireIdentityInputs(root) {
    const esc = s => String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
    (root || document).querySelectorAll('input[data-identity="true"]').forEach(input => {
        if (input.dataset.identityWired === 'true') return;
        input.dataset.identityWired = 'true';

        const menu = document.createElement('div');
        menu.style.cssText = 'position:absolute;z-index:100000;background:var(--da-surface-raised, #fff);color:var(--da-text, #000);border:1px solid #ccc;border-radius:4px;box-shadow:0 2px 8px rgba(0,0,0,.15);max-height:240px;overflow-y:auto;display:none;';
        document.body.appendChild(menu);

        const hide = () => { menu.style.display = 'none'; };
        const position = () => {
            const r = input.getBoundingClientRect();
            menu.style.left = (r.left + window.scrollX) + 'px';
            menu.style.top = (r.bottom + window.scrollY) + 'px';
            menu.style.width = r.width + 'px';
        };
        const renderList = () => {
            const q = input.value.trim().toLowerCase();
            const people = _rfIdentityPeople || [];
            const items = (q ? people.filter(u => (u.displayName + ' ' + u.mail).toLowerCase().includes(q)) : people).slice(0, 50);
            if (!items.length) { hide(); return; }
            menu.innerHTML = items.map(u => {
                const tooltipText = u.displayName.toLowerCase() !== u.mail.toLowerCase() ? `${u.displayName}\n${u.mail}` : u.displayName;
                const avatarLink = IndexLibrary.getCachedAvatar(u.mail);
                const avatarHtml = avatarLink
                    ? `<img src="${esc(avatarLink)}" style="width:28px;height:28px;border-radius:50%;flex-shrink:0;" />`
                    : `<span style="width:28px;height:28px;border-radius:50%;background:#0078d4;color:#fff;font-size:11px;font-weight:600;display:flex;align-items:center;justify-content:center;flex-shrink:0;">${esc(IndexLibrary.getInitials(u.displayName))}</span>`;
                return `<div class="rf-id-item" data-val="${esc(u.displayName)}" title="${esc(tooltipText)}" style="display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer;">
                    ${avatarHtml}
                    <span style="display:flex;flex-direction:column;min-width:0;">
                        <span style="font-size:13px;color:#212121;">${esc(u.displayName)}</span>
                        <span style="font-size:11px;color:#888;">${esc(u.mail)}</span>
                    </span>
                </div>`;
            }).join('');
            position();
            menu.style.display = 'block';

            IndexLibrary.loadAvatarsFor(items.map(u => u.mail))
                .then(loaded => { if (loaded && menu.style.display !== 'none') renderList(); });
        };

        input.addEventListener('focus', renderList);
        input.addEventListener('input', renderList);
        menu.addEventListener('mousedown', e => {
            const item = e.target.closest('.rf-id-item');
            if (!item) return;
            e.preventDefault();
            input.value = item.getAttribute('data-val');
            input.setAttribute('data-touched', 'true');
            input.dispatchEvent(new Event('change', { bubbles: true }));
            hide();
        });
        document.addEventListener('mousedown', e => {
            if (e.target === input || menu.contains(e.target)) return;
            hide();
        });
        window.addEventListener('scroll', e => {
            if (menu.style.display === 'none' || menu.contains(e.target)) return;
            position();
        }, true);
    });
}

/**
 * @param {object} field - Field definition with type, allowedValues, etc.
 * @param {number} idx - Field index
 * @param {string} defaultValue - Default value to pre-populate
 * @param {string} witName - (Optional) Work item type name for data attribute
 * @returns {string} - HTML string for the input
 */
function buildFieldInput(field, idx, defaultValue = '', witName = '') {
    const id = `popup-field-${idx}`;
    const ref = field.referenceName.replace(/"/g, '&quot;');
    const wit = witName ? `data-wit="${witName.replace(/"/g, '&quot;')}"` : '';
    const disabled = field.readOnly ? 'disabled' : '';
    const val = String(defaultValue || '').replace(/"/g, '&quot;');
    const baseClass = 'form-control';

    let inputHtml = '';

    // Dropdown for fields with allowed values
    if (field.allowedValues && field.allowedValues.length > 0) {
        const opts = ['', ...field.allowedValues].map(v => {
            const selected = v === defaultValue ? 'selected' : '';
            const optVal = String(v).replace(/"/g, '&quot;');
            const optText = v ? String(v).replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;') : '-- Select --';
            return `<option value="${optVal}" ${selected}>${optText}</option>`;
        }).join('');
        inputHtml = `<select class="${baseClass}" id="${id}" ${wit} data-ref="${ref}" data-touched="false" ${disabled}>${opts}</select>`;
    } else {
        // Type-specific input rendering
        switch (field.type) {
            case 'boolean':
                const trueSelected = val === 'true' || val === 'True' ? 'selected' : '';
                const falseSelected = val === 'false' || val === 'False' ? 'selected' : '';
                inputHtml = `<select class="${baseClass}" id="${id}" ${wit} data-ref="${ref}" data-touched="false" ${disabled}>
                    <option value="">-- Select --</option>
                    <option value="true" ${trueSelected}>True</option>
                    <option value="false" ${falseSelected}>False</option>
                </select>`;
                break;
            case 'integer':
            case 'double':
                inputHtml = `<input type="number" class="${baseClass}" id="${id}" ${wit} data-ref="${ref}" data-touched="false" value="${val}" ${disabled}>`;
                break;
            case 'dateTime':
            case 'date':
                inputHtml = `<input type="date" class="${baseClass}" id="${id}" ${wit} data-ref="${ref}" data-touched="false" value="${val}" ${disabled}>`;
                break;
            case 'html':
                const escVal = String(defaultValue || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                inputHtml = `<textarea class="${baseClass}" id="${id}" ${wit} data-ref="${ref}" data-touched="false" rows="2" ${disabled}>${escVal}</textarea>`;
                break;
            case 'identity':
                inputHtml = `<input type="text" data-identity="true" autocomplete="off" class="${baseClass}" id="${id}" ${wit} data-ref="${ref}" data-touched="false" value="${val}" placeholder="Search user..." ${disabled}>`;
                break;
            default:
                inputHtml = `<input type="text" class="${baseClass}" id="${id}" ${wit} data-ref="${ref}" data-touched="false" value="${val}" ${disabled}>`;
        }
    }

    return `<div class="field-input-wrapper">${inputHtml}<small id="${id}-err" class="field-error" style="display: none; color: #dc3545; font-size: 12px; margin-top: 2px;">Value is required</small></div>`;
}

function getPopupStyles() {
    return `
        .swal2-popup .swal2-actions {
            justify-content: center;
            gap: 8px;
            flex-direction: row;
        }
        .swal2-popup .swal2-cancel {
            order: 1;
            padding: 0.75rem 1.5rem;
        }
        .swal2-popup .swal2-confirm {
            order: 2;
            padding: 0.75rem 1.5rem;
        }
        .swal2-popup .swal2-confirm:disabled {
            cursor: not-allowed;
            opacity: 0.6;
        }
        .swal2-popup .swal2-cancel:disabled {
            cursor: not-allowed;
            opacity: 0.6;
        }
        .swal2-popup .form-control {
            width: 100%;
            box-sizing: border-box;
            border-radius: 0;
        }
        .swal2-popup .field-column {
            width: 35%;
        }
        .swal2-popup .value-column {
            width: 65%;
        }
        .swal2-popup .field-input-wrapper {
            display: flex;
            flex-direction: column;
        }
        .swal2-popup .form-control.is-invalid {
            border-color: #dc3545;
        }
    `;
}

/**
 * Creates validation handler for popup fields
 */
function createFieldValidator(createBtn) {
    return () => {
        const allInputs = document.querySelectorAll('.form-control');
        let allFilled = true;

        allInputs.forEach(input => {
            const value = input.value?.trim() || '';
            const touched = input.getAttribute('data-touched') === 'true';
            const wrapper = input.closest('.field-input-wrapper');
            const errorMsg = wrapper?.querySelector('.field-error');

            if (value === '') {
                allFilled = false;
                if (touched && errorMsg) {
                    errorMsg.style.display = 'block';
                    input.classList.add('is-invalid');
                } else if (!touched && errorMsg) {
                    errorMsg.style.display = 'none';
                    input.classList.remove('is-invalid');
                }
            } else {
                if (errorMsg) {
                    errorMsg.style.display = 'none';
                    input.classList.remove('is-invalid');
                }
            }
        });

        if (createBtn) {
            createBtn.disabled = !allFilled;
        }
    };
}

/**
 * Displays the required fields popup UI and captures user input
 * @param {object} witGroups - Pre-processed groups: { witName: { fields: [], defaultsMap: {} } }
 * @param {Array} workItemTypes - List of all work item types with icons
 * @param {boolean} isCompact - Whether to show compact UI
 * @returns {Promise<object>} - Returns { witName: { fieldRef: value, ... }, ... } or null if cancelled
 */
function showRequiredFieldsPopupForMultipleWITs(witGroups, workItemTypes, isCompact = false) {
    return new Promise((resolve) => {
        if (!witGroups || Object.keys(witGroups).length === 0) {
            resolve({});
            return;
        }

        let globalFieldIndex = 0;
        const witCount = Object.keys(witGroups).length;

        // Build UI HTML for all WIT groups
        let tablesHTML = '';
        const tableStyle = 'width: 100%; border-collapse: collapse; border: 1px solid #ddd; table-layout: fixed;';
        const cellStyle = 'text-align: left; padding: 8px; border-bottom: 1px solid #ddd;';
        const headerStyle = 'background-color: #f5f5f5;';

        for (const witName in witGroups) {
            const { fields, defaultsMap } = witGroups[witName];
            let rowsHTML = '';

            fields.forEach(field => {
                const defaultValue = defaultsMap && defaultsMap[field.referenceName]
                    ? defaultsMap[field.referenceName]
                    : (field.defaultValue || '');

                const fieldNameEscaped = String(field.name || '').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
                const inputHtml = buildFieldInput(field, globalFieldIndex++, defaultValue, witName);

                rowsHTML += `
            <tr>
                <td class="field-column" style="${cellStyle} width: 35%;">
                    ${fieldNameEscaped}
                </td>
                <td class="value-column" style="${cellStyle} width: 65%;">
                    ${inputHtml}
                </td>
            </tr>`;
            });

            const marginBottom = witCount > 1 ? '20px' : '0';
            const witNameEscaped = String(witName).replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
            const iconUrl = getWorkItemTypeIcon(witName, workItemTypes);

            tablesHTML += `
            <div style="margin-bottom: ${marginBottom};">
                <div style="text-align: left; margin-bottom: 10px; font-size: 14px; display: flex; align-items: center; gap: 8px;">
                    <img src="${iconUrl}" alt="${witNameEscaped} icon" style="width: 20px; height: 20px; flex-shrink: 0;" />
                    ${witNameEscaped}
                </div>
                <table style="${tableStyle}">
                    <thead style="${headerStyle}">
                        <tr>
                            <th class="field-column" style="${cellStyle} width: 35%;">Field</th>
                            <th class="value-column" style="${cellStyle} width: 65%;">Value</th>
                        </tr>
                    </thead>
                    <tbody>${rowsHTML}</tbody>
                </table>
            </div>
        `;
        }

        const totalFields = Object.values(witGroups).reduce((sum, g) => sum + (g.fields ? g.fields.length : 0), 0);
        const subtitleText = isCompact
            ? 'Fill the values to create work items.'
            : (totalFields > 1
                ? 'Please fill the required values for creating work items.'
                : 'Please fill the required value for creating work item.');

        Swal.fire({
            title: isCompact ? 'Complete Required Fields' : 'Complete Required Fields to Create Work Items',
            html: `
            <style>${getPopupStyles()}</style>
            <div style="text-align: left; margin-bottom: ${isCompact ? '12px' : '20px'};">
                ${subtitleText}
            </div>
            ${tablesHTML}
        `,
            width: isCompact ? '420px' : '650px',
            showCancelButton: true,
            confirmButtonText: isCompact ? 'Create' : 'Create Work Item',
            cancelButtonText: 'Cancel',
            allowOutsideClick: false,
            didOpen: () => {
                const confirmButton = Swal.getConfirmButton();
                const validateFields = createFieldValidator(confirmButton);
                const formControls = document.querySelectorAll('.form-control');

                rfWireIdentityInputs(Swal.getHtmlContainer());

                // Initial validation
                validateFields();

                // Add event listeners for field validation
                formControls.forEach(input => {
                    input.addEventListener('input', () => {
                        if (input.value.trim() !== '') {
                            input.setAttribute('data-touched', 'true');
                        }
                        validateFields();
                    });
                    input.addEventListener('change', () => {
                        if (input.value.trim() !== '') {
                            input.setAttribute('data-touched', 'true');
                        }
                        validateFields();
                    });
                });
            }
        }).then((result) => {
            if (!result.isConfirmed) {
                resolve(null);
                return;
            }

            // Capture user-provided values from popup
            const capturedValues = {};
            const formControls = document.querySelectorAll('.form-control');

            formControls.forEach((input) => {
                const witName = input.getAttribute('data-wit');
                const fieldRef = input.getAttribute('data-ref');
                const value = input.value?.trim();

                if (!witName || !fieldRef || !value) {
                    return;
                }

                if (!capturedValues[witName]) {
                    capturedValues[witName] = {};
                }

                capturedValues[witName][fieldRef] = value;
            });

            resolve(capturedValues);
        }).catch((err) => {
            console.error('Error in required fields popup:', err);
            resolve(null);
        });
    });
}

/**
 * Wrapper for single WIT
 */
function showRequiredFieldsPopup(witGroups, workItemTypes, isCompact = false) {
    return showRequiredFieldsPopupForMultipleWITs(witGroups, workItemTypes, isCompact);
}

/**
 * Get work item type icon URL
 */
function getWorkItemTypeIcon(witName, workItemTypes) {
    if (!workItemTypes || !Array.isArray(workItemTypes)) {
        return '';
    }
    const wit = workItemTypes.find(w => w.name === witName);
    return wit?.iconUrl || '';
}

// Export for use in other modules
if (typeof module !== 'undefined' && module.exports) {
    module.exports = {
        showRequiredFieldsPopup,
        showRequiredFieldsPopupForMultipleWITs
    };
}
