import 'dart:math';

import 'package:flutter/material.dart';

extension IterableHelper<T> on Iterable<T> {
  T? firstWhereOrNull(bool Function(T) test) => where(test).firstOrNull;
}

extension NullableIterableHelper<T> on Iterable<T?> {
  Iterable<T> whereNotNull() => where((element) => element != null).cast();
}

extension ListHelper<T> on List<T> {
  // List<T> shuffle([int? seed]) {
  //   Random r = Random(seed);
  //   var items = [...this];
  //   for (var i = length - 1; i > 0; i--) {
  //     var n = r.nextInt(i + 1);
  //
  //     var temp = items[i];
  //     items[i] = items[n];
  //     items[n] = temp;
  //   }
  //
  //   return items;
  // }

  void move(int from, int to) {
    RangeError.checkValidIndex(from, this, "from", length);
    RangeError.checkValidIndex(to, this, "to", length);
    var element = this[from];
    if (from < to) {
      this.setRange(from, to, this, from + 1);
    } else {
      this.setRange(to + 1, from + 1, this, to);
    }
    this[to] = element;
  }

  void sortInOrder<P>(List<P> order, P valueGetter(T v)) => sort((p, n) {
        final pVal = valueGetter(p);
        final nVal = valueGetter(n);
        final pIndex = order.indexOf(pVal);
        final nIndex = order.indexOf(nVal);
        if (pIndex == -1) {
          return nIndex == -1
              ? () {
                  if (pVal is num) {
                    return pVal.compareTo(nVal as num);
                  } else if (pVal is String) {
                    return pVal.compareTo(nVal as String);
                  }
                  return pVal.toString().compareTo(nVal.toString());
                }.call()
              : 1;
        } else if (nIndex == -1) {
          return -1;
        }
        return pIndex.compareTo(nIndex);
      });
}
