import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:getx_scaffold/getx_scaffold.dart';
import 'package:ln_jq_app/common/model/base_model.dart';
import 'package:ln_jq_app/common/model/station_model.dart';
import 'package:ln_jq_app/common/model/vehicle_info.dart';
import 'package:ln_jq_app/pages/b_page/site/controller.dart';
import 'package:ln_jq_app/pages/qr_code/view.dart';
import 'package:ln_jq_app/storage_service.dart';

import '../../../common/styles/theme.dart';
import 'reservation_list_bottomsheet.dart';

/// Helper class for managing time slots
class TimeSlot {
  final TimeOfDay start;
  final TimeOfDay end;

  TimeSlot(this.start, this.end);

  String get display {
    final startStr =
        '${start.hour.toString().padLeft(2, '0')}:${start.minute.toString().padLeft(2, '0')}';
    final endStr =
        '${end.hour.toString().padLeft(2, '0')}:${end.minute.toString().padLeft(2, '0')}';
    return '$startStr - $endStr';
  }
}

class C_ReservationController extends GetxController with BaseControllerMixin {
  @override
  String get builderId => 'reservation';

  C_ReservationController();

  final DateTime _now = DateTime.now();

  // 计算当前时间属于哪个1小时区间
  late final TimeOfDay _initialStartTime = _calculateInitialStartTime(_now);
  late final TimeOfDay _initialEndTime = TimeOfDay.fromDateTime(
    _getDateTimeFromTimeOfDay(_initialStartTime).add(const Duration(minutes: 60)),
  );
  late final Rx<DateTime> selectedDate = DateTime(_now.year, _now.month, _now.day).obs;
  late final Rx<TimeOfDay> startTime = _initialStartTime.obs;
  late final Rx<TimeOfDay> endTime = _initialEndTime.obs;

  /// 静态辅助方法，用于计算初始的开始时间
  static TimeOfDay _calculateInitialStartTime(DateTime now) {
    return TimeOfDay(hour: now.hour, minute: 0);
  }

  /// 静态辅助方法，将TimeOfDay转换为DateTime
  static DateTime _getDateTimeFromTimeOfDay(TimeOfDay time) {
    final now = DateTime.now();
    return DateTime(now.year, now.month, now.day, time.hour, time.minute);
  }

  final TextEditingController amountController = TextEditingController();
  TextEditingController plateNumberController = TextEditingController();

  final RxList<StationModel> stationOptions = <StationModel>[].obs;
  final Rxn<String> selectedStationId = Rxn<String>();

  String get formattedDate => DateFormat('yyyy-MM-dd').format(selectedDate.value);

  /// 时间段
  String get formattedTimeSlot =>
      '${_formatTimeOfDay(startTime.value)} - ${_formatTimeOfDay(endTime.value)}';

  void resetTimeForSelectedDate() {
    final now = DateTime.now();
    final today = DateTime(now.year, now.month, now.day);

    // 1. 获取当前站点
    final station = stationOptions.firstWhereOrNull(
      (s) => s.hydrogenId == selectedStationId.value,
    );
    if (station == null) return;

    // 2. 解析营业开始和结束的小时
    final bizStartHour = int.tryParse(station.startBusiness.split(':')[0]) ?? 0;
    final bizEndHour = int.tryParse(station.endBusiness.split(':')[0]) ?? 23;

    if (selectedDate.value.isAtSameMomentAs(today)) {
      // 如果是今天：起始时间 = max(当前小时, 营业开始小时)，且上限为营业结束小时
      int targetHour = now.hour;
      if (targetHour < bizStartHour) targetHour = bizStartHour;
      if (targetHour > bizEndHour) targetHour = bizEndHour;

      startTime.value = TimeOfDay(hour: targetHour, minute: 0);
    } else {
      // 如果是明天：起始时间直接重置为营业开始小时
      startTime.value = TimeOfDay(hour: bizStartHour, minute: 0);
    }

    // 结束时间默认顺延1小时
    endTime.value = TimeOfDay(hour: (startTime.value.hour + 1) % 24, minute: 0);
  }

  // 用于存储上一次成功预约的信息
  ReservationModel? lastSuccessfulReservation;

  /// 提交预约
  void submitReservation() async {
    if (plateNumber.isEmpty) {
      showToast("请先绑定车辆");
      return;
    }
    String ampuntStr = amountController.text.toString();
    if (ampuntStr.isEmpty) {
      showToast("请输入需要预约的氢量");
      return;
    }
    double ampuntDouble = (double.tryParse(ampuntStr) ?? 0.0);
    if (ampuntDouble == 0) {
      showToast("请输入需要预约的氢量");
      return;
    }
    if (ampuntDouble > (double.tryParse(difference) ?? 0.0)) {
      showToast('当前最大可预约氢量为${difference}(KG)');
      return;
    }

    if (selectedStationId.value == null || selectedStationId.value!.isEmpty) {
      showToast("请先选择加氢站");
      return;
    }

    final dateStr = formattedDate;
    final startTimeStr =
        '$dateStr ${_formatTimeOfDay(startTime.value)}:00'; // Use helper directly

    /*if (lastSuccessfulReservation != null &&
        lastSuccessfulReservation!.id == selectedStationId.value &&
        lastSuccessfulReservation!.startTime == startTimeStr) {
      showToast("请勿重复提交相同时间段的预约，可在“查看预约”中修改");
      return;
    }*/

    DateTime reservationEndDateTime = DateTime(
      selectedDate.value.year,
      selectedDate.value.month,
      selectedDate.value.day,
      endTime.value.hour,
      endTime.value.minute,
    );

    // 如果结束的小时数小于开始的小时数，或者结束时间是 00:00，说明是次日
    if (endTime.value.hour < startTime.value.hour ||
        (endTime.value.hour == 0 && endTime.value.minute == 0)) {
      reservationEndDateTime = reservationEndDateTime.add(const Duration(days: 1));
    }

    // 执行时间检查
    if (reservationEndDateTime.isBefore(
      DateTime.now().subtract(const Duration(minutes: 1)),
    )) {
      showToast("无法预约已过去的时间段");
      return;
    }

    try {
      final selectedStation = stationOptions.firstWhere(
        (s) => s.hydrogenId == selectedStationId.value,
      );

      /*if (selectedStation.siteStatusName != "营运中") {
        showToast("该站点${selectedStation.siteStatusName}，暂无法预约");
        return;
      }*/

      showLoading("提交中");

      final endTimeStr =
          '$dateStr ${_formatTimeOfDay(endTime.value)}:00'; // Use helper directly

      var responseData = await HttpService.to.post(
        'appointment/orderAddHyd/saveOrUpdate',
        data: {
          'plateNumber': plateNumber,
          'date': dateStr,
          'startTime': startTimeStr,
          'endTime': endTimeStr,
          'stationId': selectedStationId.value,
          'stationName': selectedStation.name,
          'contacts': StorageService.to.name,
          'phone': StorageService.to.phone,
          'hydAmount': ampuntStr,
        },
      );
      var result = BaseModel.fromJson(responseData?.data);

      if (responseData == null || result.code != 0) {
        dismissLoading();
        showToast(result.error);
        return;
      }
      dismissLoading();

      if (result.code == 0) {
        showSuccessToast("预约成功");

        lastSuccessfulReservation = ReservationModel(
          id: selectedStationId.value!,
          stationId: '',
          hydAmount: ampuntStr,
          startTime: startTimeStr,
          endTime: endTimeStr,
          stationName: selectedStation.name,
          plateNumber: '',
          amount: '',
          time: '',
          contactPerson: '',
          contactPhone: '',
          contacts: '',
          phone: '',
          date: '',
          state: '',
          stateName: '',
          addStatus: '',
          addStatusName: '',
          hasEdit: true,
          rejectReason: '',
          isTruckAttachment: 0,
          hasHydrogenationAttachment: true,
          hasDrivingAttachment: true,
          isEdit: '',
          drivingAttachments: [],
          hydrogenationAttachments: [],
          gunNumber: '',
        );

        //打开预约列表
        Future.delayed(const Duration(milliseconds: 500), () {
          getReservationList(showPopup: true, addStatus: '');
        });
      } else {
        showToast(result.error);
      }
    } catch (e) {
      dismissLoading();
    }
  }

  /// 状态变量：是否有预约数据
  final RxBool hasReservationData = false.obs;

  // 新增预约数据列表
  final RxList<ReservationModel> reservationList = <ReservationModel>[].obs;
  final RxBool shouldShowReservationList = false.obs;

  // --- 用于防抖的 Timer ---
  Timer? _debounce;

  //查看预约列表
  void getReservationList({bool showPopup = false, String? addStatus}) async {
    //  增加 addStatus 参数
    if (_debounce?.isActive ?? false) {
      return;
    }
    _debounce = Timer(const Duration(milliseconds: 200), () {});

    showLoading("加载中");

    try {
      final Map<String, dynamic> requestData = {
        'phone': StorageService.to.phone,
        'pageNum': 1,
        'pageSize': 50,
      };
      //  将 addStatus 参数添加到请求中
      if (addStatus != null && addStatus.isNotEmpty) {
        requestData['addStatus'] = addStatus;
      }

      var response = await HttpService.to.post(
        "appointment/orderAddHyd/driverOrderPage",
        data: requestData,
      );

      if (response == null || response.data == null) {
        showToast('暂时无法获取预约数据');
        hasReservationData.value = false;
        reservationList.clear();
        return;
      }

      final baseModel = BaseModel<dynamic>.fromJson(response.data);

      if (baseModel.code == 0 && baseModel.data != null) {
        final dataMap = baseModel.data as Map<String, dynamic>;
        final List<dynamic> listFromServer = dataMap['records'] ?? [];

        // 使用 .value 来更新响应式列表
        reservationList.value = listFromServer.map((item) {
          return ReservationModel.fromJson(item as Map<String, dynamic>);
        }).toList();

        // 更新 hasEdit 状态
        for (var reservation in reservationList) {
          try {
            // 获取当前时间和预约的结束时间
            final now = DateTime.now();
            final endDateTime = DateTime.parse(reservation.endTime);

            // 如果当前时间在结束时间之后，则不能编辑
            if (now.isAfter(endDateTime) ||
                plateNumber.isEmpty ||
                reservation.addStatus != "0") {
              reservation.hasEdit = false;
            } else {
              reservation.hasEdit = true;
            }
          } catch (e) {
            reservation.hasEdit = false;
          }
        }

        hasReservationData.value = reservationList.isNotEmpty;

        if (showPopup) {
          shouldShowReservationList.value = true;
        }
      } else {
        showToast(baseModel.message);
        hasReservationData.value = false;
        reservationList.clear();
      }
    } catch (e) {
      Logger.d("${e.toString()}");
      showToast('获取预约数据失败');
      hasReservationData.value = false;
      reservationList.clear();
    } finally {
      dismissLoading();
    }
  }

  String workEfficiency = "-";
  String fillingWeight = "-";
  String fillingTimes = "-";
  String modeImage = "";
  String plateNumber = "";
  String vin = "";
  String leftHydrogen = "-";
  num maxHydrogen = 0;
  String difference = "";
  var progressValue = 0.0;

  //用来管理查看预约的弹窗
  Worker? _sheetWorker;
  bool init = false;
  Timer? _refreshTimer;

  @override
  bool get listenLifecycleEvent => true;

  @override
  void onInit() {
    super.onInit();
    getUserBindCarInfo();
    getSiteList();
    startAutoRefresh();
    msgNotice();

    if (!init) {
      _setupListener();
      init = true;
    }
  }

  bool isNotice = false;

  Future<void> msgNotice() async {
    final Map<String, dynamic> requestData = {
      'appFlag': 1,
      'isRead': 1,
      'pageNum': 1,
      'pageSize': 5,
    };
    final response = await HttpService.to.get(
      'appointment/unread_notice/page',
      params: requestData,
    );
    if (response != null) {
      final result = BaseModel.fromJson(response.data);
      if (result.code == 0 && result.data != null) {
        String total = result.data["total"].toString();
        isNotice = int.parse(total) > 0;
        updateUi();
      }
    }
  }

  void startAutoRefresh() {
    // 先停止已存在的定时器，防止重复启动
    stopAutoRefresh();

    // 创建一个每1分钟执行一次的周期性定时器
    _refreshTimer = Timer.periodic(const Duration(minutes: 1), (timer) {
      getSiteList(showloading: false);
    });
  }

  ///停止定时器的方法
  void stopAutoRefresh() {
    // 如果定时器存在并且是激活状态，就取消它
    _refreshTimer?.cancel();
    _refreshTimer = null; // 置为null，方便判断
  }

  void _setupListener() {
    _sheetWorker = ever(shouldShowReservationList, (bool shouldShow) {
      if (shouldShow) {
        Get.bottomSheet(
          const ReservationListBottomSheet(),
          isScrollControlled: true, // 允许弹窗使用更多屏幕高度
          backgroundColor: Colors.transparent,
        );

        // 重要：显示后立即将信号重置为 false，防止不必要的重复弹出
        shouldShowReservationList.value = false;
      }
    });
  }

  void getUserBindCarInfo() {
    if (StorageService.to.hasVehicleInfo) {
      VehicleInfo? bean = StorageService.to.vehicleInfo;
      if (bean == null) {
        return;
      }
      plateNumber = bean.plateNumber;
      vin = bean.vin;
      plateNumberController = TextEditingController(text: plateNumber);
      maxHydrogen = num.tryParse(bean.maxHydrogen) ?? 0;
      getCatinfo();
      getJqinfo();
    }
  }

  void doQrCode() async {
    var scanResult = await Get.to(() => const QrCodePage());
    if (scanResult == true) {
      getUserBindCarInfo();
      refreshAppui();
    }
  }

  void getJqinfo() async {
    try {
      HttpService.to.setBaseUrl(AppTheme.test_service_url);
      var responseData = await HttpService.to.get(
        'appointment/truck/history-filling-summary?vin=$vin&plateNumber=$plateNumber',
      );
      if (responseData == null || responseData.data == null) {
        showToast('服务暂不可用，请稍后');
        return;
      }

      var result = BaseModel.fromJson(responseData.data);

      final value = double.tryParse(result.data["fillingWeight"]?.toString() ?? '0') ?? 0;
      final String formatted = value.toStringAsFixed(2);

      fillingWeight = "$formatted${result.data["fillingWeightUnit"]}";
      fillingTimes = "${result.data["fillingTimes"]}${result.data["fillingTimesUnit"]}";
      modeImage = result.data["modeImage"].toString();

      updateUi();
    } catch (e) {
    } finally {
      HttpService.to.setBaseUrl(AppTheme.test_service_url);
    }
  }

  void getCatinfo() async {
    try {
      var responseData = await HttpService.to.post(
        'appointment/vehicle/getHydrogenInfoByPlateNumber',
        data: {
          'userName': "xll@lingniu",
          'password': "4q%3!l6s0p",
          'plateNumber': plateNumber,
        },
      );
      if (responseData == null || responseData.data == null) {
        showToast('服务暂不可用，请稍后');
        return;
      }

      var result = BaseModel.fromJson(responseData.data);

      leftHydrogen = "${result.data["leftHydrogen"]}Kg";
      workEfficiency = "${result.data["workEfficiency"]}Kg";

      final leftHydrogenNum = double.tryParse(leftHydrogen) ?? 0.0;
      difference = (maxHydrogen - leftHydrogenNum).toStringAsFixed(2);

      int flooredDifference = (maxHydrogen - leftHydrogenNum).floor();
      if (flooredDifference > 0) {
        amountController.text = flooredDifference.toString();
      }

      if (maxHydrogen > 0) {
        progressValue = leftHydrogenNum / maxHydrogen;

        // 边界处理：确保值在 0 到 1 之间
        if (progressValue > 1.0) progressValue = 1.0;
        if (progressValue < 0.0) progressValue = 0.0;
      }

      updateUi();
    } catch (e) {}
    renderSliderTheme();
  }

  double current = 0.0;
  double maxVal = 0.0;

  void renderSliderTheme() {
    current = double.tryParse(amountController.text) ?? 0.0;
    maxVal = double.tryParse(difference) ?? 100.0;
    if (maxVal <= 0) maxVal = 100.0;

    updateUi();
  }

  void getSiteList({showloading = true}) async {
    if (StorageService.to.phone == "13344444444" ||
        StorageService.to.phone == "13888888888") {
      //该账号给stationOptions手动添加一个数据
      final testStation = StationModel(
        hydrogenId: '1142167389150920704',
        name: '演示加氢站',
        address: '上海市嘉定区于田南路111号于田大厦',
        price: '35.00',
        // 价格
        siteStatusName: '营运中',
        // 状态
        isSelect: 1,
        startBusiness: '08:00:00',
        endBusiness: '20:00:00', // 默认可选
      );
      //    使用 assignAll 可以确保列表只包含这个测试数据
      stationOptions.assignAll([testStation]);

      if (stationOptions.isNotEmpty) {
        selectedStationId.value = stationOptions.first.hydrogenId;
      }
      return;
    }

    try {
      if (showloading) {
        showLoading("加氢站数据加载中");
      }

      var responseData = await HttpService.to.get(
        "appointment/station/queryHydrogenSiteInfo",
      );

      if (responseData == null || responseData.data == null) {
        showToast('暂时无法获取站点信息');
        dismissLoading();
        return;
      }
      dismissLoading();
      var result = BaseModel.fromJson(responseData.data);
      var stationDataList = result.data['data'] as List;

      // 使用 map 将 List<dynamic> 转换为 List<StationModel>
      var stations = stationDataList
          .map((item) => StationModel.fromJson(item as Map<String, dynamic>))
          .toList();

      // 去重，确保每个 hydrogenId 唯一
      var uniqueStationsMap = <String, StationModel>{}; // 使用 Map 来去重
      for (var station in stations) {
        uniqueStationsMap[station.hydrogenId] = station; // 使用 hydrogenId 作为键，确保唯一
      }

      // 获取去重后的 List<StationModel>
      var uniqueStations = uniqueStationsMap.values.toList();

      stationOptions.assignAll(uniqueStations);

      if (stationOptions.isEmpty) {
        showToast('附近暂无可用加氢站');
      } else {
        // showToast('站点列表已刷新');
      }

      // 找到第一个可选的站点作为默认值
      if (stationOptions.isNotEmpty) {
        final firstSelectable = stationOptions.firstWhere(
          (station) => station.isSelect == 1,
          orElse: () => stationOptions.first, // 降级：如果没有可选的，就用第一个
        );
        selectedStationId.value = firstSelectable.hydrogenId;
      } else {
        // 如果列表为空，确保 selectedStationId 也为空
        selectedStationId.value = null;
      }
    } catch (e) {
      dismissLoading();
      showToast('数据异常');
    } finally {
      dismissLoading();
      // 如果未绑定车辆，且本次会话尚未提示过，则弹出提示
      if (!StorageService.to.hasShownBindVehicleDialog &&
          StorageService.to.isLoggedIn &&
          StorageService.to.loginChannel == LoginChannel.driver &&
          !StorageService.to.hasVehicleInfo) {
        Future.delayed(const Duration(milliseconds: 500), () {
          DialogX.to.showConfirmDialog(
            title: '当前尚未绑定车辆',
            confirmText: "去绑定",
            cancelText: "稍后",
            onConfirm: () {
              doQrCode();
            },
          );
          // 标记为已显示，本次会话不再提示
          StorageService.to.markBindVehicleDialogAsShown();
        });
      }
    }
  }

  String _formatTimeOfDay(TimeOfDay time) {
    final hour = time.hour.toString().padLeft(2, '0');
    final minute = time.minute.toString().padLeft(2, '0');
    return '$hour:$minute';
  }

  @override
  void onClose() {
    super.onClose();
    amountController.dispose();
    plateNumberController.dispose();
    if (_debounce != null) {
      _debounce?.cancel();
    }
    _sheetWorker?.dispose();
    stopAutoRefresh();
  }
}
