library easy_stepper;
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'components/base_step.dart';
import 'components/custom_line.dart';
class CustomStepper extends StatefulWidget {
  final List<StepModel> steps;
  final OnStepReached ?onStepReached;
  final Color ?unreachedStepBackgroundColor;
  final Color ?unreachedStepTextColor;
  final Color ?unreachedStepIconColor;
  final Color ?unreachedStepBorderColor;
  final BorderType ?unreachedStepBorderType;
  final Color activeStepBackgroundColor;
  final Color? activeStepTextColor;
  final Color activeStepIconColor;
  final Color activeStepBorderColor;
  final BorderType ?activeStepBorderType;
  final Color finishedStepBackgroundColor;
  final Color ?finishedStepBorderColor;
  final Color ?finishedStepTextColor;
  final Color ?finishedStepIconColor;
  final BorderType ?finishedStepBorderType;
  final double stepRadius;
  final int activeStep;
  final int ?maxReachedStep;
  final Set<int>? reachedSteps;
  final AlignmentGeometry alignment;
  final double internalPadding;
  final EdgeInsetsGeometry padding;
  final bool titlesAreLargerThanSteps;
  final Curve stepAnimationCurve;
  final Duration stepAnimationDuration;
  final double borderThickness;
  final StepShape stepShape;
  final double ?stepBorderRadius;
  final bool showStepBorder;
  final bool showScrollbar;
  final bool fitWidth;
  final LineStyle ?lineStyle;

  const CustomStepper({
    Key? key,
    required this.activeStep,
    required this.steps,
    this.reachedSteps,
    this.maxReachedStep,
    this.onStepReached,
    this.unreachedStepBackgroundColor,
    this.unreachedStepTextColor,
    this.unreachedStepIconColor,
    this.unreachedStepBorderColor,
    this.activeStepTextColor,
    this.activeStepIconColor=AppColor.primary10,
    this.activeStepBackgroundColor=AppColor.primary10,
    this.activeStepBorderColor=AppColor.primary10,
    this.finishedStepBackgroundColor=AppColor.primary10,
    this.finishedStepBorderColor,
    this.finishedStepIconColor,
    this.stepRadius = 20,
    this.alignment = Alignment.center,
    this.fitWidth = true,
    this.showScrollbar = false,
    this.padding=EdgeInsetsDirectional.zero,
    this.titlesAreLargerThanSteps = false,
    this.internalPadding = 8,
    this.stepAnimationCurve = Curves.linear,
    this.stepAnimationDuration = const Duration(seconds: 1),
    this.borderThickness = 1,
    this.stepShape = StepShape.circle,
    this.stepBorderRadius,
    this.unreachedStepBorderType,
    this.activeStepBorderType,
    this.finishedStepBorderType,
    this.showStepBorder = false,
    this.lineStyle, this.finishedStepTextColor,
  })  : assert(maxReachedStep == null || reachedSteps == null,
            'only "maxReachedStep" or "reachedSteps" allowed'),
        super(key: key);

  @override
  State<CustomStepper> createState() => _CustomStepperState();
}

class _CustomStepperState extends State<CustomStepper> {
  late ScrollController _scrollController;
   int ?_selectedIndex;
   LineStyle? lineStyle;
   EdgeInsetsGeometry? _padding;

  @override
  void initState() {
    lineStyle = widget.lineStyle ?? const LineStyle();
    _selectedIndex = widget.activeStep;
    _scrollController = ScrollController();

    _padding = const EdgeInsetsDirectional.all(10);
      if (widget.steps.any((element) => element.topTitle??false)) {
        _padding = _padding!.add(const EdgeInsetsDirectional.only(top: 45));
      }
      if (widget.titlesAreLargerThanSteps) {
        _padding = _padding!.add(EdgeInsetsDirectional.symmetric(
            horizontal: lineStyle!.lineLength / 2));
    }
    _padding!.add(widget.padding);

    super.initState();
  }

  @override
  void didUpdateWidget(CustomStepper oldWidget) {
    super.didUpdateWidget(oldWidget);

    // Verify that the active step falls within a valid range.
    if (widget.activeStep >= 0 && widget.activeStep < widget.steps.length) {
      _selectedIndex = widget.activeStep;
    }
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    lineStyle = widget.lineStyle ?? const LineStyle();

    return Align(
      alignment: widget.alignment,
      child: NotificationListener<OverscrollIndicatorNotification>(
        onNotification: (OverscrollIndicatorNotification overscroll) {
          overscroll.disallowIndicator();
          return false;
        },
        child: FittedBox(
                    fit: widget.fitWidth ? BoxFit.fitWidth : BoxFit.none,
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: _buildEasySteps(),
                    ),
                  )
      ),
    );
  }

  List<Widget> _buildEasySteps() {
    return List.generate(widget.steps.length, (index) {
      return Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                _buildStep(index),
                _buildLine(index, Axis.horizontal),
              ],
            );
    });
  }

  BaseStep _buildStep(int index) {
    final step = widget.steps[index];
    return BaseStep(
      step: step,
      radius: widget.stepRadius,
      isActive: index == widget.activeStep,
      isFinished: widget.reachedSteps != null
          ? index < widget.activeStep && widget.reachedSteps!.contains(index)
          : index < widget.activeStep,
      isUnreached: index > widget.activeStep,
      isAlreadyReached: widget.reachedSteps != null
          ? widget.reachedSteps!.contains(index)
          : widget.maxReachedStep != null
              ? index <= widget.maxReachedStep!
              : false,
      activeStepBackgroundColor: widget.activeStepBackgroundColor,
      activeStepBorderColor: widget.activeStepBorderColor,
      activeTextColor: widget.activeStepTextColor??AppColor.neutral100,
      activeIconColor: widget.activeStepIconColor,
      unreachedBackgroundColor: widget.unreachedStepBackgroundColor??AppColor.white10,
      unreachedBorderColor: widget.unreachedStepBorderColor??AppColor.neutral100,
      unreachedTextColor: widget.unreachedStepTextColor??AppColor.neutral100,
      unreachedIconColor: widget.unreachedStepIconColor??AppColor.neutral100,
      padding: max(widget.internalPadding, 0),
      stepRadius: widget.stepBorderRadius??10,
      showStepBorder: widget.showStepBorder,
      lineLength: lineStyle!.lineLength,
      enabled: widget.steps[index].enabled??false,
    );
  }

  // BorderType _handleBorderType(int index) {
  //   if (index == widget.activeStep) {
  //     //Active Step
  //     return widget.activeStepBorderType ?? widget.defaultStepBorderType;
  //   } else if (index > widget.activeStep) {
  //     //Unreached Step
  //     return widget.unreachedStepBorderType ?? widget.defaultStepBorderType;
  //   } else if (index < widget.activeStep) {
  //     //Finished Step
  //     return widget.finishedStepBorderType ?? widget.defaultStepBorderType;
  //   } else {
  //     return widget.defaultStepBorderType;
  //   }
  // }

  Color _getLineColor(int index) {
    Color ?preferredColor;
    if (index == widget.activeStep) {
      //Active Step
      preferredColor = lineStyle!.activeLineColor??AppColor.primary10;
    } else if (index > widget.activeStep) {
      //Unreached Step
      preferredColor = lineStyle!.unreachedLineColor??AppColor.primary10;
    } else if (index < widget.activeStep) {
      //Finished Step
      preferredColor = lineStyle!.finishedLineColor??AppColor.primary10;
    }

    return preferredColor ??
        lineStyle!.defaultLineColor ??
        Theme.of(context).colorScheme.primary;
  }

  Widget _buildLine(int index, Axis axis) {
    return index < widget.steps.length - 1
        ? Column(
            children: [
              Padding(
                padding: EdgeInsets.only(
                  top: axis == Axis.horizontal
                      ? (widget.stepRadius - lineStyle!.lineThickness)
                      : 0,
                ),
                child: _buildBaseLine(index, axis),
              ),
              if (axis == Axis.horizontal) ...[
                const SizedBox(height: 5),
                SizedBox(
                  width: lineStyle!.lineLength,
                  child: widget.steps[index].customLineWidget ??
                      Text(
                        widget.steps[index].lineText??'',
                        maxLines: 3,
                        textAlign: TextAlign.center,
                        style: Theme.of(context).textTheme.labelSmall,
                      ),
                ),
              ],
            ],
          )
        : const Offstage();
  }

  EasyLine _buildBaseLine(int index, Axis axis) {
    return EasyLine(
      length: lineStyle!.lineLength,
      color: _getLineColor(index),
      thickness: lineStyle!.lineThickness,
      spacing: lineStyle!.lineSpace,
      width: lineStyle!.lineWidth,
      axis: axis,
      lineType:
          index > widget.activeStep - 1 && lineStyle!.unreachedLineType != null
              ? lineStyle!.unreachedLineType
              : lineStyle!.lineType,
    );
  }
}
