import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:rasadyar_core/presentation/widget/list_view/r_paginated_list_view.dart';
import 'package:rasadyar_core/utils/network/resource.dart';

import 'r_shimmer_list.dart';

class RListView<T> extends StatelessWidget {
  final ListType type;
  final Axis scrollDirection;
  final bool reverse;
  final ScrollController? controller;
  final bool? primary;
  final ScrollPhysics? physics;
  final ScrollBehavior? scrollBehavior;
  final bool shrinkWrap;
  final Key? center;
  final double? cacheExtent;
  final int? semanticChildCount;
  final int itemCount;
  final DragStartBehavior dragStartBehavior;
  final ScrollViewKeyboardDismissBehavior? keyboardDismissBehavior;
  final String? restorationId;
  final Clip clipBehavior;
  final HitTestBehavior hitTestBehavior;
  final Widget? prototypeItem;
  final EdgeInsetsGeometry? padding;
  final double? itemExtent;
  final ItemExtentBuilder? itemExtentBuilder;
  final ChildIndexGetter? findChildIndexCallback;
  final NullableIndexedWidgetBuilder itemBuilder;
  final IndexedWidgetBuilder? separatorBuilder;
  final bool addAutomaticKeepAlives;
  final bool addRepaintBoundaries;
  final bool addSemanticIndexes;
  final Widget loadingWidget;
  final Widget emptyWidget;
  final Widget errorWidget;
  final Resource<List<T>> resource;
  final Future<void> Function()? onRefresh;

  const RListView.builder({
    super.key,
    this.scrollDirection = Axis.vertical,
    this.reverse = false,
    this.controller,
    this.primary,
    this.physics,
    this.scrollBehavior,
    this.shrinkWrap = false,
    this.center,
    this.cacheExtent,
    this.semanticChildCount,
    required this.itemCount,
    this.dragStartBehavior = DragStartBehavior.start,
    this.keyboardDismissBehavior,
    this.restorationId,
    this.clipBehavior = Clip.hardEdge,
    this.hitTestBehavior = HitTestBehavior.opaque,
    this.prototypeItem,
    this.padding,
    this.itemExtent,
    this.itemExtentBuilder,
    this.findChildIndexCallback,
    required this.itemBuilder,
    this.addAutomaticKeepAlives = true,
    this.addRepaintBoundaries = true,
    this.addSemanticIndexes = true,
    this.loadingWidget = const RShimmerList(isSeparated: true),
    this.emptyWidget = const Center(child: Text("هیچ آیتمی یافت نشد")),
    this.errorWidget = const Center(child: CircularProgressIndicator()),
    required this.resource,
    this.onRefresh,
  }) : type = ListType.builder,
       separatorBuilder = null;

  const RListView.separated({
    super.key,
    this.scrollDirection = Axis.vertical,
    this.reverse = false,
    this.controller,
    this.primary,
    this.physics,
    this.scrollBehavior,
    this.shrinkWrap = false,
    this.center,
    this.cacheExtent,
    this.semanticChildCount,
    required this.itemCount,
    this.dragStartBehavior = DragStartBehavior.start,
    this.keyboardDismissBehavior,
    this.restorationId,
    this.clipBehavior = Clip.hardEdge,
    this.hitTestBehavior = HitTestBehavior.opaque,
    this.prototypeItem,
    this.padding,
    this.itemExtent,
    this.itemExtentBuilder,
    this.findChildIndexCallback,
    required this.itemBuilder,
    required this.separatorBuilder,
    this.addAutomaticKeepAlives = true,
    this.addRepaintBoundaries = true,
    this.addSemanticIndexes = true,
    this.loadingWidget = const Center(child: CircularProgressIndicator()),
    this.emptyWidget = const Center(child: Text("هیچ آیتمی یافت نشد")),
    this.errorWidget = const Center(child: CircularProgressIndicator()),
    required this.resource,
    this.onRefresh,
  }) : type = ListType.separated;

  @override
  Widget build(BuildContext context) {
    switch (resource.status) {
      case ResourceStatus.initial:
      case ResourceStatus.loading:
        return loadingWidget;

      case ResourceStatus.error:
        return errorWidget;

      case ResourceStatus.empty:
        return emptyWidget;

      case ResourceStatus.success:
        if (resource.data?.isEmpty ?? true) {
          return emptyWidget;
        }

        final list = type == ListType.builder
            ? ListView.builder(
                key: key,
                scrollDirection: scrollDirection,
                reverse: reverse,
                controller: controller,
                primary: primary,
                physics: physics,
                shrinkWrap: shrinkWrap,
                padding: padding,
                itemExtent: itemExtent,
                itemBuilder: itemBuilder,
                itemCount: itemCount,
                prototypeItem: prototypeItem,
                itemExtentBuilder: itemExtentBuilder,
                findChildIndexCallback: findChildIndexCallback,
                addAutomaticKeepAlives: addAutomaticKeepAlives,
                addRepaintBoundaries: addRepaintBoundaries,
                addSemanticIndexes: addSemanticIndexes,
                cacheExtent: cacheExtent,
                semanticChildCount: semanticChildCount,
                dragStartBehavior: dragStartBehavior,
                keyboardDismissBehavior: keyboardDismissBehavior,
                restorationId: restorationId,
                clipBehavior: clipBehavior,
              )
            : ListView.separated(
                key: key,
                scrollDirection: scrollDirection,
                reverse: reverse,
                controller: controller,
                primary: primary,
                physics: physics,
                shrinkWrap: shrinkWrap,
                padding: padding,
                itemBuilder: itemBuilder,
                separatorBuilder: separatorBuilder!,
                itemCount: itemCount,
                findChildIndexCallback: findChildIndexCallback,
                addAutomaticKeepAlives: addAutomaticKeepAlives,
                addRepaintBoundaries: addRepaintBoundaries,
                addSemanticIndexes: addSemanticIndexes,
                cacheExtent: cacheExtent,
                dragStartBehavior: dragStartBehavior,
                keyboardDismissBehavior: keyboardDismissBehavior,
                restorationId: restorationId,
                clipBehavior: clipBehavior,
              );

        return onRefresh != null ? RefreshIndicator(onRefresh: onRefresh!, child: list) : list;
    }
  }

  RListView._({
    required this.type,
    required this.scrollDirection,
    required this.reverse,
    required this.controller,
    required this.primary,
    required this.physics,
    required this.scrollBehavior,
    required this.shrinkWrap,
    required this.center,
    required this.cacheExtent,
    required this.semanticChildCount,
    required this.itemCount,
    required this.dragStartBehavior,
    required this.keyboardDismissBehavior,
    required this.restorationId,
    required this.clipBehavior,
    required this.hitTestBehavior,
    required this.prototypeItem,
    required this.padding,
    required this.itemExtent,
    required this.itemExtentBuilder,
    required this.findChildIndexCallback,
    required this.itemBuilder,
    required this.separatorBuilder,
    required this.addAutomaticKeepAlives,
    required this.addRepaintBoundaries,
    required this.addSemanticIndexes,
    required this.loadingWidget,
    required this.emptyWidget,
    required this.errorWidget,
    required this.resource,
    required this.onRefresh,
  });
}
