package com.foxx.androidcast.sender;

/*********************************************************************
 * DeviceListAdapter.java
 * Created at: Fri 15 May 2026 17:47:09 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class DeviceListAdapter
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (5 commits, 130 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	a4c5b1e8d95601ce81990177e42d342f86afe8dd704bef1fc4db89cdb5b90670
**********************************************************************/
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.foxx.androidcast.R;
import com.foxx.androidcast.discovery.DiscoveryManager;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/** Device list with single or multi selection. */
public class DeviceListAdapter extends BaseAdapter {
  private final Context context;
  private final LayoutInflater inflater;
  private final boolean multiSelect;
  private final List<DiscoveryManager.DiscoveredDevice> devices = new ArrayList<>();
  private int selectedPosition = -1;
  private final Set<Integer> selectedPositions = new LinkedHashSet<>();

  public DeviceListAdapter(Context context, boolean multiSelect) {
    this.context = context;
    inflater = LayoutInflater.from(context);
    this.multiSelect = multiSelect;
  }

  public void clearDevices() {
    devices.clear();
    selectedPosition = -1;
    selectedPositions.clear();
    notifyDataSetChanged();
  }

  public void setDevices(List<DiscoveryManager.DiscoveredDevice> list) {
    devices.clear();
    if (list != null) {
      devices.addAll(list);
    }
    if (selectedPosition >= devices.size()) {
      selectedPosition = -1;
    }
    selectedPositions.removeIf(i -> i >= devices.size());
    notifyDataSetChanged();
  }

  public void setSelectedPosition(int position) {
    if (multiSelect) {
      if (position >= 0 && position < devices.size()) {
        if (selectedPositions.contains(position)) {
          selectedPositions.remove(position);
        } else {
          selectedPositions.add(position);
        }
      }
    } else {
      selectedPosition = position;
    }
    notifyDataSetChanged();
  }

  public int getSelectedPosition() {
    return selectedPosition;
  }

  public List<DiscoveryManager.DiscoveredDevice> getSelectedDevices() {
    List<DiscoveryManager.DiscoveredDevice> out = new ArrayList<>();
    if (multiSelect) {
      for (int i : selectedPositions) {
        if (i >= 0 && i < devices.size()) {
          out.add(devices.get(i));
        }
      }
    } else if (selectedPosition >= 0 && selectedPosition < devices.size()) {
      out.add(devices.get(selectedPosition));
    }
    return out;
  }

  public DiscoveryManager.DiscoveredDevice getSelectedDevice() {
    List<DiscoveryManager.DiscoveredDevice> list = getSelectedDevices();
    return list.isEmpty() ? null : list.get(0);
  }

  @Override
  public int getCount() {
    return devices.size();
  }

  @Override
  public DiscoveryManager.DiscoveredDevice getItem(int position) {
    return devices.get(position);
  }

  @Override
  public long getItemId(int position) {
    return position;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    if (row == null) {
      row = inflater.inflate(R.layout.item_device, parent, false);
    }
    TextView label = row.findViewById(R.id.device_label);
    DiscoveryManager.DiscoveredDevice d = devices.get(position);
    String prefix = d.pinnedRecent
            ? context.getString(R.string.discovery_pinned_label) + " · " : "";
    label.setText(prefix + d.name + " — " + d.host + " [" + d.transport.toUpperCase() + "]");
    boolean selected = multiSelect ? selectedPositions.contains(position) : position == selectedPosition;
    row.setActivated(selected);
    row.setSelected(selected);
    label.setTypeface(null, selected ? Typeface.BOLD : Typeface.NORMAL);
    return row;
  }
}
