import 'dart:async';
import 'dart:math' as math;

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


class Carousel3D extends StatefulWidget {
  final List<Widget> items;
  final double height;
  final Duration autoPlayDuration;
  final Function(int)? onItemChanged;
  final bool showControls;

  const Carousel3D({
    super.key,
    required this.items,
    this.height = 220,
    this.autoPlayDuration = const Duration(seconds: 4),
    this.onItemChanged,
    this.showControls = true,
  });

  @override
  State<Carousel3D> createState() => _Carousel3DState();
}

class _Carousel3DState extends State<Carousel3D> with SingleTickerProviderStateMixin {
  late final AnimationController _controller;
  Timer? _autoPlayTimer;
  int _currentIndex = 0;
  int _targetIndex = 0;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 150),
    );
    _startAutoPlay();
  }

  void _startAutoPlay() {
    _autoPlayTimer?.cancel();
    _autoPlayTimer = Timer.periodic(widget.autoPlayDuration, (timer) {
      if (mounted) {
        _goToIndex((_currentIndex + 1) % widget.items.length);
      }
    });
  }

  void _goToIndex(int index) {
    if (index == _currentIndex) return;

    setState(() {
      _targetIndex = index;
    });

    _controller.forward(from: 0).then((_) {
      setState(() {
        _currentIndex = _targetIndex;
      });
      widget.onItemChanged?.call(_currentIndex);
      _controller.reset();
    });
    _startAutoPlay();
  }

  void _nextPage() {
    _goToIndex((_currentIndex + 1) % widget.items.length);
  }

  void _previousPage() {
    _goToIndex((_currentIndex - 1 + widget.items.length) % widget.items.length);
  }


  @override
  void dispose() {
    _autoPlayTimer?.cancel();
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;

    return Column(
      children: [
        SizedBox(
          height: widget.height,
          child: AnimatedBuilder(
            animation: _controller,
            builder: (context, child) {
              return Stack(
                alignment: Alignment.center,
                children: List.generate(widget.items.length, (index) {
                  final double currentRelativePos = (index - _currentIndex).toDouble();
                  final double targetRelativePos = (index - _targetIndex).toDouble();
                  final double relativePos = Tween<double>(
                    begin: currentRelativePos,
                    end: targetRelativePos,
                  ).transform(CurvedAnimation(parent: _controller, curve: Curves.easeInOutCubic).value);

                  final bool isGrayscale = relativePos != 0;
                  final double absRelativePos = relativePos.abs();

                  final double scale = (1 - (absRelativePos * 0.15)).clamp(0.0, 1.0);
                  final double translateX = relativePos * -30.0;
                  final double translateZ = absRelativePos * -100.0;
                  final double opacity = (1 - (absRelativePos * 0.3)).clamp(0.0, 1.0);

                  Matrix4 transform = Matrix4.identity()
                    ..setEntry(3, 2, 0.001)
                    ..translate(translateX, 0.0, translateZ)
                    ..scale(scale);

                  return Transform(
                    transform: transform,
                    alignment: Alignment.center,
                    child: Opacity(
                      opacity: opacity,
                      child: GestureDetector(
                        onTap: () {
                           if (relativePos != 0) {
                              _goToIndex(index);
                           }
                        },
                        child: Container(
                           width: screenWidth * 0.7,
                           decoration: BoxDecoration(
                             borderRadius: BorderRadius.circular(12),
                             boxShadow: [
                               BoxShadow(
                                 color: Colors.black.withOpacity(isGrayscale ? 0.1 : 0.25),
                                 spreadRadius: 2,
                                 blurRadius: 10,
                                 offset: const Offset(0, 5),
                               ),
                             ],
                           ),
                           child: ClipRRect(
                             borderRadius: BorderRadius.circular(12),
                             child: ColorFiltered(
                               colorFilter: isGrayscale
                                   ? const ColorFilter.matrix([
                                       0.2126, 0.7152, 0.0722, 0, 0,
                                       0.2126, 0.7152, 0.0722, 0, 0,
                                       0.2126, 0.7152, 0.0722, 0, 0,
                                       0,      0,      0,      1, 0,
                                     ])
                                   : const ColorFilter.mode(
                                       Colors.transparent,
                                       BlendMode.multiply,
                                     ),
                               child: widget.items[index],
                             ),
                           ),
                         ),
                      ),
                    ),
                  );
                }).toList()
                  ..sort((a, b) {
                    final transformA = a.transform;
                    final transformB = b.transform;
                    return transformA.getTranslation().z.compareTo(transformB.getTranslation().z);
                  }),
              );
            },
          ),
        ),
        if (widget.showControls) ...[
          const SizedBox(height: 4),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              IconButton(
                icon: SvgPicture.asset('lib/assets/icons/Arrow Right.svg'),
                iconSize: 40,
                onPressed: _previousPage,
              ),
              const SizedBox(width: 20),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: List.generate(widget.items.length, (index) {
                  return AnimatedContainer(
                    duration: const Duration(milliseconds: 150),
                    margin: const EdgeInsets.symmetric(horizontal: 3),
                    width: _currentIndex == index ? 9.0 : 7.0,
                    height: _currentIndex == index ? 9.0 : 7.0,
                    decoration: BoxDecoration(
                      color: _currentIndex == index
                          ? const Color.fromARGB(255, 0, 126, 167)
                          : Colors.grey.withOpacity(0.5),
                      shape: BoxShape.circle,
                    ),
                  );
                }),
              ),
              const SizedBox(width: 20),
              IconButton(
                icon: SvgPicture.asset('lib/assets/icons/Click Area.svg'),
                iconSize: 40,
                onPressed: _nextPage,
              ),
            ],
          ),
        ],
      ],
    );
  }
}