import 'package:account_center/page/account_company/company_auth/widget/common/gesture_tap.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class DatePicker extends StatefulWidget {
  final DateTime? minValue, maxValue, selectData;
  final Function(DateTime select)? onSelect;
  final DateType type;
  final String title;

  const DatePicker(
    this.onSelect, {
    super.key,
    this.selectData,
    this.minValue,
    this.maxValue,
    this.type = DateType.YMD_HM,
    this.title = "请选择",
  });

  @override
  State<DatePicker> createState() => _DatePickerState();
}

class _DatePickerState extends State<DatePicker> {
  var years = <int>[];
  var yearIndex = 0;
  var months = <int>[];
  var monthIndex = 0;
  var days = <int>[];
  var dayIndex = 0;
  var hours = <int>[];
  var hourIndex = 0;
  var minutes = <int>[];
  var minuteIndex = 0;
  var seconds = <int>[];
  var secondIndex = 0;

  /// 默认选择时间
  late DateTime defaultTime;

  FixedExtentScrollController yearController = FixedExtentScrollController();
  FixedExtentScrollController monthController = FixedExtentScrollController();
  FixedExtentScrollController dayController = FixedExtentScrollController();
  FixedExtentScrollController hourController = FixedExtentScrollController();
  FixedExtentScrollController minuteController = FixedExtentScrollController();
  FixedExtentScrollController secondController = FixedExtentScrollController();

  static const int delay = 50;
  int times = 1;
  int midIndex = 0;
  @override
  void initState() {
    defaultTime = widget.selectData ?? DateTime.now();
    var minYear = widget.minValue?.year ?? 1920;
    var maxYear = widget.maxValue?.year ?? 2100;
    years.clear();
    years.addAll(_getRangArray(minYear, maxYear));
    yearIndex = years.indexOf(defaultTime.year);
    Future.delayed(const Duration(milliseconds: delay)).then((value) {
      yearController.jumpToItem(yearIndex);
    });
    _initMonthValue(isInit: true);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 280,
      decoration: const BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.vertical(
          top: Radius.circular(12),
        ),
      ),
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.symmetric(vertical: 12),
            child: Row(
              children: [
                GestureTapWidget(
                  onTap: () {
                    Get.back();
                  },
                  child: const Text('取消'),
                ),
                Expanded(
                  child: Center(
                    child: Text(
                      widget.title,
                      style: const TextStyle(
                        color: Color(0xff344254),
                        fontWeight: FontWeight.w600,
                        fontSize: 16,
                      ),
                    ),
                  ),
                ),
                GestureTapWidget(
                  onTap: () {
                    widget.onSelect?.call(_getSelectDate());
                    Get.back();
                  },
                  child: const Text('确认'),
                ),
              ],
            ),
          ),
          Container(
            color: const Color(0x66E0E6FD),
            height: 1,
            width: double.infinity,
          ),
          Expanded(
              child: Row(
            children: _getViews(),
          ))
        ],
      ),
    );
  }

  DateTime _getSelectDate() {
    switch (widget.type) {
      case DateType.YM:
        return DateTime(years[yearIndex], _getMonth());
      case DateType.YMD:
        return DateTime(years[yearIndex], _getMonth(), _getDay());
      case DateType.YMD_H:
        return DateTime(
          years[yearIndex],
          _getMonth(),
          _getDay(),
          _getHour(),
        );
      case DateType.YMD_HM:
        return DateTime(
          years[yearIndex],
          _getMonth(),
          _getDay(),
          _getHour(),
          _getMinute(),
        );
      case DateType.YMD_HMS:
        return DateTime(
          years[yearIndex],
          _getMonth(),
          _getDay(),
          _getHour(),
          _getMinute(),
          _getSecond(),
        );
    }
  }

  List<Widget> _getViews() {
    var views = <Widget>[];
    switch (widget.type) {
      case DateType.YM:
        views.add(_getYearView());
        views.add(_getMonthView());
        break;
      case DateType.YMD:
        views.add(_getYearView());
        views.add(_getMonthView());
        views.add(_getDayView());
        break;

      case DateType.YMD_H:
        views.add(_getYearView());
        views.add(_getMonthView());
        views.add(_getDayView());
        views.add(_getHourView());
        break;
      case DateType.YMD_HM:
        views.add(_getYearView());
        views.add(_getMonthView());
        views.add(_getDayView());
        views.add(_getHourView());
        views.add(_getMinuteView());
        break;
      case DateType.YMD_HMS:
        views.add(_getYearView());
        views.add(_getMonthView());
        views.add(_getDayView());
        views.add(_getHourView());
        views.add(_getMinuteView());
        views.add(_getSecondView());
        break;
    }
    return views;
  }

  int _getMonth() => _getSelectValue(months, monthIndex);

  int _getDay() => _getSelectValue(days, dayIndex);

  int _getHour() => _getSelectValue(hours, hourIndex);

  int _getMinute() => _getSelectValue(minutes, minuteIndex);

  int _getSecond() => _getSelectValue(seconds, secondIndex);

  int _realMonthIndex() => monthIndex % months.length;

  int _realDayIndex() => dayIndex % days.length;

  int _realHourIndex() => hourIndex % hours.length;

  int _realMinuteIndex() => minuteIndex % minutes.length;

  void _initMonthValue({bool isInit = false}) {
    /// 设置月的数据
    var minMonth = 1;
    var maxMonth = 12;
    var selectMonthValue = isInit ? defaultTime.month : _getMonth();

    if (yearIndex == 0) {
      minMonth = widget.minValue?.month ?? 1;
    }
    if (yearIndex == years.length - 1) {
      maxMonth = widget.maxValue?.month ?? 12;
    }
    months.clear();
    months.addAll(_getRangArray(minMonth, maxMonth));

    /// 确定选择的值
    if (selectMonthValue < minMonth) {
      selectMonthValue = minMonth;
    } else if (selectMonthValue > maxMonth) {
      selectMonthValue = maxMonth;
    }
    int realIndex = months.indexOf(selectMonthValue);
    monthIndex = midIndex * months.length + realIndex;
    Future.delayed(const Duration(milliseconds: delay)).then((value) {
      monthController.jumpToItem(monthIndex);
    });
    if (widget.type == DateType.YM) {
      _refresh();
      return;
    }

    /// 联动刷新数据
    if (realIndex == 0 ||
        realIndex == months.length - 1 ||
        days.length != _calcDateCount(years[yearIndex], _getMonth())) {
      _initDayValue(isInit: isInit);
    } else {
      _refresh();
    }
  }

  void _initDayValue({bool isInit = false}) {
    /// 设置天的数据
    var minDay = 1;
    var selectDay = isInit ? defaultTime.day : _getDay();
    var maxDay = _calcDateCount(years[yearIndex], _getMonth());
    if (_isMinMonth()) {
      minDay = widget.minValue?.day ?? 1;
    }
    if (_isMaxMonth()) {
      maxDay = widget.maxValue?.day ?? maxDay;
    }
    days.clear();
    days.addAll(_getRangArray(minDay, maxDay));

    /// 确定选择的值
    if (selectDay < minDay) {
      selectDay = minDay;
    } else if (selectDay > maxDay) {
      selectDay = maxDay;
    }
    int realIndex = days.indexOf(selectDay);
    dayIndex = midIndex * days.length + realIndex;
    Future.delayed(const Duration(milliseconds: delay)).then((value) {
      dayController.jumpToItem(dayIndex);
    });
    if (widget.type == DateType.YMD) {
      _refresh();
      return;
    }

    /// 联动刷新
    if (realIndex == 0 || realIndex == days.length - 1 || hours.length != 24) {
      _initHourData(isInit: isInit);
    } else {
      _refresh();
    }
  }

  void _initHourData({bool isInit = false}) {
    /// 设置小时的数据
    var minHour = 0;
    var maxHour = 23;
    var selectHour = isInit ? defaultTime.hour : _getHour();
    if (_isMinMonth() && _realDayIndex() == 0) {
      minHour = widget.minValue?.hour ?? 0;
    }
    if (_isMaxMonth() && _realDayIndex() == days.length - 1) {
      maxHour = widget.maxValue?.hour ?? maxHour;
    }
    hours.clear();
    hours.addAll(_getRangArray(minHour, maxHour));

    /// 确定选择的值
    if (selectHour < minHour) {
      selectHour = minHour;
    } else if (selectHour > maxHour) {
      selectHour = maxHour;
    }
    int realIndex = hours.indexOf(selectHour);
    hourIndex = midIndex * hours.length + realIndex;
    Future.delayed(const Duration(milliseconds: delay)).then((value) {
      hourController.jumpToItem(hourIndex);
    });

    if (widget.type == DateType.YMD_H) {
      _refresh();
      return;
    }

    /// 联动刷新
    if (realIndex == 0 ||
        realIndex == hours.length - 1 ||
        minutes.length != 60) {
      _initMinuteData(isInit: isInit);
    } else {
      _refresh();
    }
  }

  /// 初始化分钟的数据
  void _initMinuteData({bool isInit = false}) {
    /// 设置分钟的数据
    var minMinute = 0;
    var maxMinute = 59;
    var selectMinute = isInit ? defaultTime.minute : _getMinute();

    if (_isMinMonth() && _realDayIndex() == 0 && _realHourIndex() == 0) {
      minMinute = widget.minValue?.minute ?? 0;
    }
    if (_isMaxMonth() &&
        _realDayIndex() == days.length - 1 &&
        _realHourIndex() == hours.length - 1) {
      maxMinute = widget.maxValue?.minute ?? maxMinute;
    }
    minutes.clear();
    minutes.addAll(_getRangArray(minMinute, maxMinute));

    /// 确定选择的值
    if (selectMinute < minMinute) {
      selectMinute = minMinute;
    } else if (selectMinute > maxMinute) {
      selectMinute = maxMinute;
    }
    int realIndex = minutes.indexOf(selectMinute);
    minuteIndex = midIndex * minutes.length + realIndex;
    Future.delayed(const Duration(milliseconds: delay)).then((value) {
      minuteController.jumpToItem(minuteIndex);
    });

    if (widget.type == DateType.YMD_HMS) {
      _initSecondData(isInit: isInit);
    } else {
      /// 联动刷新
      _refresh();
    }
  }

  void _initSecondData({
    bool isInit = false,
  }) {
    if (!isInit) {
      return;
    }
    for (int i = 0; i < 60; i++) {
      seconds.add(i);
    }
    var index = seconds.indexOf(defaultTime.second);
    secondIndex = midIndex * seconds.length + index;
    Future.delayed(const Duration(milliseconds: delay)).then((value) {
      secondController.jumpToItem(secondIndex);
    });
    _refresh();
  }

  void _refresh() {
    setState(() {});
  }

  /// 数组对应index的值
  int _getSelectValue(List<int> data, int selectIndex) {
    if (data.isEmpty) {
      return 1;
    }
    return data[selectIndex % data.length];
  }

  /// 获取区间数组
  List<int> _getRangArray(int start, int end) {
    var result = <int>[];
    result.add(start);
    if (start < end) {
      for (int i = 1; i <= end - start; i++) {
        result.add(start + i);
      }
    }
    return result;
  }

  /// 月的天数
  int _calcDateCount(int year, int month) {
    switch (month) {
      case 1:
      case 3:
      case 5:
      case 7:
      case 8:
      case 10:
      case 12:
        return 31;
      case 2:
        {
          if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            return 29;
          }
          return 28;
        }
    }
    return 30;
  }

  bool _isMaxMonth() {
    return yearIndex == years.length - 1 &&
        _realMonthIndex() == months.length - 1;
  }

  bool _isMinMonth() => yearIndex == 0 && _realMonthIndex() == 0;

  bool _isMaxDay() {
    return _isMaxMonth() && _realDayIndex() == days.length - 1;
  }

  bool _isMinDay() =>
      yearIndex == 0 && _realMonthIndex() == 0 && _realDayIndex() == 0;

  Widget _item(String title) {
    return Container(
      width: double.infinity,
      alignment: Alignment.center,
      child: Text(
        title,
        style: _textStyle,
      ),
    );
  }

  Widget _getYearView() {
    return Expanded(
      flex: 2,
      child: _getPickerView(
        scrollController: yearController,
        childCount: years.length,
        itemBuilder: (context, index) {
          return _item(years[index].toString());
        },
        onSelectedItemChanged: (int index) {
          bool changeMonth = yearIndex == 0 ||
              yearIndex == years.length - 1 ||
              index == 0 ||
              index == years.length - 1;
          yearIndex = index;
          if (changeMonth) {
            _initMonthValue();
          } else if (widget.type != DateType.YM) {
            _initDayValue();
          }
        },
      ),
    );
  }

  final TextStyle _textStyle =
      const TextStyle(fontSize: 16, color: Color(0xff344254));

  Widget _getMonthView() {
    return Expanded(
      child: _getPickerView(
        scrollController: monthController,
        childCount: months.length * times,
        itemBuilder: (context, index) {
          return _item('${months[index % months.length]}月');
        },
        onSelectedItemChanged: (int index) {
          monthIndex = monthController.selectedItem;
          print('月份改变');
          print(monthIndex);
          _initDayValue();
        },
      ),
    );
  }

  Widget _getDayView() {
    return Expanded(
      child: _getPickerView(
        scrollController: dayController,
        childCount: days.length * times,
        itemBuilder: (context, index) {
          return _item(
            '${days[index % days.length]}日',
          );
        },
        onSelectedItemChanged: (int index) {
          var minChange = _isMinMonth() &&
              (_realDayIndex() == 0 || index % days.length == 0);
          var maxChange = _isMaxMonth() &&
              (_realDayIndex() == days.length - 1 ||
                  index % days.length == days.length - 1);
          dayIndex = index;
          if (minChange || maxChange) {
            _initHourData();
          }
        },
      ),
    );
  }

  Widget _getHourView() {
    return Expanded(
      child: _getPickerView(
        scrollController: hourController,
        childCount: hours.length * times,
        itemBuilder: (context, index) {
          return _item(_timeString(hours[index % hours.length]));
        },
        onSelectedItemChanged: (int index) {
          var maxChange = _isMaxDay() &&
              (index % hours.length == hours.length - 1 ||
                  _realHourIndex() == hours.length - 1);
          var minChange = _isMinDay() &&
              (index % hours.length == 0 || _realHourIndex() == 0);
          hourIndex = index;
          if (minChange || maxChange) {
            _initMinuteData();
          }
        },
      ),
    );
  }

  String _timeString(int index) {
    if (index < 10) {
      return '0$index';
    }
    return index.toString();
  }

  Widget _getMinuteView() {
    return Expanded(
      child: _getPickerView(
        scrollController: minuteController,
        childCount: minutes.length * times,
        itemBuilder: (context, index) {
          return _item(
            _timeString(minutes[index % minutes.length]),
          );
        },
        onSelectedItemChanged: (int index) {
          minuteIndex = index;
        },
      ),
    );
  }

  Widget _getSecondView() {
    return Expanded(
      child: _getPickerView(
        scrollController: secondController,
        childCount: seconds.length * times,
        itemBuilder: (context, index) {
          return _item(
            _timeString(seconds[index % seconds.length]),
          );
        },
        onSelectedItemChanged: (int index) {
          secondIndex = index;
        },
      ),
    );
  }

  Widget _getPickerView({
    FixedExtentScrollController? scrollController,
    int? childCount,
    required NullableIndexedWidgetBuilder itemBuilder,
    required ValueChanged<int> onSelectedItemChanged,
  }) {
    return CupertinoPicker.builder(
      scrollController: scrollController,
      itemExtent: 28,
      // looping: picker.looping,
      magnification: 1.1,
      squeeze: 1.0,
      diameterRatio: 1.5,
      childCount: childCount,
      itemBuilder: itemBuilder,
      onSelectedItemChanged: onSelectedItemChanged,
    );
  }
}

enum DateType {
  // y, m, d
  YM,
  YMD,
  YMD_H, // y ,m
  YMD_HM,
  YMD_HMS, // y, m, d, hh, mm
}
