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/category.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/models/view/app_bar_data.dart';
import 'package:didvan/views/radar/radar_state.dart';
import 'package:didvan/views/widgets/categories_gird.dart';
import 'package:didvan/views/widgets/categories_list.dart';
import 'package:didvan/views/widgets/date_picker_button.dart';
import 'package:didvan/views/widgets/didvan/scaffold.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/views/widgets/overview/radar.dart';
import 'package:didvan/views/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) => DidvanScaffold(
        padding: EdgeInsets.zero,
        appBarData: AppBarData(
          hasBack: true,
          hasElevation: false,
          title: 'پویش‌های افق',
        ),
        children: [
          SizedBox(
            height: MediaQuery.of(context).size.height,
            child: Stack(
              children: [
                CustomScrollView(
                  physics: _isAnimating
                      ? const NeverScrollableScrollPhysics()
                      : const ClampingScrollPhysics(),
                  controller: _scrollController,
                  slivers: [
                    if (!state.filtering &&
                        !state.searching &&
                        state.appState != AppState.failed)
                      const SliverToBoxAdapter(
                        child: SizedBox(height: 320),
                      ),
                    if (state.appState != AppState.failed)
                      SliverPadding(
                        padding: const EdgeInsets.only(
                            right: 16, bottom: 20, top: 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.titleMedium,
                                color: Theme.of(context).colorScheme.title,
                              ),
                            ),
                          ),
                        ),
                      ),
                    if (state.isColapsed || state.searching || state.filtering)
                      const SliverToBoxAdapter(
                        child: SizedBox(
                          height: 160,
                        ),
                      ),
                    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: state.page + 1);
                        }
                        index -= 2;
                        if (index >= state.radars.length) {
                          return RadarOverview.placeholder;
                        }
                        final radar = state.radars[index];
                        return RadarOverview(
                          radar: radar,
                          onMarkChanged: state.changeMark,
                          onLikedChanged: state.changeLike,
                          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),
                      ),
                    const SliverToBoxAdapter(
                      child: SizedBox(
                        height: 100,
                      ),
                    ),
                  ],
                ),
                if (state.appState != AppState.failed)
                  CategoriesRow1(
                    topPadding: 212,
                    rightPadding: 124,
                    onSelected: _onCategorySelected,
                    categories: state.categories,
                    isColapsed:
                        state.isColapsed || state.searching || state.filtering,
                  ),
                if (state.appState != AppState.failed)
                  CategoriesRow2(
                    categories: state.categories,
                    isColapsed:
                        state.isColapsed || state.searching || state.filtering,
                    onSelected: _onCategorySelected,
                  ),
                if (state.appState != AppState.failed &&
                    !state.searching &&
                    !state.filtering)
                  CategoriesList(
                    top: 60,
                    categories: state.categories,
                    isColapsed:
                        state.isColapsed || state.searching || state.filtering,
                    onSelected: (_) => state.getRadars(page: 1),
                    selectedCats: state.selectedCats,
                  ),
                if (state.appState != AppState.failed)
                  Container(
                    padding: const EdgeInsets.all(16),
                    decoration: BoxDecoration(
                      color: Theme.of(context).colorScheme.surface,
                      borderRadius: const BorderRadius.vertical(
                        bottom: Radius.circular(12),
                      ),
                    ),
                    child: SearchField(
                      focusNode: _focusNode,
                      isFiltered: state.filtering,
                      title: 'پویش‌های افق',
                      onChanged: _onChanged,
                      onFilterButtonPressed: _showFilterBottomSheet,
                    ),
                  ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  void _onCategorySelected(CategoryData category) {
    final state = context.read<RadarState>();
    state.selectedCats.clear();
    if (category.id != 0) {
      state.selectedCats.add(category);
    }
    state.getRadars(page: 1);
  }

  void _onChanged(String value) {
    final state = context.read<RadarState>();
    if (value.length < 3 && 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(context).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.bodyMedium,
              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.category_regular,
              style: Theme.of(context).textTheme.bodyMedium,
            ),
            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].label,
                      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();
  }
}
