import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../business/news_controller.dart';
import '../../business/scroll_state_controller.dart';
import 'news_grid_item.dart';

// scroll edge listener source:
// https://github.com/jezsung/scroll_edge_listener/blob/main/lib/scroll_edge_listener.dart

class NewsGrid extends ConsumerWidget {
  NewsGrid({super.key});

  final ScrollController scrollController = ScrollController();

  bool get _isBottom =>
      scrollController.position.maxScrollExtent == scrollController.offset;

  bool get _hasScrolledDown => scrollController.offset > 500;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    bool hasScrolledDown = ref.watch(scrollStateControllerProvider);
    final news = ref.watch(newsControllerProvider);

    scrollController.addListener(() {
      if (_isBottom) {
        // make call to fetch next batch of items
        ref.read(newsControllerProvider.notifier).appendPage();
      }
      if (_hasScrolledDown) {
        ref.read(scrollStateControllerProvider.notifier).toggle(true);
      } else {
        ref.read(scrollStateControllerProvider.notifier).toggle(false);
      }
    });

    return Scaffold(
      body: news.when(
        data: (data) {
          return GridView.builder(
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 4,
              childAspectRatio: 1,
            ),
            padding: const EdgeInsets.only(top: 32, left: 64, right: 64),
            controller: scrollController,
            itemCount: data.news.length + 1,
            itemBuilder: (context, index) {
              if (index < data.news.length) {
                // only show stories
                if (data.news[index].type == 'story' &&
                    data.news[index].teaserImage != null) {
                  return NewsGridItem(news: data.news[index]);
                } else {
                  // return empty container for other types
                  return NewsGridItem(news: data.news[index]);
                }
              } else {
                return const Center(
                  child: Padding(
                    padding: EdgeInsets.symmetric(vertical: 24.0),
                    child: CircularProgressIndicator(),
                  ),
                );
              }
            },
          );
        },
        error: (err, st) => Text(
          'ERROR: ${err.toString()}',
        ),
        loading: () => const Center(
          child: CircularProgressIndicator(),
        ),
      ),
      floatingActionButton: Visibility(
        visible: hasScrolledDown,
        child: FloatingActionButton(
          child: const Icon(Icons.arrow_upward),
          onPressed: () {
            scrollController.animateTo(
              0,
              duration: const Duration(seconds: 1),
              curve: Curves.linear,
            );
          },
        ),
      ),
    );
  }
}
