import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:intl/intl.dart';
import 'package:sticky_headers/sticky_headers/widget.dart';
import 'main.dart' as Main;
import 'newActivity.dart';
import 'Data.dart';
import 'User.dart' as User;
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

class Activities extends StatefulWidget {
  const Activities({Key? key}) : super(key: key);

  @override
  _ActivitiesState createState() => _ActivitiesState();
}

class _ActivitiesState extends State<Activities> {
  //late ProgressDialog progressDialog;
  TextEditingController searchController = TextEditingController();
  FocusNode _focus = FocusNode();
  bool searching = false;

  void _onFocusChange() {
    print("FOCUS CHANGED! : ${_focus.hasFocus}");

    if (!_focus.hasFocus) {
      searching = false;
      setState(() {});
    }
  }

  var refreshSub;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _focus.addListener(_onFocusChange);
    refreshSub = User.refreshStream.stream.listen((event) {
      if (!event) {
        setState(() {});
      }
    });
    //UpdateList();
    //init(context);
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _focus.removeListener(_onFocusChange);
    _focus.dispose();
    refreshSub?.closeStream();
  }

  void UpdateList() async {
    try {
      //progressDialog.show(max: 100, msg: 'Loading Activities');
    } catch (e) {}
    await User.refreshUserData();
    setState(() {});
    try {
      // progressDialog.update(value: 100);
    } catch (e) {}
  }

  Map<String, ActivityListDateGroup> activitiesGroups = <String, ActivityListDateGroup>{};
  @override
  Widget build(BuildContext context) {
    // progressDialog = ProgressDialog(context: context);
    // List<Widget> activities = PrintTasks();
    activitiesGroups = PrintTasks();
    bool landscape=((MediaQuery.of(context).size.width / MediaQuery.of(context).size.height) > 1);
    return Scaffold(
        floatingActionButton: FloatingActionButton.extended(
            onPressed: () {
              Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewActivity())).then((value) => UpdateList());
            },
            label: Text("New Activity"),
            icon: Icon(Icons.add)),
        appBar: AppBar(
            toolbarHeight: (searching) ? 90 : null,
            title: (searching)
                ? Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Row(
                        mainAxisSize: MainAxisSize.max,
                        children: [
                          Expanded(
                            child: TextField(
                              onChanged: (text) {
                                setState(() {});
                              },
                              controller: searchController,
                              focusNode: _focus,
                              decoration: InputDecoration(
                                filled: true,
                              ),
                            ),
                          ),
                          InkWell(
                            onTap: () {
                              searching = false;
                              searchController.clear();
                              setState(() {});
                            },
                            child: Container(
                              margin: EdgeInsets.all(10),
                              child: Icon(Icons.cancel),
                            ),
                          )
                        ],
                      ),
                      Text(
                        'searched time : ${Main.MinutesToTimeString(searchTime)}',
                        style: TextStyle(fontSize: 15),
                      )
                    ],
                  )
                : Row(
                    mainAxisSize: MainAxisSize.max,
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Row(children: [Icon(Icons.task, color: Theme.of(context).primaryColor), SizedBox(width: 10), Text('Activities')]),
                      (selecting)
                          ? Row(children: [
                              InkWell(
                                  onTap: () {
                                    DeleteSelectedTasks();
                                  },
                                  child: Container(
                                    margin: EdgeInsets.all(5),
                                    child: Icon(
                                      Icons.delete,
                                      size: 30,
                                    ),
                                  )),
                              InkWell(
                                onTap: () {
                                  setState(() {
                                    selecting = false;
                                  });
                                },
                                child: Container(margin: EdgeInsets.all(10), child: Icon(Icons.close, size: 30)),
                              )
                            ])
                          : Row(
                              children: [
                                InkWell(
                                    onTap: () {
                                      searching = true;
                                      _focus.requestFocus();
                                      setState(() {});
                                    },
                                    child: Container(
                                      margin: EdgeInsets.all(10),
                                      child: Icon(
                                        Icons.search,
                                        size: 30,
                                      ),
                                    )),
                                InkWell(
                                  onTap: () {
                                    UpdateList();
                                    setState(() {});
                                  },
                                  child: Container(margin: EdgeInsets.all(10), child: Icon(Icons.refresh, size: 30)),
                                )
                              ],
                            ),
                    ],
                  )),
        drawer: landscape ? null : Main.navDrawer(context, 2),
        body: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            landscape?Main.navDrawer(context, 2) : Container(),
            Expanded(
              child: Container(
                  padding: EdgeInsets.all(0),
                  child: ScrollablePositionedList.builder(
                      itemScrollController: scrollController,
                      itemCount: activitiesGroups.length,
                      itemBuilder: (context, index) {
                        //  return activities[index];
                        return StickyHeader(
                            header: activitiesGroups.values.toList()[index].dateSeperator,
                            content: Column(
                              children: activitiesGroups.values.toList()[index].activities,
                            ));
                      })
                  // SingleChildScrollView(
                  //     child: Column(
                  //   children: PrintTasks(),
                  // ))
                  ),
            ),
          ],
        ));
  }

  DateFormat dFormat = DateFormat("yyyy-MM-dd");
  ItemScrollController scrollController = ItemScrollController();
  ScrollController controller = ScrollController();
  int searchTime = 0;
  Map<String, ActivityListDateGroup> PrintTasks() {
    Map<String, ActivityListDateGroup> _tasks = <String, ActivityListDateGroup>{};

    print('Priting cats : ' + User.taskTypes.length.toString());
    String lastDate = "";

    Map<String, int> productivtyActs = <String, int>{};
    Map<String, int> unproductivtyActs = <String, int>{};
    Map<String, int> totalMinutes = <String, int>{};
    for (var element in User.activities) {
      String thisDate = dFormat.format(element.startTime);
      int thisMinutes = element.endTime.difference(element.startTime).inMinutes;
      if (totalMinutes.containsKey(thisDate)) {
        if ((totalMinutes[thisDate] ?? 0) < thisMinutes) {
          totalMinutes[thisDate] = thisMinutes;
        }
      } else {
        totalMinutes.putIfAbsent(thisDate, () => thisMinutes);
      }

      if (element.taskType.cat?.productive ?? false) {
        if (productivtyActs.containsKey(thisDate)) {
          productivtyActs[thisDate] = (productivtyActs[thisDate]! + thisMinutes);
        } else {
          productivtyActs.putIfAbsent(thisDate, () => thisMinutes);
        }
      } else {
        if (unproductivtyActs.containsKey(thisDate)) {
          unproductivtyActs[thisDate] = (unproductivtyActs[thisDate]! + thisMinutes);
        } else {
          unproductivtyActs.putIfAbsent(thisDate, () => thisMinutes);
        }
      }
    }
    print(productivtyActs);
    //for (var element in User.activities) {
    searchTime = 0;
    for (int i = 0; i < User.activities.length; i++) {
      Activity element = User.activities[i];
      if (searching) {
        bool matchMetadata = element.metadata!.toLowerCase().contains(searchController.text.toLowerCase());
        bool matchTaskType = element.taskType.name.toLowerCase().contains(searchController.text.toLowerCase());
        bool matchCategory = element.taskType.cat!.name.toLowerCase().contains(searchController.text.toLowerCase());
        if (matchMetadata || matchTaskType || matchCategory) {
          //Good to go
          searchTime += element.endTime.difference(element.startTime).inMinutes;
        } else {
          continue;
        }
      }

      String thisDate = dFormat.format(element.startTime);

      if (thisDate != lastDate) {
        int prodActs = productivtyActs[thisDate] ?? 0;
        int unProdActs = unproductivtyActs[thisDate] ?? 0;
        //_tasks.add(DateSeperator(thisDate, prodActs, unProdActs));
        // _tasks.putIfAbsent(DateSeperator(thisDate, prodActs, unProdActs), () => [List.generate(0, (i) => List(2));]);
        _tasks.putIfAbsent(thisDate, () => ActivityListDateGroup(DateSeperator(thisDate, prodActs, unProdActs), []));
        // print('adding');
        lastDate = thisDate;
      }
      String name = element.taskType.name;
      if (element.taskType.cat == null) {
        print('Got some null cat : ${element.taskType.name}');
      } else {
        Color color = Main.HexColor.fromHex(element.taskType.cat?.color ?? '#000000');
        bool productive = element.taskType.cat?.productive ?? true;
        Widget task = ActivityCard(context, name, element.startTime, element.endTime, productive, color, element, totalMinutes[thisDate] ?? 0);
        // print('Activity : ${name} ,sTime: ${element.startTime}, eTime: ${element.endTime}');
        // _tasks.values.toList()[_tasks.length-1].add(task);
        _tasks[thisDate]!.activities.add(task);
      }
      //Check for gaps
      if (i < User.activities.length - 1) {
        int gap = User.activities[i].trueStartTime.difference(User.activities[i + 1].trueEndTime).inMinutes;
        if (gap > 10) {
          Widget addGap = timeGap(User.activities[i].trueStartTime, User.activities[i + 1].trueEndTime);

          //_tasks.values.toList()[_tasks.length-1].add(addGap);
          _tasks[thisDate]!.activities.add(addGap);
        }
      }
    }

    return _tasks;
  }

  Widget timeGap(DateTime sTime, DateTime eTime) {
    DateFormat dateFormat = DateFormat("HH:mm");
    String gap = Main.MinutesToTimeString(sTime.difference(eTime).inMinutes);
    return Row(
      mainAxisSize: MainAxisSize.max,
      children: [
        Container(
            padding: EdgeInsets.fromLTRB(10, 0, 5, 0),
            child: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [
              // Text(dateFormat.format(activity.endTime)),
              SizedBox(width: 1, height: 30, child: Container(color: Colors.white)),
              Text(dateFormat.format(eTime))
            ])),
        Expanded(
          child: InkWell(
            onTap: () {
              Navigator.of(context)
                  .push(MaterialPageRoute(builder: (context) => NewActivity(sTime: eTime, eTime: sTime)))
                  .then((value) => UpdateList());
            },
            child: Card(
                child: Row(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                Container(
                  alignment: Alignment.bottomLeft,
                  padding: const EdgeInsets.all(8),
                  child: Text('Untracked period $gap'),
                ),
                Row(
                  children: [Icon(Icons.add, size: 30), Text("Add Activity")],
                ),
              ],
            )),
          ),
        ),
      ],
    );
  }

  void OnJumpToDate(date) {
    int itemId = 0;
    List<String> keys = activitiesGroups.keys.toList();
    List<ActivityListDateGroup> values = activitiesGroups.values.toList();
    for (int i = 0; i < activitiesGroups.length; i++) {
      if (keys[i] == dFormat.format(date)) {
        break;
      }
      itemId++;
      // itemId+= values[i].activities.length;
    }
    scrollController.scrollTo(index: itemId, duration: Duration(seconds: 1), curve: Curves.fastOutSlowIn);
  }

  Widget DateSeperator(date, prodActs, unprodActs, {Function? onTap}) {
    // double prodPercentage = (prodActs / (prodActs + unprodActs)) * 100;

    return FutureBuilder(
        future: Settings.getUntrackedUnproductive(),
        builder: (context, snapshot) {
          double prodPercentage = (User.ParseBool(snapshot.data)) ? ((prodActs / 1440) * 100) : ((prodActs / unprodActs) * 100);
          return Container(
            color: Color(0xFF333333),
            padding: const EdgeInsets.fromLTRB(0, 10, 10, 10),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Row(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    InkWell(
                      onTap: () {
                        DatePicker.showDatePicker(context,
                            showTitleActions: true,
                            minTime: User.activities[User.activities.length - 1].startTime,
                            maxTime: User.activities[0].startTime,
                            theme: DatePickerTheme(), onChanged: (date) {
                          // print('change $date');
                        }, onConfirm: OnJumpToDate, currentTime: DateTime.parse(date), locale: LocaleType.en);
                      },
                      child: Row(
                        children: [
                          SizedBox(
                            width: 15,
                          ),
                          Icon(Icons.circle),
                          SizedBox(
                            width: 10,
                          ),
                          Text(
                            date,
                            style: TextStyle(fontSize: 18),
                          ),
                        ],
                      ),
                    ),
                    Row(
                      children: [
                        Row(
                          children: [
                            if (prodPercentage < 35)
                              Text(
                                Main.MinutesToTimeString(prodActs),
                              ),
                            Container(
                              child: Align(
                                child: (prodPercentage >= 35)
                                    ? FittedBox(
                                        child: Text(
                                        Main.MinutesToTimeString(prodActs),
                                      ))
                                    : Container(),
                                alignment: Alignment.center,
                              ),
                              width: (prodPercentage) * 1,
                              height: 20,
                              decoration: BoxDecoration(color: Colors.green, borderRadius: BorderRadius.horizontal(left: Radius.circular(10))),
                            ),
                            Container(
                              child: Align(
                                child: (prodPercentage < 35) ? Text(Main.MinutesToTimeString(unprodActs)) : Container(),
                                alignment: Alignment.center,
                              ),
                              width: (100 - prodPercentage) * 1,
                              height: 20,
                              decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.horizontal(right: Radius.circular(10))),
                            ),
                            if (prodPercentage >= 35) Text(Main.MinutesToTimeString(unprodActs))
                          ],
                        ),
                        SizedBox(
                          width: 10,
                        ),
                        Text(prodPercentage.toStringAsFixed(1) + "%",
                            style: TextStyle(color: Colors.green, fontWeight: FontWeight.bold, fontSize: 20))
                      ],
                    )
                    // CustomPaint(
                    //   painter: MyPlayerBar(100, prodPercentage.toInt(),
                    //       background: Colors.green, fill: Colors.deepOrange),
                    //   child: Container(
                    //     alignment: Alignment.center,
                    //     height: 25.0,
                    //     width: 200,
                    //     child: Text(
                    //         "Productivity : ${prodPercentage.toStringAsFixed(1)}%",
                    //     style: TextStyle(fontWeight: FontWeight.bold),),
                    //
                    //   ),
                    // ),
                  ],
                )
              ],
            ),
          );
        });
  }

  bool selecting = false;
  Widget ActivityCard(
      BuildContext context, String name, DateTime sTime, DateTime eTime, bool productive, Color color, Activity activity, int totalMinutes) {
    DateFormat dateFormat = DateFormat("HH:mm");
    int thisMinutes = (activity.endTime.difference(activity.startTime).inMinutes);

    int timePercentage = ((thisMinutes / totalMinutes) * 100).toInt();
    //  print("$thisMinutes / $totalMinutes");
    bool containsMetadata = ((activity.metadata ?? 'null') != 'null') && ((activity.metadata ?? '').isNotEmpty);
    bool containsStepData = (containsMetadata && activity.metadata!.contains('[') && activity.metadata!.contains(']'));
    var _timeSpan = eTime.difference(sTime);
    String timeSpan = ((_timeSpan.inHours > 0) ? _timeSpan.inHours.toString() + 'h ' : '') +
        ((_timeSpan.inMinutes % 60 > 0) ? (_timeSpan.inMinutes % 60).toString() + 'm' : '');
    return Row(children: [
      // Container(),
      (selecting)
          ? Checkbox(
              value: selectedActivities.contains(activity),
              onChanged: (value) {
                print('selected $name');
                OnItemSelected(activity);
                setState(() {});
              })
          : Container(
              padding: EdgeInsets.fromLTRB(10, 0, 5, 0),
              child: Column(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  // Text(dateFormat.format(activity.endTime)),
                  SizedBox(width: 1, height: 100, child: Container(color: Colors.white)),
                  Text(dateFormat.format(activity.startTime)),
                ],
              )),
      Expanded(
        child: Column(children: [
          Padding(
            padding: const EdgeInsets.fromLTRB(0, 0, 5, 0),
            child: Card(

                // color: color,
                elevation: 30,
                shadowColor: color,
                child: InkWell(
                    onTap: () {
                      //Open Respective Category
                      if (selecting) {
                        OnItemSelected(activity);
                      }
                      setState(() {});
                    },
                    onLongPress: () {
                      print('gonna delete');
                      selecting = !selecting;
                      selectedActivities = [activity];
                      setState(() {});
                    },
                    child: Container(
                        padding: EdgeInsets.all(15),
                        child: Column(
                          children: [
                            Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [
                              Text(name + " [$timeSpan]", style: TextStyle(fontSize: 17)),
                              if (containsMetadata)
                                Row(mainAxisAlignment: MainAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [
                                  Icon(
                                    Icons.arrow_forward_outlined,
                                    size: 20,
                                  ),
                                  SizedBox(
                                    width: MediaQuery.of(context).size.width / 3,
                                    child: Text(
                                      (containsStepData)
                                          ? activity.metadata!.substring(activity.metadata!.indexOf(']') + 1)
                                          : (activity.metadata ?? ''),
                                    ),
                                  ),
                                ]),
                              // Icon(Icons.analytics, color: color, size: 20,),
                            ]),
                            SizedBox(
                              height: 5,
                            ),
                            Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
                              Text(dateFormat.format(sTime) + " - " + dateFormat.format(eTime)),
                              SizedBox(
                                width: 20,
                              ),
                              Row(
                                children: [
                                  (activity.taskType.relatedProject != null)
                                      ? Row(
                                          children: [
                                            if (containsStepData)
                                              Container(
                                                  padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
                                                  decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
                                                  child: Text(activity.metadata!.substring(1, activity.metadata!.indexOf(']')) ?? 'n/a')),
                                            SizedBox(width: 8 ,),
                                            Container(
                                                padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
                                                decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black26),
                                                child: Text(activity.taskType.relatedProject!.name ?? 'n/a')),
                                          ],
                                        )
                                      : Container(),
                                  SizedBox(
                                    width: 10,
                                  ),
                                  Container(
                                      padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
                                      decoration:
                                          BoxDecoration(borderRadius: BorderRadius.circular(10), color: (productive) ? Colors.green : Colors.red),
                                      child: Text(activity.taskType.cat?.name ?? 'n/a')),
                                ],
                              )
                              // Icon(Icons.circle,
                              //   color: (productive)
                              //       ? Colors.green
                              //       : Colors.red)
                            ])
                          ],
                        ))
                )),
          ),
          Container(
              margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
              height: 2,
              child: Row(
                children: [Expanded(flex: timePercentage, child: Container(color: color)), Expanded(flex: 100 - timePercentage, child: Container())],
              )),
        ]),
      ),
      if (selecting)
        InkWell(
          child: Container(margin: EdgeInsets.all(10), child: Icon(Icons.edit)),
          onTap: () {
            selecting = false;
            selectedActivities = [];
            setState(() {});
            Navigator.of(context)
                .push(MaterialPageRoute(
                    builder: (context) => NewActivity(
                          sTime: activity.trueStartTime,
                          eTime: activity.trueEndTime,
                          metadata: activity.metadata,
                          selectedTask: activity.taskType.name +
                              ((activity.taskType.relatedProject != null) ? ' [${activity.taskType.relatedProject!.name}]' : ''),
                        )))
                .then((value) => UpdateList());
          },
        )
    ]);
  }

  void OnItemSelected(Activity activity) {
    if (!selectedActivities.contains(activity)) {
      selectedActivities.add(activity);
    } else {
      selectedActivities.remove(activity);
    }
  }

  void DeleteSelectedTasks() async {
    //progressDialog.show(max: 100, msg: 'Deleteing ${selectedActivities.length} Activities');
    selectedActivities.forEach((element) async {
      await User.UserOperations.deleteActivity(element, bulk: true);
    });

    await Future.delayed(Duration(seconds: 2));
    await User.UserOperations.executeQueries();
    await User.updateActList();
    selectedActivities = [];
    selecting = false;
    setState(() {
      // progressDialog.update(value: 100);
    });
  }
}

class ActivityListDateGroup {
  ActivityListDateGroup(this.dateSeperator, this.activities);
  Widget dateSeperator;
  List<Widget> activities;
}

List<Activity> selectedActivities = [];
