package com.foxx.androidcast.ui;

/*********************************************************************
 * SettingsEnumSpinner.java
 * Created at: Sun 17 May 2026 22:49:49 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class SettingsEnumSpinner
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (3 commits, 121 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	ac91f40ce7f3db13225aadbea9f25900e0d7037eddd67d4fe3af81d43d06d5eb
**********************************************************************/
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.foxx.androidcast.R;

import java.util.ArrayList;
import java.util.List;

/** Spinner with optional disabled rows (future codecs). */
public final class SettingsEnumSpinner {
    private SettingsEnumSpinner() {}

    public static <T> void bind(Spinner spinner, T[] values, String[] labels, boolean[] selectable,
            T current, java.util.function.Consumer<T> onSelect) {
        bind(spinner, values, labels, null, selectable, current, onSelect);
    }

    public static <T> void bind(Spinner spinner, T[] values, String[] labels, int[] priorityScores,
            boolean[] selectable, T current, java.util.function.Consumer<T> onSelect) {
        spinner.setTag(R.id.tag_spinner_enum, values);
        spinner.setTag(R.id.tag_spinner_selectable, selectable);
        SettingsStringArrayAdapter adapter = priorityScores != null
                ? new ScoredDisabledAdapter(spinner.getContext(), labels, priorityScores, selectable)
                : new DisabledAdapter(spinner.getContext(), labels, selectable);
        spinner.setBackgroundResource(R.drawable.bg_settings_spinner);
        spinner.setAdapter(adapter);
        spinner.setPopupBackgroundResource(R.drawable.bg_settings_spinner_popup);
        final int[] selectedIndex = {0};
        for (int i = 0; i < values.length; i++) {
            if (values[i].equals(current) && selectable[i]) {
                selectedIndex[0] = i;
                break;
            }
        }
        spinner.setSelection(selectedIndex[0]);
        setAdapterSelectedPosition(adapter, selectedIndex[0]);
        SettingsStringArrayAdapter.wireSelectionRefresh(spinner, adapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                if (position < 0 || position >= values.length) {
                    return;
                }
                if (!selectable[position]) {
                    spinner.setSelection(selectedIndex[0]);
                    return;
                }
                selectedIndex[0] = position;
                setAdapterSelectedPosition(adapter, position);
                onSelect.accept(values[position]);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
        });
    }

    private static void setAdapterSelectedPosition(SettingsStringArrayAdapter adapter, int position) {
        adapter.setSelectedPosition(position);
    }

    @SuppressWarnings("unchecked")
    public static <T extends Enum<T>> T read(Spinner spinner, T fallback) {
        Object tag = spinner.getTag(R.id.tag_spinner_enum);
        Object selTag = spinner.getTag(R.id.tag_spinner_selectable);
        if (!(tag instanceof Enum[]) || !(selTag instanceof boolean[])) {
            return fallback;
        }
        Enum<?>[] values = (Enum<?>[]) tag;
        boolean[] selectable = (boolean[]) selTag;
        int pos = spinner.getSelectedItemPosition();
        if (pos >= 0 && pos < values.length && selectable[pos]) {
            return (T) values[pos];
        }
        return fallback;
    }

    private static final class DisabledAdapter extends SettingsStringArrayAdapter {
        private final boolean[] selectable;

        DisabledAdapter(Context context, String[] labels, boolean[] selectable) {
            super(context, labels);
            this.selectable = selectable;
        }

        @Override
        public boolean isEnabled(int position) {
            return position >= 0 && position < selectable.length && selectable[position];
        }
    }

    private static final class ScoredDisabledAdapter extends SettingsScoredArrayAdapter {
        private final boolean[] selectable;

        ScoredDisabledAdapter(Context context, String[] labels, int[] scores, boolean[] selectable) {
            super(context, labels, scores);
            this.selectable = selectable;
        }

        @Override
        public boolean isEnabled(int position) {
            return position >= 0 && position < selectable.length && selectable[position];
        }
    }
}
