import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';

class CarouselSliderWidget<T> extends StatefulWidget {
  final List<T> items;
  final Widget Function(
    BuildContext context,
    T item,
  ) onPageBuilder;
  final bool withNavs;
  final double height;
  final bool autoPlay;
  final bool enableInfiniteScroll;
  final Function()? onLastClick;

  const CarouselSliderWidget({
    super.key,
    required this.items,
    required this.onPageBuilder,
    this.withNavs = false,
    this.onLastClick,
    this.autoPlay = true,
    this.enableInfiniteScroll = true,
    this.height = 200,
  });

  @override
  State<CarouselSliderWidget<T>> createState() =>
      _CarouselSliderWidgetState<T>();
}

class _CarouselSliderWidgetState<T> extends State<CarouselSliderWidget<T>> {
  int activeIndex = 0;
  final CarouselSliderController _controller = CarouselSliderController();

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        CarouselSlider.builder(
          carouselController: _controller,
          itemCount: widget.items.length,
          itemBuilder: (context, index, realIndex) {
            return widget.onPageBuilder(context, widget.items[index]);
          },
          options: CarouselOptions(
            height: widget.height * 0.75,
            autoPlay: widget.autoPlay,
            enableInfiniteScroll: widget.enableInfiniteScroll,
            enlargeCenterPage: true,
            viewportFraction: 0.9,
            onPageChanged: (index, reason) =>
                setState(() => activeIndex = index),
          ),
        ),
        Padding(
          padding: const EdgeInsets.all(16.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Expanded(child: Center(child: buildIndicator())),
              if (widget.withNavs)
                Expanded(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      Opacity(
                        opacity: activeIndex != 0 ? 1 : 0,
                        child: IconButton(
                          icon: const Icon(Icons.arrow_back_ios_new_rounded),
                          onPressed: () => _controller.previousPage(),
                        ),
                      ),
                      Container(
                        padding: EdgeInsets.all(8),
                        decoration: BoxDecoration(
                            shape: BoxShape.circle,
                            color: Theme.of(context).primaryColor),
                        child: InkWell(
                          highlightColor: Theme.of(context).primaryColor,
                          onTap: () {
                            if (activeIndex == widget.items.length - 1) {
                              if (widget.onLastClick != null) {
                                widget.onLastClick!();
                              }
                            } else {
                              _controller.nextPage();
                            }
                          },
                          child: const Icon(Icons.arrow_forward_ios_rounded),
                        ),
                      ),
                    ],
                  ),
                ),
            ],
          ),
        ),
      ],
    );
  }

  Widget buildImage(String urlImage, int index) => Container(
        margin: const EdgeInsets.symmetric(horizontal: 12),
        color: Colors.grey,
        child: Image.network(
          urlImage,
          fit: BoxFit.cover,
        ),
      );

  Widget buildIndicator() => AnimatedSmoothIndicator(
        activeIndex: activeIndex,
        count: widget.items.length,
        effect: ExpandingDotsEffect(
          dotWidth: 10,
          dotHeight: 10,
          activeDotColor: Theme.of(context).primaryColor,
          dotColor: Theme.of(context).colorScheme.onSurface,
        ),
      );
}
