// ignore_for_file: prefer_const_constructors

import 'dart:async';
import 'dart:math';

import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/requests/radar.dart';
import 'package:didvan/models/view/action_sheet_data.dart';
import 'package:didvan/views/home/radar/radar_state.dart';
import 'package:didvan/views/home/radar/widgets/categories_gird.dart';
import 'package:didvan/views/home/radar/widgets/categories_list.dart';
import 'package:didvan/views/home/widgets/date_picker_button.dart';
import 'package:didvan/views/home/widgets/logo_app_bar.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/views/home/widgets/radar_overview.dart';
import 'package:didvan/views/home/widgets/search_field.dart';
import 'package:didvan/views/widgets/animated_visibility.dart';
import 'package:didvan/views/widgets/didvan/checkbox.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/item_title.dart';
import 'package:didvan/views/widgets/state_handlers/empty_result.dart';
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

  @override
  State<Radar> createState() => _RadarState();
}

class _RadarState extends State<Radar> {
  final ScrollController _scrollController = ScrollController();
  final _focusNode = FocusNode();

  bool _isAnimating = false;

  Timer? _timer;

  @override
  void initState() {
    _scrollController.addListener(() {
      _handleAnimations();
    });
    final state = context.read<RadarState>();
    state.addListener(() {
      if (state.shouldColapse && mounted) {
        _handleAnimations(true);
        state.shouldColapse = false;
      }
    });
    state.init();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Consumer<RadarState>(
      builder: (context, state, child) => Stack(
        children: [
          CustomScrollView(
            physics: _isAnimating
                ? const NeverScrollableScrollPhysics()
                : const ClampingScrollPhysics(),
            controller: _scrollController,
            slivers: [
              const SliverToBoxAdapter(child: LogoAppBar()),
              if (state.appState != AppState.failed)
                SliverPadding(
                  padding: const EdgeInsets.only(
                    left: 16,
                    right: 16,
                    bottom: 16,
                  ),
                  sliver: SliverToBoxAdapter(
                    child: SearchField(
                      focusNode: _focusNode,
                      isFiltered: state.filtering,
                      title: 'رادار',
                      onChanged: _onChanged,
                      onFilterButtonPressed: _showFilterBottomSheet,
                    ),
                  ),
                ),
              if (!state.filtering &&
                  !state.searching &&
                  state.appState != AppState.failed)
                const SliverToBoxAdapter(
                  child: SizedBox(height: 276),
                ),
              if (state.appState != AppState.failed)
                SliverPadding(
                  padding: const EdgeInsets.only(right: 16, bottom: 20),
                  sliver: SliverToBoxAdapter(
                    child: Align(
                      alignment: Alignment.centerRight,
                      child: AnimatedVisibility(
                        isVisible: !state.isColapsed &&
                            !state.searching &&
                            !state.filtering,
                        duration: DesignConfig.lowAnimationDuration,
                        child: DidvanText(
                          'آخرین رصد',
                          style: Theme.of(context).textTheme.subtitle1,
                          color: Theme.of(context).colorScheme.title,
                        ),
                      ),
                    ),
                  ),
                ),
              SliverStateHandler<RadarState>(
                onRetry: () => state.getRadars(page: state.page),
                state: state,
                itemPadding: const EdgeInsets.only(
                  bottom: 20,
                  left: 16,
                  right: 16,
                ),
                enableEmptyState: state.radars.isEmpty,
                emptyState: Padding(
                  padding: const EdgeInsets.only(bottom: 120),
                  child:
                      EmptyResult(onNewSearch: () => _focusNode.requestFocus()),
                ),
                placeholder: RadarOverview.placeholder,
                builder: (context, state, index) {
                  index += 2;
                  if (index % 15 == 0 && state.lastPage != state.page) {
                    state.getRadars(page: index ~/ 15 + 1);
                  }
                  index -= 2;
                  if (index >= state.radars.length) {
                    return RadarOverview.placeholder;
                  }
                  final radar = state.radars[index];
                  return RadarOverview(
                    radar: radar,
                    onMarkChanged: (id, value) => state.changeMark(id, value),
                    onCommentsChanged: (id, count) =>
                        state.onCommentsChanged(id, count),
                    radarRequestArgs: RadarRequestArgs(
                      page: state.page,
                      categories:
                          List.from(state.selectedCats.map((cat) => cat.id)),
                      endDate: state.endDate,
                      isSingleItem: false,
                      search: state.search,
                      startDate: state.startDate,
                    ),
                  );
                },
                childCount: state.radars.length +
                    (state.lastPage == state.page ? 0 : 3),
              ),
              if (state.radars.length == 1)
                const SliverToBoxAdapter(
                  child: SizedBox(height: 320),
                ),
            ],
          ),
          if (state.appState != AppState.failed) CategoriesRow1(),
          if (state.appState != AppState.failed) CategoriesRow2(),
          if (state.appState != AppState.failed &&
              !state.searching &&
              !state.filtering)
            CategoriesList(),
        ],
      ),
    );
  }

  void _onChanged(String value) {
    final state = context.read<RadarState>();
    if (value.length < 4 && value.isNotEmpty || state.lastSearch == value) {
      return;
    }
    _timer?.cancel();
    _timer = Timer(const Duration(seconds: 1), () {
      state.search = value;
      state.getRadars(page: 1);
    });
  }

  void _handleAnimations([bool forceAnimate = false]) async {
    final state = context.read<RadarState>();
    if (_isAnimating || state.filtering || state.searching) return;
    final double position = _scrollController.offset;
    if (position > 5 && !state.isColapsed || forceAnimate) {
      state.isScrolled = true;
      _isAnimating = true;
      setState(() {});
      await _scrollController.animateTo(
        380,
        duration: DesignConfig.mediumAnimationDuration,
        curve: Curves.easeIn,
      );
      _isAnimating = false;
      setState(() {});
    } else if (position <
            min(_scrollController.position.maxScrollExtent, 380) &&
        state.isColapsed) {
      state.isScrolled = false;
      _isAnimating = true;
      setState(() {});
      await _scrollController.animateTo(
        0,
        duration: DesignConfig.mediumAnimationDuration,
        curve: Curves.easeIn,
      );
      _isAnimating = false;
      setState(() {});
    }
  }

  Future<void> _showFilterBottomSheet() async {
    final state = context.read<RadarState>();
    await ActionSheetUtils.showBottomSheet(
      data: ActionSheetData(
        title: 'فیلتر جستجو',
        smallDismissButton: true,
        titleIcon: DidvanIcons.filter_regular,
        dismissTitle: 'حذف فیلتر',
        confrimTitle: 'نمایش نتایج',
        onDismissed: () => state.resetFilters(false),
        onConfirmed: () => state.getRadars(page: 1),
        content: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            ItemTitle(
              title: 'تاریخ رادار',
              style: Theme.of(context).textTheme.bodyText2,
              icon: DidvanIcons.calendar_range_regular,
            ),
            const SizedBox(height: 8),
            StatefulBuilder(
              builder: (context, setState) => Row(
                children: [
                  DatePickerButton(
                    initialValue: state.startDate,
                    emptyText: 'از تاریخ',
                    onPicked: (date) => setState(() => state.startDate = date),
                    lastDate: state.endDate,
                  ),
                  const SizedBox(width: 8),
                  DatePickerButton(
                    initialValue: state.endDate,
                    emptyText: 'تا تاریخ',
                    onPicked: (date) => setState(() => state.endDate = date),
                    firstDate: state.startDate,
                  ),
                ],
              ),
            ),
            const SizedBox(height: 28),
            ItemTitle(
              title: 'دسته بندی',
              icon: DidvanIcons.radar_regular,
              style: Theme.of(context).textTheme.bodyText2,
            ),
            const SizedBox(height: 12),
            Wrap(
              children: [
                for (var i = 0; i < state.categories.length; i++)
                  SizedBox(
                    width: (MediaQuery.of(context).size.width - 40) / 2,
                    child: DidvanCheckbox(
                      title: state.categories[i].title,
                      value: state.selectedCats.contains(state.categories[i]),
                      onChanged: (value) {
                        if (value) {
                          state.selectedCats.add(state.categories[i]);
                          return;
                        }
                        state.selectedCats.remove(state.categories[i]);
                      },
                    ),
                  ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _focusNode.dispose();
    _scrollController.dispose();
    super.dispose();
  }
}
