import 'dart:developer';
import 'dart:math' as math;

import 'package:auto_route/auto_route.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:mnemo_cards/managers/audio_player.dart';
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
import 'package:rxdart/rxdart.dart';

import '../../di/locator.dart';
import 'scroll_physics.dart';
import 'test_complete_widget.dart';
import 'test_progress_widget.dart';
import 'test_widgets/input_buttons_test.dart';
import 'test_widgets/simple_test.dart';

@RoutePage()
class TestPage extends StatefulWidget {
  final String testId;

  @override
  State<StatefulWidget> createState() => _TestPageState();

  TestPage(this.testId);
}

class _TestPageState extends State<TestPage> {
  PageController get pageController => locator.testManager.pageController;

  int? lastSkipIndex;
  int? _lastAudioQuestionId;

  @override
  void initState() {
    super.initState();
    locator.testManager.setActiveTest(widget.testId);
    locator.testManager.preloadImages(context);
    pageController.addListener(_pageScrollListener);
  }

  @override
  void dispose() {
    pageController.removeListener(_pageScrollListener);
    super.dispose();
  }

  void _pageScrollListener() {
    if (!pageController.hasClients) {
      return;
    }
    final index = pageController.page!.floor();
    print('Current index $index, lastAudio $_lastAudioQuestionId');

    if (index < locator.testManager.questions.length) {
      final question = locator.testManager.questions[index];
      if (question.id != _lastAudioQuestionId) {
        print('AUDIO $_lastAudioQuestionId ${question.id}');
        _lastAudioQuestionId = question.id;
        try {
          AudioPlayer.playAudio((question as dynamic).audio);
        } catch (e, s) {}
      }
    }

    if (index == lastSkipIndex) {
      return;
    }
    print('Will try to skip $index, ${locator.testManager.questions.length}');
    if (index > 0 && index <= locator.testManager.questions.length) {
      final prevId = locator.testManager.questions[index - 1].id!;
      final state = locator.testManager.getState(prevId);
      if (state?.isAnswered == false) {
        print('Skipping $index ${state?.word}');
        locator.testManager.skip(prevId);
        lastSkipIndex = index;
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: StreamBuilder(
          stream: locator.testManager.testHolder.asStream.takeWhileInclusive(
            (state) => state?.questions.isNotEmpty != true,
          ),
          builder: (context, s) {
            if (!s.hasData || s.requireData!.questions.isEmpty) {
              return Scaffold(
                body: Center(
                  child: Text('Загружаю тест...'),
                ),
              );
            }

            WidgetsBinding.instance.addPostFrameCallback((_) {
              _pageScrollListener();
            });

            final keys = List.generate(
              locator.testManager.questions.length,
              (v) =>
                  GlobalKey(debugLabel: locator.testManager.questions[v].word),
            );

            return Scaffold(
              backgroundColor: locator.testManager.color.withOpacity(0.25),
              body: SafeArea(
                child: Builder(builder: (context) {
                  return Column(
                    children: [
                      SizedBox(
                        height:
                            (64.h - 20.h - MediaQuery.of(context).padding.top) /
                                2,
                      ),
                      Padding(
                        padding: EdgeInsets.symmetric(horizontal: 10.0.w),
                        child: const TestProgressWidget(),
                      ),
                      Expanded(
                        child: PageView.builder(
                          physics: RightBlockedScrollPhysics(
                            canScroll: _canScroll,
                          ),
                          controller: locator.testManager.pageController,
                          itemBuilder: (context, index) {
                            if (index > locator.testManager.questions.length) {
                              return null;
                            }
                            if (index == locator.testManager.questions.length) {
                              return TestCompleteWidget(
                                locator.testManager.states,
                                locator.testManager.color,
                              );
                            }
                            final question = locator.testManager.getTest(index);
                            return switch (question.questionType) {
                              TestQuestionType.simple => SimpleTestWidget(
                                  question as SimpleTestQuestionBody,
                                  key: keys[index],
                                ),
                              TestQuestionType.input_buttons =>
                                InputButtonsTestWidget(
                                    question as InputButtonsTestQuestionBody,
                                    key: keys[index]),
                              TestQuestionType.matrix => Container(),
                              TestQuestionType.match => Container(),
                              // TODO: Handle this case.
                              TestQuestionType.undefined =>
                                throw UnimplementedError(),
                            };
                          }.let(
                            (builder) => (c, i) =>
                                builder.call(c, i)?.let((w) => kDebugMode
                                    ? Stack(
                                        children: [
                                          w,
                                          Row(
                                            children: [
                                              Text('$i'),
                                              IconButton(
                                                  onPressed: () {
                                                    locator.testManager
                                                        .pageController
                                                        .animateToPage(
                                                      locator
                                                              .testManager
                                                              .pageController
                                                              .page!
                                                              .toInt() +
                                                          1,
                                                      duration: Duration(
                                                          milliseconds: 500),
                                                      curve: Curves.easeIn,
                                                    );
                                                  },
                                                  icon: Icon(
                                                      Icons.next_plan_outlined))
                                            ],
                                          ),
                                        ],
                                      )
                                    : w),
                          ),
                        ),
                      ),
                    ],
                  );
                }),
              ),
            );
          }),
    );
  }

  bool _canScroll() {
    return locator.testManager.pageController.hasClients &&
        locator.testManager.pageController.page !=
            locator.testManager.questions.length;
  }
}

class _LifeWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      mainAxisSize: MainAxisSize.max,
      children: [
        Icon(Icons.ac_unit_outlined),
        SizedBox(
          width: 2,
        ),
        Text(
          '30',
          style: TextStyle(fontSize: 22),
        )
      ],
    );
  }
}
