// ignore_for_file: unused_import

import 'dart:developer';

import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:jiffy/jiffy.dart';
import 'package:linear_progress_bar/linear_progress_bar.dart';
import 'package:multi_select_flutter/multi_select_flutter.dart';
import 'package:tp5/core/core.dart';
import 'package:tp5/csv/csv_data.dart';
import 'package:tp5/csv/data.dart';
import 'package:tp5/flightslist/w_flt.dart';
import 'package:tp5/fltinfo/delaycodes.dart';
import 'package:tp5/fltinfo/widget/w_cadre.dart';
import 'package:tp5/ftl/widget/w_shadowbox.dart';
import 'package:tp5/lido/lido_api.dart';
import 'package:tp5/lido/model/Lidoapi_list.dart';
import 'package:tp5/lido/model/Lidoapi_ofp.dart';
import 'package:tp5/lido/w_lidoflt.dart';
import 'package:tp5/pdf/pdf_page.dart';
import 'package:tp5/roster/api/crewlink_api.dart';
import 'package:tp5/roster/models/duty.dart';
import 'package:tp5/roster/widgets/w_airport.dart';
import 'package:tp5/roster/widgets/w_citypair.dart';
import 'package:tp5/roster/widgets/w_crew.dart';
import 'package:tp5/roster/widgets/w_day.dart';
import 'package:tp5/roster/widgets/w_fnum.dart';
import 'package:tp5/roster/widgets/w_hour.dart';
import 'package:tp5/widgets/my_row.dart';

class DutyinfoPage extends ConsumerStatefulWidget {
  const DutyinfoPage({required this.params, super.key});
  final DutyinfoParams params;

  @override
  ConsumerState<ConsumerStatefulWidget> createState() => _DutyinfoPageState();
}

class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
  @override
  void initState() {
    Future.delayed(Duration.zero, () {
      if (widget.params.tlc != null) {
        final qualif = ref.read(dataProvider).qualif;
        collegeSelected = qualif
            .where((e) => e.tlc == widget.params.tlc)
            .map((e) => e.college ?? "")
            .toSet()
            .toList();
        acSelected = qualif
            .where((e) => e.tlc == widget.params.tlc)
            .map((e) => e.ac ?? "")
            .toSet()
            .toList();
        baseSelected = qualif
            .where((e) => e.tlc == widget.params.tlc)
            .map((e) => e.base ?? "")
            .toSet()
            .toList();
      }
      crewPnlegLoad();
    });
    super.initState();
  }

  // List crew = [];

  Jiffy _now = Jiffy.now().toUtc();

  @override
  Widget build(BuildContext context) {
    //final data = ref.watch(dataProvider);
    //final pnleg = data.pnleg;
    // final _dateNotifiedcrew = data.pnlegupdate;

    _now = ref.watch(clockProvider);

    //final qualif = ref.watch(dataProvider).qualif;

    return Scaffold(
      appBar: AppBar(
        title: MyRow(
          // mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(
                '${widget.params.dutytype ?? ""} ${widget.params.label ?? ""} ${widget.params.dep}${widget.params.des != null ? "-${widget.params.des}" : ""}'),
            const Gap(10),
            Text(widget.params.jdep!.format(pattern: "EEE ddMMM'yy"),
                style: const TextStyle(fontSize: 12)),
          ],
        ),
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () {
            context.pop(context);
          },
        ),
        actions: [
          Text(
            '${widget.params.dutytype ?? "Duty"} info',
            style: TextStyle(
                fontSize: 12,
                fontWeight: FontWeight.w700,
                color: Colors.yellow),
          ),
          Gap(10)
        ],
      ),
      body: ListView(
        padding: const EdgeInsets.all(5),
        children: [
          WCadre(
            child: Column(
              children: [
                WDay(date: widget.params.jdep!),
                if (widget.params.label != null)
                  Text(
                    widget.params.label!,
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
                  )
                else if (widget.params.dutytype != null)
                  Text(
                    widget.params.dutytype!,
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
                  ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  mainAxisSize: MainAxisSize.max,
                  children: [
                    if (widget.params.des != null)
                      WCitypair(
                          iata1: "${widget.params.dep}",
                          iata2: widget.params.des ?? "---")
                    else
                      WAirport(iata: widget.params.dep ?? "---"),
                  ],
                ),
                Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    mainAxisSize: MainAxisSize.max,
                    children: [
                      WHour(jiffy: widget.params.jdep!),
                      if (widget.params.jdes != null) ...[
                        const Gap(20),
                        WHour(jiffy: widget.params.jdes!)
                      ],
                    ]),
                const Gap(10)
              ],
            ),
          ),
          const Gap(20),
          if (widget.params.dutytype == "standby")
            _stdbyCrew()
          else
            _notifiedCrew(),
        ],
      ),
    );
  }

  Jiffy? _dateNotifiedcrew;

  static List<Pnleg> filterPnleg(Map data) {
    final List<Pnleg> pnleg = data["pnleg"];
    final DutyinfoParams filter = data["filter"];
    return pnleg
        .where((leg) => ((filter.jdep == null ||
                (filter.sameday
                    ? (leg.jdep?.startOf(Unit.day) ==
                        filter.jdep?.startOf(Unit.day))
                    : ((leg.jdep == filter.jdep) &&
                        (filter.jdes == null || leg.jarr == filter.jdes)))) &&
            (filter.dep == null || leg.dep == filter.dep) &&
            (filter.des == null || leg.arr == filter.des) &&
            (filter.label == null || leg.label == filter.label) &&
            (filter.dutytype == null || leg.dutytype == filter.dutytype)))
        .toList();
  }

  List<Pnleg> crewPnleg = [];
  bool crewPnlegLoading = false;
  crewPnlegLoad() async {
    crewPnlegLoading = true;

    setState(() {});
    final data = ref.watch(dataProvider);
    final pnleg = data.pnleg;
    _dateNotifiedcrew = data.pnlegupdate;

    crewPnleg =
        await compute(filterPnleg, {"pnleg": pnleg, "filter": widget.params});
    crewPnlegLoading = false;
    setState(() {});
  }

  _notifiedCrew() {
    // final qualif = ref.watch(qualifProvider(CrewFilter()));
    final qualif = ref.watch(dataProvider).qualif;

    return WCadre(
      titleright: crewPnlegLoading
          ? Padding(
              padding: const EdgeInsets.all(5.0),
              child: CircularProgressIndicator(),
            )
          : ElevatedButton.icon(
              label: const Text("Update", style: TextStyle(fontSize: 9)),
              onPressed: () async {
                await crewPnlegLoad();
              },
              icon: const Icon(Icons.update)),
      title: "Notified Crew (alt)",
      bottomright: _dateNotifiedcrew != null
          ? Text("data retrieved ${_dateNotifiedcrew?.from(_now)}",
              style: GoogleFonts.robotoMono(
                  fontSize: 10, fontWeight: FontWeight.w300))
          : null,
      child: crewPnleg.isEmpty
          ? const Text("No data found !")
          : Column(
              children: [
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Column(
                      children: crewPnleg
                          .mapIndexed((int i, leg) => {
                                "index": i,
                                "college": (["F", ""].contains(leg.type))
                                    ? "DH"
                                    : (qualif
                                            .firstWhereOrNull((e) =>
                                                (e.tlc == leg.tlc) &&
                                                (e.ac == leg.actype))
                                            ?.college ??
                                        qualif
                                            .firstWhereOrNull(
                                                (e) => e.tlc == leg.tlc)
                                            ?.college ??
                                        "--")
                              })
                          .sortedByCompare(
                              (e) => e["college"].toString(), collegeSort)
                          .map<Widget>((e) {
                    final x = crewPnleg.elementAt(e["index"] as int);
                    // final pn = qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
                    final pn = (qualif.firstWhereOrNull(
                            (e) => (e.tlc == x.tlc) && (e.ac == x.actype)) ??
                        qualif.firstWhereOrNull((e) => e.tlc == x.tlc));
                    return WCrew(
                      college: pn?.college,
                      mle: x.tlc,
                      base: pn?.base,
                      name: "${pn?.lname}, ${pn?.fname}",
                    );
                  }).toList()),
                )
              ],
            ),
    );
  }

  List<String> collegeSelected = [];
  List<String> acSelected = [];
  List<String> baseSelected = [];

  _stdbyCrew() {
    // final qualif = ref.watch(qualifProvider(CrewFilter()));
    final qualif = ref.watch(dataProvider).qualif;
    final tlcs = crewPnleg.map((e) => e.tlc).toSet();
    final pairs = qualif
        .where((e) => tlcs.contains(e.tlc))
        .map((e) => "${e.college},${e.ac},${e.base}")
        .toSet()
        .map((e) => e.split(","))
        .toList();
    final List<String> pnfilterd = qualif
        .where((q) =>
            ((collegeSelected.isEmpty || collegeSelected.contains(q.college)) &&
                (acSelected.isEmpty || acSelected.contains(q.ac)) &&
                (baseSelected.isEmpty || baseSelected.contains(q.base))))
        .map((e) => e.tlc ?? "")
        .toSet()
        .toList();
    final List<Pnleg> crewPnlegFiltered =
        crewPnleg.where((e) => pnfilterd.contains(e.tlc)).toList();
    return WCadre(
      titleright: crewPnlegLoading
          ? Padding(
              padding: const EdgeInsets.all(5.0),
              child: CircularProgressIndicator(),
            )
          : ElevatedButton.icon(
              label: const Text("Update", style: TextStyle(fontSize: 9)),
              onPressed: () async {
                await crewPnlegLoad();
              },
              icon: const Icon(Icons.update)),
      title: "STDBY Crew",
      bottomright: _dateNotifiedcrew != null
          ? Text("data retrieved ${_dateNotifiedcrew?.from(_now)}",
              style: GoogleFonts.robotoMono(
                  fontSize: 10, fontWeight: FontWeight.w300))
          : null,
      child: crewPnleg.isEmpty
          ? const Text("No data found !")
          : Column(
              children: [
                MyRow(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Gap(5),
                    Column(
                      children: [
                        const Text('College:', style: TextStyle(fontSize: 11)),
                        Text("(${(collegeSelected.length)})",
                            style: TextStyle(fontSize: 11))
                      ],
                    ),
                    Gap(5),
                    MultiSelectChipDisplay(
                      colorator: (value) => (collegeSelected.contains(value))
                          ? Colors.green[800]
                          : Colors.grey[900],
                      //chipColor: Colors.blue[900],
                      icon: null,
                      textStyle: TextStyle(fontSize: 9, color: Colors.white),
                      scrollBar: HorizontalScrollBar(),
                      scroll: true,
                      items: pairs
                          .map((e) => e[0])
                          .sortedByCompare((e) => e, collegeSort)
                          .toSet()
                          .map((e) => MultiSelectItem(e, "$e"))
                          .toList(),
                      onTap: (value) {
                        setState(() {
                          if (collegeSelected.contains(value)) {
                            collegeSelected.remove(value);
                          } else {
                            collegeSelected.add(value);
                          }
                        });
                      },
                    ),
                  ],
                ),
                MyRow(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    Gap(5),
                    Column(
                      children: [
                        const Text('ACs:', style: TextStyle(fontSize: 11)),
                        Text("(${(acSelected.length)})",
                            style: TextStyle(fontSize: 11))
                      ],
                    ),
                    Gap(5),
                    MultiSelectChipDisplay(
                      colorator: (value) => (acSelected.contains(value))
                          ? Colors.green[800]
                          : Colors.grey[900],
                      //chipColor: Colors.blue[900],
                      icon: null,
                      textStyle: TextStyle(fontSize: 9, color: Colors.white),
                      scrollBar: HorizontalScrollBar(),
                      scroll: true,
                      items: pairs
                          .map((e) => e[1])
                          .sortedByCompare((e) => e, acSort)
                          .toSet()
                          .map((e) => MultiSelectItem(e, "$e"))
                          .toList(),
                      onTap: (value) {
                        setState(() {
                          if (acSelected.contains(value)) {
                            acSelected.remove(value);
                          } else {
                            acSelected.add(value);
                          }
                        });
                      },
                    ),
                  ],
                ),
                MyRow(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: [
                    const Gap(5),
                    Column(
                      children: [
                        const Text('Base:', style: TextStyle(fontSize: 11)),
                        Text("(${(baseSelected.length)})",
                            style: TextStyle(fontSize: 11))
                      ],
                    ),
                    const Gap(5),
                    MultiSelectChipDisplay(
                      colorator: (value) => (baseSelected.contains(value))
                          ? Colors.green[800]
                          : Colors.grey[900],
                      //chipColor: Colors.blue[900],
                      icon: null,
                      textStyle: TextStyle(fontSize: 9, color: Colors.white),
                      scrollBar: HorizontalScrollBar(),
                      scroll: true,
                      items: pairs
                          .map((e) => e[2])
                          .sortedByCompare((e) => e, baseSort)
                          .toSet()
                          .map((e) => MultiSelectItem(e, "$e"))
                          .toList(),
                      onTap: (value) {
                        setState(() {
                          if (baseSelected.contains(value)) {
                            baseSelected.remove(value);
                          } else {
                            baseSelected.add(value);
                          }
                        });
                      },
                    ),
                  ],
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Column(
                      children: crewPnlegFiltered
                          .mapIndexed((int i, leg) {
                            // print(leg);
                            return {
                              "index": i,
                              "college": (qualif
                                          .where((e) => e.tlc == leg.tlc)
                                          .map((e) => e.college)
                                          .sortedByCompare(
                                              (e) => e ?? "", collegeSort))
                                      .firstOrNull ??
                                  "--",
                              // "jdep": (leg.jdep?.millisecondsSinceEpoch ?? 0)
                              "jdep": (leg.label ?? "0")
                            };
                          })
                          .sortedByCompare(
                              (e) => [
                                    e["jdep"].toString(),
                                    e["college"].toString()
                                  ],
                              jdepcollegeSort)
                          .map<Widget>((e) {
                            final x =
                                crewPnlegFiltered.elementAt(e["index"] as int);
                            // final pn =
                            //     qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
                            final pn = (qualif.firstWhereOrNull((e) =>
                                    (e.tlc == x.tlc) && (e.ac == x.actype)) ??
                                qualif.firstWhereOrNull((e) => e.tlc == x.tlc));
                            return Row(
                              children: [
                                Text("${e["jdep"]}"),
                                WCrew(
                                  college: pn?.college,
                                  mle: x.tlc,
                                  base: pn?.base,
                                  name: "${pn?.lname}, ${pn?.fname}",
                                ),
                              ],
                            );
                          })
                          .toList()),
                )
              ],
            ),
    );
  }
}

class DutyinfoParams {
  const DutyinfoParams({
    this.tlc,
    this.sameday = false,
    this.date,
    this.start,
    this.end,
    this.label,
    this.dutytype,
    this.jdep,
    this.jdes,
    this.dep,
    this.des,
  });
  final String? tlc;
  final bool sameday;
  final Jiffy? start;
  final Jiffy? end;
  final String? date;
  final String? label;
  final String? dutytype;
  final Jiffy? jdep;
  final Jiffy? jdes;
  final String? dep;
  final String? des;
}

int collegeSort(String a, String b) {
  // Define the order based on your requirements
  final order = ['CP', 'FO', 'PU', 'SE', 'ST', 'JU'];

  // Get the index of each element in the order list
  final indexA = !order.contains(a) ? 99 : order.indexOf(a);
  final indexB = !order.contains(b) ? 99 : order.indexOf(b);

  // Compare based on the index
  return indexA.compareTo(indexB);
}

int acSort(String a, String b) {
  // Define the order based on your requirements
  final order = ['320', '330', '32N', '319', '32T'];

  // Get the index of each element in the order list
  final indexA = !order.contains(a) ? 99 : order.indexOf(a);
  final indexB = !order.contains(b) ? 99 : order.indexOf(b);

  // Compare based on the index
  return indexA.compareTo(indexB);
}

int baseSort(String a, String b) {
  // Define the order based on your requirements
  final order = ['TUN', 'MIR', 'DJE'];

  // Get the index of each element in the order list
  final indexA = !order.contains(a) ? 99 : order.indexOf(a);
  final indexB = !order.contains(b) ? 99 : order.indexOf(b);

  // Compare based on the index
  return indexA.compareTo(indexB);
}

int jdepcollegeSort(List<String> a, List<String> b) {
  final String x = a[0];
  final String y = b[0];

  final res = x.compareTo(y);
  if (res == 0) {
    return collegeSort(a[1], b[1]);
  } else {
    return res;
  }
}
