/**
 * A reusable function that initializes a Choices.js select with
 * typical "fetch single item" + "fetch search results" logic.
 *
 * @param {Object} config
 * @param {string} config.elementId - The DOM id of the <select>
 * @param {(id: string|number) => string} config.fetchShowUrl - Builds URL for the single-item fetch
 * @param {(term: string) => string} config.fetchSearchUrl - Builds URL for the search fetch
 * @param {string|number|null} config.oldValue - The old(...) value from Blade (if any)
 * @param {string|number|null} config.existingValue - The existing DB value (if any)
 * @param {boolean} config.isReadOnly - Whether to disable this Choices instance
 * @param {string} [config.placeholder='Search...']
 * @param {string} [config.searchPlaceholder='Type to search...']
 * @param {string} [config.errorClass='border-red-500'] - A Tailwind class for error highlighting
 * @param {string} [config.alignmentClass='choices--align-left'] - For left/right alignment
 * @param {boolean} [config.shouldShowPopover=false] - Whether to enable hover popover
 * @param {string|null} [config.popoverId=null] - The DOM id of the popover element (if using popover)
 * @param {string} [config.labelKey='label'] - The property name for the main label (from JSON response)
 * @param {string|null} [config.customLabelKey=null] - If you want search results to display a different field
 */
function initDynamicSelect(config) {
    const {
        elementId,
        fetchShowUrl,
        fetchSearchUrl,
        oldValue = null,
        existingValue = null,
        isReadOnly = false,
        placeholder = 'Search...',
        searchPlaceholder = 'Type to search...',
        errorClass = 'border-red-500',
        alignmentClass = 'choices--align-left',
        shouldShowPopover = false,
        popoverId = null,
        labelKey = 'label',
        customLabelKey = null,
    } = config;

    const selectEl = document.getElementById(elementId);
    if (!selectEl) return; // If this element doesn't exist on the page, skip

    // Check if the element has a Tailwind error class
    const hasError = selectEl.classList.contains(errorClass);

    // Initialize Choices
    const choices = new Choices(selectEl, {
        allowHTML: true,
        placeholderValue: placeholder,
        searchPlaceholderValue: searchPlaceholder,
        searchResultLimit: 20,
        shouldSort: false,
        classNames: {
            containerOuter: `choices ${alignmentClass}`,
            containerInner: `choices__inner flex items-center ${hasError ? errorClass : ''}`,
        },
    });

    // Determine which value (old or existing) to preselect
    const selectedId = oldValue || existingValue;
    if (selectedId) {
        fetch(fetchShowUrl(selectedId))
            .then(response => response.json())
            .then(item => {
                choices.clearChoices();
                choices.setChoices(
                    [
                        {
                            value: item.value,
                            label: item[labelKey], // e.g. item['label']
                            customProperties: {
                                // fallback if item.dropdown_label is missing
                                dropdown_label: item.dropdown_label || item[labelKey],
                            },
                            selected: true,
                        },
                    ],
                    'value',
                    'label',
                    false
                );
            })
            .catch(err => console.error('Error fetching single item:', err));
    }

    // Add "search" event listener => dynamic fetching
    selectEl.addEventListener('search', (event) => {
        const searchTerm = event.detail.value || '';
        // Optionally skip if searchTerm.length < 2

        fetch(fetchSearchUrl(searchTerm))
            .then(response => response.json())
            .then(data => {
                const mapped = data.map(d => ({
                    value: d.value,
                    // If you want the dropdown to show the "full" text, you can override label with d.dropdown_label
                    label: customLabelKey ? d[customLabelKey] : d[labelKey],
                    customProperties: {
                        dropdown_label: d.dropdown_label || d[labelKey],
                    },
                }));
                choices.clearChoices();
                choices.setChoices(mapped, 'value', 'label', true);
            })
            .catch(err => console.error('Error searching items:', err));
    });

    // Optional popover on hover
    if (shouldShowPopover && popoverId) {
        // By default, the single select's displayed item is in .choices__list--single
        // but the easiest is to query a known parent wrapper or the generated Choices container
        // We'll try the nearest .choices container next to this select.
        const parentDiv = selectEl.closest('.choices')?.querySelector('.choices__list--single');
        const popoverEl = document.getElementById(popoverId);

        if (parentDiv && popoverEl) {
            parentDiv.addEventListener('mouseenter', () => {
                const selected = choices.getValue();
                if (selected && selected.customProperties?.dropdown_label) {
                    popoverEl.textContent = selected.customProperties.dropdown_label;
                    popoverEl.style.display = 'block';
                }
            });
            parentDiv.addEventListener('mouseleave', () => {
                popoverEl.style.display = 'none';
            });
        }
    }

    // If read-only => disable
    if (isReadOnly) {
        choices.disable();
    }
}

/**
 * initAllDropdowns
 *
 * Call initDynamicSelect() for each dropdown you had in your Blade code.
 * (You can rename or reorganize as desired.)
 */
function initAllDropdowns() {
    // Grab whether we’re read-only from a global Blade variable or inline script:
    // (Adjust how you pass $readonly as needed in your layout.)
    const isReadOnly = window.__IS_READONLY__ === true;

    // 1) place_of_birth_city_id
    initDynamicSelect({
        elementId: 'place_of_birth_city_id',
        fetchShowUrl: (id) => `/api/cities/${id}`,
        fetchSearchUrl: (term) => `/api/cities?search=${encodeURIComponent(term)}`,
        oldValue: window.__OLD_place_of_birth_city_id, // or inline the Blade: "{{ old('place_of_birth_city_id') }}"
        existingValue: window.__EXISTING_place_of_birth_city_id, 
        isReadOnly,
        placeholder: 'Type to search for a city...',
        searchPlaceholder: 'Pretraži gradove...',
        errorClass: 'border-red-500',
        alignmentClass: 'choices--align-left',
        shouldShowPopover: false,
        popoverId: null,
    });

    // 2) place_of_birth_country_id
    initDynamicSelect({
        elementId: 'place_of_birth_country_id',
        fetchShowUrl: (id) => `/api/passport-city-show/${id}`,
        fetchSearchUrl: (term) => `/api/passport-city-search?search=${encodeURIComponent(term)}`,
        oldValue: window.__OLD_place_of_birth_country_id,
        existingValue: window.__EXISTING_place_of_birth_country_id,
        isReadOnly,
        placeholder: 'Type to search...',
        searchPlaceholder: 'Type to search...',
        errorClass: 'border-red-500',
        alignmentClass: 'choices--align-left',
        // If you have a popover, set these:
        shouldShowPopover: true,
        popoverId: 'fullCityPopover', // make sure it matches your Blade's <div id="fullCityPopover">
    });

    // 3) country_code_country_id
    initDynamicSelect({
        elementId: 'country_code_country_id',
        fetchShowUrl: (id) => `/api/countrycode-show/${id}`,
        fetchSearchUrl: (term) => `/api/countrycode-search?search=${encodeURIComponent(term)}`,
        oldValue: window.__OLD_country_code_country_id,
        existingValue: window.__EXISTING_country_code_country_id,
        isReadOnly,
        placeholder: 'Search country...',
        searchPlaceholder: 'Search country...',
        errorClass: 'border-red-500',
        // If you want a popover on hover:
        shouldShowPopover: true,
        popoverId: 'fullCountryCodePopover', // make sure it matches your Blade's <div id="fullCountryCodePopover">
    });

    // 4) nationality_country_id
    initDynamicSelect({
        elementId: 'nationality_country_id',
        fetchShowUrl: (id) => `/api/nationality-show/${id}`,
        fetchSearchUrl: (term) => `/api/nationality-search?search=${encodeURIComponent(term)}`,
        oldValue: window.__OLD_nationality_country_id,
        existingValue: window.__EXISTING_nationality_country_id,
        isReadOnly,
        placeholder: 'Search nationality...',
        searchPlaceholder: 'Search nationality...',
        errorClass: 'border-red-500',
        alignmentClass: 'choices--align-right', // if you want it aligned right
        shouldShowPopover: true,
        popoverId: 'fullNationalityPopover',
    });

    // 5) residence_city_id_create
    initDynamicSelect({
        elementId: 'residence_city_id_create',
        fetchShowUrl: (id) => `/api/cities/${id}`,
        fetchSearchUrl: (term) => `/api/cities?search=${encodeURIComponent(term)}`,
        oldValue: window.__OLD_residence_city_id, 
        existingValue: window.__EXISTING_residence_city_id,
        isReadOnly,
        placeholder: 'Search for a city...',
        searchPlaceholder: 'Search...',
        errorClass: 'border-red-500',
    });

    // 6) residence_city_id_update
    initDynamicSelect({
        elementId: 'residence_city_id_update',
        fetchShowUrl: (id) => `/api/cities/${id}`,
        fetchSearchUrl: (term) => `/api/cities?search=${encodeURIComponent(term)}`,
        oldValue: window.__OLD_residence_city_id,
        existingValue: window.__EXISTING_residence_city_id,
        isReadOnly,
        placeholder: 'Search for a city...',
        searchPlaceholder: 'Search...',
        errorClass: 'border-red-500',
    });

    // 7) mailing_city_id_create
    initDynamicSelect({
        elementId: 'mailing_city_id_create',
        fetchShowUrl: (id) => `/api/cities/${id}`,
        fetchSearchUrl: (term) => `/api/cities?search=${encodeURIComponent(term)}`,
        oldValue: window.__OLD_mailing_city_id,
        existingValue: window.__EXISTING_mailing_city_id,
        isReadOnly,
        placeholder: 'Search for a city...',
        searchPlaceholder: 'Search...',
        errorClass: 'border-red-500',
    });

    // 8) mailing_city_id_update
    initDynamicSelect({
        elementId: 'mailing_city_id_update',
        fetchShowUrl: (id) => `/api/cities/${id}`,
        fetchSearchUrl: (term) => `/api/cities?search=${encodeURIComponent(term)}`,
        oldValue: window.__OLD_mailing_city_id,
        existingValue: window.__EXISTING_mailing_city_id,
        isReadOnly,
        placeholder: 'Search for a city...',
        searchPlaceholder: 'Search...',
        errorClass: 'border-red-500',
    });
}

// Finally, run initAllDropdowns on DOMContentLoaded
document.addEventListener('DOMContentLoaded', initAllDropdowns);

// Export the helper if you want to import in other JS files:
export { initDynamicSelect, initAllDropdowns };
