import 'package:cs_resources/generated/assets.dart';
import 'package:cs_resources/theme/app_colors_theme.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:shared/utils/log_utils.dart';
import 'package:widgets/ext/ex_widget.dart';
import 'package:widgets/my_load_image.dart';

import '../../utils/dark_theme_util.dart';

//日历的具体控件展示
class FullCalendar extends StatefulWidget {
  final DateTime startDate;
  final DateTime? endDate;
  final DateTime? selectedDate;
  final Color? dateColor;
  final Color? dateSelectedColor;
  final Color? dateSelectedBg;
  final double? padding;
  final String? locale;
  final Widget? calendarBackground;
  final List<String>? events;
  final Function onDateChange;

  const FullCalendar({
    Key? key,
    this.endDate,
    required this.startDate,
    required this.padding,
    required this.onDateChange,
    this.calendarBackground,
    this.events,
    this.dateColor,
    this.dateSelectedColor,
    this.dateSelectedBg,
    this.locale,
    this.selectedDate,
  }) : super(key: key);

  @override
  State<FullCalendar> createState() => _FullCalendarState();
}

class _FullCalendarState extends State<FullCalendar> {
  late DateTime endDate;
  late DateTime startDate;
  late int _initialPage;

  List<String>? _events = [];

  late PageController _horizontalScroll;

  @override
  void initState() {
    setState(() {
      startDate = DateTime.parse("${widget.startDate.toString().split(" ").first} 00:00:00.000");
      endDate = DateTime.parse("${widget.endDate.toString().split(" ").first} 23:00:00.000");

      _events = widget.events;
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    List<String> partsStart = startDate.toString().split(" ").first.split("-");

    DateTime firstDate = DateTime.parse("${partsStart.first}-${partsStart[1].padLeft(2, '0')}-01 00:00:00.000");

    List<String> partsEnd = endDate.toString().split(" ").first.split("-");

    DateTime lastDate =
        DateTime.parse("${partsEnd.first}-${(int.parse(partsEnd[1]) + 1).toString().padLeft(2, '0')}-01 23:00:00.000").subtract(const Duration(days: 1));

    double width = MediaQuery.of(context).size.width - (2 * widget.padding!);

    List<DateTime?> dates = [];

    DateTime referenceDate = firstDate;

    while (referenceDate.isBefore(lastDate)) {
      List<String> referenceParts = referenceDate.toString().split(" ");
      DateTime newDate = DateTime.parse("${referenceParts.first} 12:00:00.000");
      dates.add(newDate);

      referenceDate = newDate.add(const Duration(days: 1));
    }

    if (firstDate.year == lastDate.year && firstDate.month == lastDate.month) {
      return Padding(
        padding: EdgeInsets.fromLTRB(widget.padding!, 40.0, widget.padding!, 0.0),
        child: month(dates, width, widget.locale),
      );
    } else {
      List<DateTime?> months = [];
      for (int i = 0; i < dates.length; i++) {
        if (i == 0 || (dates[i]!.month != dates[i - 1]!.month)) {
          months.add(dates[i]);
        }
      }

      months.sort((b, a) => a!.compareTo(b!));

      final index = months.indexWhere((element) => element!.month == widget.selectedDate!.month && element.year == widget.selectedDate!.year);

      _initialPage = index;
      _horizontalScroll = PageController(initialPage: _initialPage);

      double monthHeight = 6 * (width / 7) + 16 + 10 + 10 + 80; // 固定高度，6行的高度加上80额外空间

      return Container(
        height: monthHeight, // 使用固定的高度
        padding: const EdgeInsets.fromLTRB(25, 10.0, 25, 20.0),
        //只是PageView
        child: Stack(
          children: [
            //主题
            PageView.builder(
              physics: const BouncingScrollPhysics(),
              controller: _horizontalScroll,
              reverse: true,
              scrollDirection: Axis.horizontal,
              itemCount: months.length,
              itemBuilder: (context, index) {
                DateTime? date = months[index];
                List<DateTime?> daysOfMonth = [];
                for (var item in dates) {
                  if (date!.month == item!.month && date.year == item.year) {
                    daysOfMonth.add(item);
                  }
                }

                bool isLast = index == 0;

                return Container(
                  padding: EdgeInsets.only(bottom: isLast ? 0.0 : 10.0),
                  child: month(daysOfMonth, width, widget.locale),
                );
              },
            ),

            //返回按钮
            Positioned(
              top: -11,
              width: MediaQuery.of(context).size.width * 0.88,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  MyAssetImage(
                    Assets.baseLibCalendarLeftIcon,
                    width: 44,
                    height: 44,
                    color: DarkThemeUtil.multiColors(context, AppColorsTheme.colorPrimary, darkColor: Colors.white),
                  ).onTap(() {
                    _horizontalScroll.nextPage(
                      duration: const Duration(milliseconds: 300),
                      curve: Curves.ease,
                    );
                  }),
                  MyAssetImage(
                    Assets.baseLibCalendarRightIcon,
                    width: 44,
                    height: 44,
                    color: DarkThemeUtil.multiColors(context, AppColorsTheme.colorPrimary, darkColor: Colors.white),
                  ).onTap(() {
                    _horizontalScroll.previousPage(
                      duration: const Duration(milliseconds: 300),
                      curve: Curves.ease,
                    );
                  }),
                ],
              ),
            )
          ],
        ),
      );
    }
  }

  //顶部星期的文本数据
  Widget daysOfWeek(double width, String? locale) {
    List daysNames = [];
    for (var day = 12; day <= 18; day++) {
      daysNames.add(DateFormat.E(locale.toString()).format(DateTime.parse('1970-01-$day')));
    }

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        dayName(width / 7, daysNames[0]),
        dayName(width / 7, daysNames[1]),
        dayName(width / 7, daysNames[2]),
        dayName(width / 7, daysNames[3]),
        dayName(width / 7, daysNames[4]),
        dayName(width / 7, daysNames[5]),
        dayName(width / 7, daysNames[6]),
      ],
    );
  }

  //顶部星期的文本控件展示
  Widget dayName(double width, String text) {
    return Container(
      width: width,
      alignment: Alignment.center,
      child: Text(
        text,
        style: const TextStyle(
          fontSize: 13.0,
          fontWeight: FontWeight.w500,
        ),
        overflow: TextOverflow.ellipsis,
      ),
    );
  }

  //当前月份，每一天的布局
  Widget dateInCalendar(DateTime date, bool outOfRange, double width, bool event) {
    bool isSelectedDate = date.toString().split(" ").first == widget.selectedDate.toString().split(" ").first;
    return GestureDetector(
      onTap: () => outOfRange ? null : widget.onDateChange(date),
      child: Container(
        width: width / 7,
        height: width / 7,
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          color: isSelectedDate ? widget.dateSelectedBg : Colors.transparent,
        ),
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const SizedBox(
              height: 5.0,
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 4.0),
              child: Text(
                DateFormat("dd").format(date),
                style: TextStyle(
                    color: outOfRange
                        ? isSelectedDate
                            ? widget.dateSelectedColor!.withOpacity(0.9)
                            : widget.dateColor!.withOpacity(0.4)
                        : isSelectedDate
                            ? widget.dateSelectedColor
                            : widget.dateColor,
                    fontWeight: FontWeight.w500,
                    fontSize: 13),
              ),
            ),
            event
                ? Icon(
                    Icons.bookmark,
                    size: 8,
                    color: isSelectedDate ? widget.dateSelectedColor : widget.dateSelectedBg,
                  )
                : const SizedBox(height: 5.0),
          ],
        ),
      ),
    );
  }

  //单独一个月的Page布局
  Widget month(List dates, double width, String? locale) {
    DateTime first = dates.first;

    // 获取这个月的第一天
    DateTime firstDayOfMonth = DateTime(first.year, first.month, 1);

    // 找到这个月的第一天是星期几
    int firstWeekday = firstDayOfMonth.weekday;

    // 计算需要的前导空格数量
    int leadingDaysCount = (firstWeekday - DateTime.monday + 7) % 7;

    // 只保留当前月份的日期
    List<DateTime?> fullDates = List.from(dates);

    // 在视图中添加用于填充的空日期（如果需要，这里就不填充上个月尾的日期了）
    for (int i = 0; i < leadingDaysCount; i++) {
      fullDates.insert(0, null); // 用null填充前导位置
    }

    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        Text(
          DateFormat.yMMMM(Locale(locale!).toString()).format(first),
          style: TextStyle(fontSize: 18.0, color: widget.dateColor, fontWeight: FontWeight.w500),
        ),

        // 周一到周天的星期文本
        Padding(
          padding: const EdgeInsets.only(top: 30.0),
          child: daysOfWeek(width, widget.locale),
        ),

        // 底部的每月的每一天
        Container(
          padding: const EdgeInsets.only(top: 10.0),
          height: (fullDates.length > 28) ? (fullDates.length > 35 ? 6.2 * width / 7 : 5.2 * width / 7) : 4 * width / 7,
          width: MediaQuery.of(context).size.width - 2 * widget.padding!,
          child: GridView.builder(
            itemCount: fullDates.length,
            physics: const NeverScrollableScrollPhysics(),
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 7),
            itemBuilder: (context, index) {
              DateTime? date = fullDates[index]; // 使用 DateTime? 类型以支持 null

              // 如果 date 为 null，表示该位置为空，返回一个透明的容器
              if (date == null) {
                return Container(
                  width: width / 7,
                  height: width / 7,
                  color: Colors.transparent, // 透明或其他样式
                );
              }

              bool outOfRange = date.isBefore(startDate) || date.isAfter(endDate);

              return dateInCalendar(
                date,
                outOfRange,
                width,
                _events!.contains(date.toString().split(" ").first) && !outOfRange,
              );
            },
          ),
        )
      ],
    );
  }
}
