import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

import 'paginator_listener.dart';

typedef RowBuilder = Widget Function(dynamic);
typedef OnScroll = void Function(bool down);

class PaginatorListView<T> extends StatelessWidget {
  final PaginatorListener<T> paginatorListener;
  final RowBuilder rowBuilder;
  final OnScroll onScroll;
  final ScrollController _scrollController;
  final Color color;

  PaginatorListView(
      {Key key,
      this.paginatorListener,
      this.rowBuilder,
      this.onScroll,
      this.color = Colors.blueAccent})
      : _scrollController = ScrollController(),
        assert(paginatorListener != null),
        assert(rowBuilder != null),
        super(key: key) {
    _scrollController.addListener(() async {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        paginatorListener.loadMore();
      }
      if (onScroll != null) {
        var down = _scrollController.position.userScrollDirection ==
            ScrollDirection.forward;
        onScroll(down);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    bool ended = paginatorListener.ended;
    int count = paginatorListener.data.length;
    if (ended) count++;

    return Column(
      children: [
        Expanded(
          child: RefreshIndicator(
            onRefresh: () {
              return paginatorListener.refresh();
            },
            child: ListView.separated(
                separatorBuilder: (context, index) =>
                    Divider(height: 1, color: Colors.black),
                controller: _scrollController,
                scrollDirection: Axis.vertical,
                physics: const AlwaysScrollableScrollPhysics(),
                shrinkWrap: true,
                itemCount: count,
                itemBuilder: (BuildContext context, int index) {
                  if (ended && index == count - 1) {
                    return Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Center(child: Text("No more data")),
                    );
                  }
                  T t = paginatorListener.data[index];
                  return rowBuilder(t);
                }),
          ),
        ),
        paginatorListener.isLoading ? _loadingRow() : Container()
      ],
    );
  }

  Widget _loadingRow() {
    return Container(
      padding: EdgeInsets.all(8),
      color: Colors.transparent,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Column(
            children: [
              CircularProgressIndicator(
                  valueColor: new AlwaysStoppedAnimation<Color>(color)),
              Text(
                "Loading...",
                style: TextStyle(color: color),
              )
            ],
          ),
        ],
      ),
    );
  }
}
