import 'dart:io';

import 'package:application/logger.dart';
import 'package:application/service/api.dart';
import 'package:application/service/map_watch.dart';
import 'package:common_pub/model/distance.dart';
import 'package:common_pub/model/pace.dart';
import 'package:common_pub/utils.dart';
import 'package:fixnum/fixnum.dart';
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../../widget/title_point.dart';

class PersonalRankController extends GetxController {
  @override
  void onInit() {
    super.onInit();
    final now = DateTime.now();
    filterStartAt.value = DateTime(now.year, now.month, now.day);

    workFlushData();
  }

  Future<void> workFlushData() async {
    while (!isClosed) {
      final map = MapWatchService.instance;
      if (map == null) {
        activeList.clear();
        await 3.seconds.delay();
        continue;
      }
      final startAt = filterStartAt.value.millisecondsSinceEpoch ~/ 1000;
      try {
        final r = await ApiService.to.stub.toGameRanking(ToGameRankingRequest(
            mapId: map.id.toInt(), startSecond: Int64(startAt)));
        final out = <RankActiveInfo>[];

        for (final actSrc in r.list) {
          final act = RankActiveInfo()
            ..id = actSrc.actId
            ..name = actSrc.actName
            ..userList = actSrc.rankList.map((e) {
              final one = e.toModel();
              final memAct = map.getActiveById(actSrc.actId);
              if (memAct != null) {
                final memUser = memAct.getUserById(one.id);
                if (memUser != null) {
                  one.flag = memUser.flag.value;
                }
              }

              return one;
            }).toList();

          out.add(act);
        }

        activeList.value = out;
      } catch (_) {}

      await 3.seconds.delay();
    }
  }

  final filterStartAt = DateTime.now().obs;
  final activeList = <RankActiveInfo>[].obs;
  final Rx<RankActiveInfo?> selectActive = Rx(null);
}

class PersonalRankPage extends StatelessWidget {
  PersonalRankPage({super.key});

  final dateFmt = DateFormat('yyyy-MM-dd');

  @override
  Widget build(BuildContext context) {
    return GetBuilder(
        init: PersonalRankController(),
        builder: (c) {
          return Container(
            width: double.infinity,
            height: double.infinity,
            margin: const EdgeInsets.all(20),
            padding: const EdgeInsets.fromLTRB(12, 17, 12, 17),
            decoration: BoxDecoration(
                color: Colors.transparent,
                borderRadius: BorderRadius.circular(16)),
            child: DefaultTextStyle(
                style: const TextStyle(color: Colors.white),
                child: Row(
                  children: [
                    SizedBox(
                        width: 260,
                        height: double.infinity,
                        child: Obx(() => eActiveList(context, c))),
                    const SizedBox(width: 20),
                    Expanded(child: Obx(() => eUserList(context, c)))
                  ],
                )),
          );
        });
  }

  Future<void> _pickDate(BuildContext context, PersonalRankController c) async {
    final now = DateTime.now();

    final date = await showDatePicker(
        context: context,
        initialDate: c.filterStartAt.value,
        firstDate: DateTime(now.year - 1),
        lastDate: DateTime(now.year, now.month, now.day + 1),
    );

    if (date != null) {
      c.filterStartAt.value = DateTime(date.year, date.month, date.day);
    }
  }

  Widget titlePoint() {
    return const TitlePoint(color: Color(0xff98d8ff));
  }

  Widget eActiveList(BuildContext context, PersonalRankController c) {
    return Column(
      children: [
        Row(
          children: [
            Padding(padding: const EdgeInsets.all(8), child: titlePoint()),
            Text('活动列表',
                style: context.textTheme.titleLarge
                    ?.copyWith(color: Colors.white)),
            const Spacer(),
            Container(
              decoration: BoxDecoration(
                  border: Border.all(color: const Color(0xffe3e3e3))),
              child: TextButton(
                  onPressed: () => _pickDate(context, c),
                  child: Text(dateFmt.format(c.filterStartAt.value))),
            )
          ],
        ),
        const SizedBox(height: 20),
        Expanded(
            child: Container(
                padding: const EdgeInsets.all(12),
                decoration: BoxDecoration(
                    color: const Color(0xff003656),
                    borderRadius: BorderRadius.circular(9)),
                child: ListView(
                  children: c.activeList
                      .map((e) => wActiveCard(
                              context, e, c.selectActive.value?.id == e.id, () {
                            c.selectActive.value = e;
                          }))
                      .toList(),
                ))),
      ],
    );
  }

  Widget wActiveCard(BuildContext context, RankActiveInfo active, bool selected,
      VoidCallback onTap) {
    return GestureDetector(
        onTap: onTap,
        child: Container(
          decoration: const BoxDecoration(color: Color(0xff00a0ff), boxShadow: [
            BoxShadow(color: Color(0x4d000000), blurRadius: 3.5)
          ]),
          height: _cardHeight,
          width: double.infinity,
          margin: const EdgeInsets.only(top: 7),
          padding: const EdgeInsets.only(right: 11),
          child: Row(
            children: [
              Container(
                margin: const EdgeInsets.only(right: 10),
                height: double.infinity,
                width: 6.4,
                color: selected ? const Color(0xffff870d) : Colors.transparent,
              ),
              Expanded(child: Text(active.name)),
              const SizedBox(width: 8),
              Text(active.userList.length.toString())
            ],
          ),
        ));
  }

  Widget eUserList(BuildContext context, PersonalRankController c) {
    final active = c.selectActive.value;

    if (active == null) {
      return const SizedBox();
    }

    final userList = c.selectActive.value?.userList ?? <RankUserInfo>[];

    return Column(
      children: [
        Row(
          children: [
            const Padding(padding: EdgeInsets.all(8), child: TitlePoint()),
            Text('个人排名',
                style: context.textTheme.titleLarge
                    ?.copyWith(color: Colors.white)),
            Text(' (${active.name})',
                style: context.textTheme.titleLarge
                    ?.copyWith(color: const Color(0xffffcb00))),
          ],
        ),
        Expanded(
            child: Padding(
                padding: const EdgeInsets.all(18),
                child: Column(
                  children: [
                    eUserListTitle(context),
                    Expanded(
                        child: ListView(
                      children: userList.indexed.map<Widget>((t) {
                        return eUserCard(context, c, t.$1 + 1, t.$2);
                      }).toList(),
                    ))
                  ],
                )))
      ],
    );
  }

  Widget eUserListTitle(BuildContext context) {
    return DefaultTextStyle(
        style: const TextStyle(
            color: Color(0xff98d8ff),
            fontSize: 20,
            fontWeight: FontWeight.w700),
        child: Row(
          children: [
            const SizedBox(
                width: _userIndexWidth,
                child: Text('排名', textAlign: TextAlign.center)),
            const SizedBox(width: 4),
            const SizedBox(
                width: _userNameWidth,
                child: Text('用户名', textAlign: TextAlign.center)),
            verticalDivider(show: false),
            const Expanded(child: Text('路线ID', textAlign: TextAlign.center)),
            verticalDivider(show: false),
            const SizedBox(
                width: _userResultWidth,
                child: Text('成绩', textAlign: TextAlign.center)),
            verticalDivider(show: false),
            const SizedBox(
                width: _userTimeWidth,
                child: Text('总时间', textAlign: TextAlign.center)),
            verticalDivider(show: false),
            const Expanded(child: Text('总里程', textAlign: TextAlign.center)),
            verticalDivider(show: false),
            const Expanded(child: Text('配速', textAlign: TextAlign.center)),
            verticalDivider(show: false),
            const SizedBox(
                width: _userFlagWidth,
                child: Text('分组', textAlign: TextAlign.center)),
            verticalDivider(show: false),
          ],
        ));
  }

  Widget eUserCard(BuildContext context, PersonalRankController c, int index,
      RankUserInfo data) {
    return DefaultTextStyle(
        style: context.textTheme.bodyMedium!.copyWith(color: Colors.white),
        child: Container(
            height: _cardHeight,
            width: double.infinity,
            margin: const EdgeInsets.only(top: 3),
            child: Row(
              children: [
                Container(
                    width: _userIndexWidth,
                    height: double.infinity,
                    decoration: const BoxDecoration(
                        color: Color(0xffff870d),
                        borderRadius: BorderRadius.only(
                            topLeft: Radius.circular(6),
                            bottomLeft: Radius.circular(6))),
                    alignment: Alignment.center,
                    child: Text(
                      index.toString(),
                      textAlign: TextAlign.center,
                      style: const TextStyle(
                          fontSize: 34,
                          fontWeight: FontWeight.w700,
                          fontStyle: FontStyle.italic),
                    )),
                const SizedBox(width: 4),
                Expanded(
                    child: Container(
                  height: double.infinity,
                  decoration: const BoxDecoration(
                      color: Color(0xff003656),
                      borderRadius: BorderRadius.only(
                          topRight: Radius.circular(6),
                          bottomRight: Radius.circular(6))),
                  child: Row(
                    children: [
                      SizedBox(
                          width: _userNameWidth,
                          child: Text(
                            data.name,
                            textAlign: TextAlign.center,
                          )),
                      verticalDivider(),
                      Expanded(
                          child: Text(
                        data.routeName,
                        textAlign: TextAlign.center,
                      )),
                      verticalDivider(),
                      SizedBox(
                          width: _userResultWidth,
                          child: Text(
                            switch(data.state){
                              GameState.processing=>'进行中',
                              GameState.finish=>'完赛',
                            GameState.unFinish=>'退赛'
                            },
                            textAlign: TextAlign.center,
                          )),
                      verticalDivider(),
                      SizedBox(
                          width: _userTimeWidth,
                          child: Text(
                            data.duration.toMinSecondString(),
                            textAlign: TextAlign.center,
                          )),
                      verticalDivider(),
                      Expanded(
                          child: Text(
                        data.distance.toString(),
                        textAlign: TextAlign.center,
                      )),
                      verticalDivider(),
                      Expanded(
                          child: Container(
                              margin: const EdgeInsets.only(left: 8, right: 8),
                              alignment: Alignment.center,
                              height: 18,
                              decoration: BoxDecoration(
                                  color: data.pace.color,
                                  borderRadius: BorderRadius.circular(9)),
                              child: Text(
                                data.pace.toString(),
                                textAlign: TextAlign.center,
                              ))),
                      verticalDivider(),
                      Container(
                          alignment: Alignment.center,
                          width: _userFlagWidth,
                          child: Icon(Icons.flag, color: data.flag.color)),
                    ],
                  ),
                ))
              ],
            )));
  }

  Widget verticalDivider({bool show = true}) {
    return VerticalDivider(
      width: 3,
      indent: 14,
      endIndent: 14,
      color: show ? Colors.white : Colors.transparent,
    );
  }

  static const _userIndexWidth = 56.0;
  static const _userNameWidth = 84.0;
  static const _userResultWidth = 62.0;
  static const _userTimeWidth = 92.0;
  static const _cardHeight = 45.0;
  static const _userFlagWidth = 52.0;
}

enum GameState {
  processing,
  finish,
  unFinish,
}

class RankUserInfo {
  var id = 0;
  var name = '';
  var routeName = '';
  var state = GameState.processing;
  var duration = 0.seconds;
  var distance = 0.meter;
  var startAt = DateTime(2000);

  Pace get pace => Pace(distance, duration);
  var flag = Flag.red;
}

class RankActiveInfo {
  var id = 0;
  var name = '';
  var userList = <RankUserInfo>[];
}

extension UserRankInfoExt on ToOrienteerRankInfo {
  RankUserInfo toModel() {
    return RankUserInfo()
      ..id = oId
      ..name = oName
      ..routeName = courseName
      ..state = switch (state) {
        1 => GameState.finish,
        2 => GameState.processing,
        _ => GameState.unFinish
      }
      ..startAt = startAt.toModel()
      ..duration = duration.toModel()
      ..distance = distance.meter;
  }
}
