import 'dart:async';
import 'dart:convert';
import 'package:fis_common/logger/logger.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vitalapp/architecture/app_parameters.dart';
import 'package:vitalapp/global.dart';
import 'package:vitalapp/managers/device_controller_manager.dart';
import 'package:vitalapp/managers/interfaces/data_convert.dart';
import 'package:vitalapp/managers/interfaces/models/device.dart';
import 'package:vitalapp/pages/medical/widgets/exam_card.dart';
import 'package:vitalapp/pages/medical/controller.dart';
import 'package:vitalapp/pages/medical/models/worker.dart';
import 'package:vitalapp/pages/medical/widgets/device_status.dart';
import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
import 'package:vitalapp/pages/medical/widgets/ecg_view/index.dart';
import 'package:vitalapp/pages/medical/widgets/side_bar.dart';
import 'package:vnote_device_plugin/consts/types.dart';
import 'package:vnote_device_plugin/devices/heart.dart';
import 'package:vnote_device_plugin/models/exams/heart.dart';
import 'package:http/http.dart' as http;

class HeartRate extends StatefulWidget {
  const HeartRate({
    super.key,
  });

  @override
  State<HeartRate> createState() => _HeartRateState();
}

class _HeartRateState extends State<HeartRate> {
  bool get isPureSoftwareMode => AppParameters.data.isPureSoftwareMode;
  final MedicalController medicalController = Get.find<MedicalController>();
  final IDataConvertManager dataConvertManager =
      Get.find<IDataConvertManager>();
  DeviceControllerManager? heart;
  late HeartDeviceWorker worker;
  WorkerStatus connectStatus = WorkerStatus.connecting;
  List<int> ecgPoint = [];
  int errorCount = 0;
  bool isConnectFail = false;
  late String _heart =
      medicalController.diagnosisDataValue['Heart']?['HEART']?.toString() ?? '';
  late String _assess =
      medicalController.diagnosisDataValue['Heart']?['ASSESS'] ?? '';
  late final heartRate =
      medicalController.diagnosisDataValue['Heart']?['HEART'] ?? 0;

  /// 是否显示重试按钮
  bool showResetButton = false;

  /// 初始时的心电初始数据
  List<int>? initEcgData;

  String _deviceError = '';
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        ExamCard(
          titleText: const SizedBox(),
          // bottomPadding: 10,
          content: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  const SideBar(
                    title: '心率',
                    value: '',
                    unit: '',
                  ),
                  const Expanded(child: SizedBox()),
                  Text(
                    _heart.isEmpty ? '--' : _heart,
                    style: const TextStyle(
                      fontSize: 60,
                      color: Colors.black,
                    ),
                  ),
                  const Text(
                    "  bpm",
                    style: TextStyle(fontSize: 25),
                  ),
                  const SizedBox(
                    width: 15,
                  )
                ],
              ),
              if (_deviceError.isNotEmpty)
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 30,
                      ),
                      child: const Text(
                        '心率测量出错',
                        style: TextStyle(
                          fontSize: 25,
                        ),
                      ),
                    ),
                    Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 50,
                      ),
                      child: Text(
                        _deviceError,
                        style: const TextStyle(
                          fontSize: 24,
                        ),
                      ),
                    ),
                  ],
                ),
              if (_assess.isNotEmpty)
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 30,
                      ),
                      child: const Text(
                        '心率评估',
                        style: TextStyle(
                          fontSize: 25,
                        ),
                      ),
                    ),
                    Container(
                      padding: const EdgeInsets.only(
                        right: 15,
                      ),
                      child: Text(
                        dataConvertManager.heartRateConversion(
                            int.parse(heartRate.toString())),
                        style: const TextStyle(
                          fontSize: 24,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                  ],
                ),
              const SizedBox(
                height: 10,
              ),
              SizedBox(
                height: 240,
                child: LayoutBuilder(builder: (context, constraints) {
                  if (initEcgData == null) {
                    return Container();
                  } else {
                    return EcgView(
                      width: constraints.maxWidth,
                      height: constraints.maxHeight,
                      initData: initEcgData!,
                    );
                  }
                }),
              ),
              Container(
                // !! 这一层 Container 不能删 ,否则会引发 EcgView 的 controller 被异常删除
                child: _buildResetButton(),
              ),
            ],
          ),
        ),
        if (!isPureSoftwareMode) ...[
          if (!isConnectFail)
            DeviceStatusPosition(
              deviceStatus: DeviceStatus(connectStatus: connectStatus),
            )
          else
            _buildErrorButton(),
        ],
      ],
    );
  }

  // Widget _buildDebugButton() {
  //   return Container(
  //     child: Row(
  //       children: [
  //         const Text(
  //           '测试============?',
  //           style: TextStyle(color: Colors.grey, fontSize: 24),
  //         ),
  //         TextButton(
  //           onPressed: () {
  //             debugTest();
  //           },
  //           child: const Text(
  //             '重试',
  //             style: TextStyle(color: Colors.blue, fontSize: 24),
  //           ),
  //         ),
  //       ],
  //     ),
  //   );
  // }

  Widget _buildResetButton() {
    if (!showResetButton) {
      return const SizedBox(
        height: 48,
      );
    }
    return Container(
      padding: const EdgeInsets.only(left: 30),
      child: Row(
        children: const [
          Text(
            '时长不足30S',
            style: TextStyle(color: Colors.grey, fontSize: 24),
          ),
          // TextButton(
          //   onPressed: () {
          //     ecgPoint = [];
          //     resetEcgView();
          //     setEcgData();
          //     setState(() {
          //       showResetButton = false;
          //     });
          //   },
          //   child: const Text(
          //     '重试',
          //     style: TextStyle(color: Colors.blue, fontSize: 24),
          //   ),
          // ),
        ],
      ),
    );
  }

  // 设备初始化
  Future<void> initDevice() async {
    DeviceModel? device = await medicalController.getDevice(DeviceTypes.HEART);
    if (device == null) {
      connectStatus = WorkerStatus.unboundDevice;
      setState(() {});
      return;
    }
    heart =
        DeviceControllerManager(DeviceTypes.HEART, device.model, device.mac);
    worker = heart!.worker as HeartDeviceWorker;
    connectStatus = heart!.connectStatus;

    loadListeners();
    connect();
  }

  /// 尝试重连
  Future<void> tryReconnect() async {
    await disconnect();
    await connect();
  }

  Future<void> disconnect() async {
    await worker.disconnect();
  }

  Future<void> connect() async {
    await worker.connect();
  }

  @override
  void dispose() {
    heart?.dispose();
    heart = null;
    releaseListeners();
    disconnect();
    worker.dispose();
    super.dispose();
  }

  /// 重置数据以及心电图
  void resetEcgView() {
    try {
      EcgViewController ecgViewController = Get.find<EcgViewController>();
      ecgPoint = [];
      ecgViewController.reset();
    } catch (e) {
      logger.i('心率图测量失败:$e');
    }
  }

  /// 数据初始化
  Future<void> initData() async {
    // medicalController.readCachedRecord();
    if (medicalController.diagnosisDataValue['Heart'] == null) {
      medicalController.diagnosisDataValue['Heart'] = {};
    }
    if (medicalController.diagnosisDataValue['Heart']?['ECG_POINT'] != null) {
      String pointInfo =
          medicalController.diagnosisDataValue['Heart']?['ECG_POINT'] ?? '';
      if ((pointInfo.toString().startsWith('https://') ||
              pointInfo.toString().startsWith('http://')) &&
          kIsOnline) {
        final response = await http.get(Uri.parse(pointInfo));
        pointInfo = response.body;
      }
      initEcgData = jsonDecode(pointInfo).cast<int>();
      if (initEcgData != null &&
          initEcgData!.isNotEmpty &&
          initEcgData!.length < 125 * 30) {
        // print("数据不完整 ⭐⭐⭐⭐⭐⭐⭐");
        showResetButton = true;
      }
    } else {
      initEcgData = [];
    }

    setState(() {});
  }

  Future<void> initHeart() async {
    await initDevice();
    await initData();
  }

  @override
  void initState() {
    initHeart();
    super.initState();
  }

  void loadListeners() {
    worker.connectErrorEvent.addListener(_onConnectFail);
    worker.connectedEvent.addListener(_onConnectSuccess);
    worker.disconnectedEvent.addListener(_onDisconnected);
    worker.hrValueUpdateEvent.addListener(_onHrValueUpdate);
    worker.ecgValueUpdateEvent.addListener(_onEcgValueUpdate);
    worker.resultReceivedEvent.addListener(_onRCesultReceived);
    worker.errorEvent.addListener(_onError);
  }

  void releaseListeners() {
    worker.connectErrorEvent.removeListener(_onConnectFail);
    worker.connectedEvent.removeListener(_onConnectSuccess);
    worker.disconnectedEvent.removeListener(_onDisconnected);
    worker.hrValueUpdateEvent.removeListener(_onHrValueUpdate);
    worker.ecgValueUpdateEvent.removeListener(_onEcgValueUpdate);
    worker.resultReceivedEvent.removeListener(_onRCesultReceived);
    worker.errorEvent.removeListener(_onError);
  }

  /// 需要封装一下
  Widget _buildErrorButton() {
    return DeviceStatusPosition(
      deviceStatus: Row(
        children: [
          const Text(
            '请确认设备是否启动',
            style: TextStyle(fontSize: 24, color: Colors.red),
          ),
          IconButton(
            onPressed: () {
              tryReconnect();
              setState(() {
                connectStatus = WorkerStatus.connecting;
                isConnectFail = false;
              });
            },
            icon: const Icon(Icons.refresh),
            iconSize: 32,
          ),
        ],
      ),
    );
  }

  void _onConnectFail(sender, e) async {
    logger.i("设备连接失败:${worker.mac}");
    if (errorCount < 3) {
      errorCount++;
      await tryReconnect();
    } else {
      isConnectFail = true;
    }
    connectStatus = WorkerStatus.connectionFailed;

    setState(() {});
  }

  void _onConnectSuccess(sender, e) {
    logger.e('_HeartRateState ${worker.mac}, 设备连接成功');
    isConnectFail = false;
    errorCount = 0;
    connectStatus = WorkerStatus.connected;
    setState(() {});
  }

  /// 设备连接中断
  void _onDisconnected(sender, e) async {
    print('设备连接中断');
    logger.i("设备连接中断:${worker.mac}");
    await tryReconnect();
    errorCount = 0;
    connectStatus = WorkerStatus.disconnected;
    setState(() {});
  }

  // 心电图数据更新
  void _onEcgValueUpdate(_, List<int> e) {
    try {
      EcgViewController ecgViewController = Get.find<EcgViewController>();
      ecgPoint.addAll(e);
      if (ecgPoint.length > 125 * 3) {
        // 3s 后开始塞数据
        ecgViewController.addData(e);
      }
    } catch (e) {
      print(e);
    }
  }

  /// 更新心率
  void _onHrValueUpdate(_, int e) {
    if (_deviceError.isNotEmpty || _assess.isNotEmpty) {
      // 如果上次因错误而停止了,这里需要先重置
      _deviceError = '';
      _assess = '';
      resetEcgView();
    }
    setState(() {
      _heart = e.toString();
      showResetButton = false;
    });
  }

  void _onError(_, String e) {
    logger.i('心率更新失败:$e');
    _deviceError = e;
    resetEcgView();
    setState(() {});
  }

  /// 接收到最终结果
  void _onRCesultReceived(_, HeartExamResult e) async {
    logger.i('心率更新接收结果:${e.heartRate}');
    // print(ecgPoint.toString());
    // _heart = e.toString();
    _assess = e.analysis.first;
    _heart = e.heartRate.toString();
    medicalController.diagnosisDataValue['Heart']?['HEART'] =
        e.heartRate.toString();
    medicalController.diagnosisDataValue['Heart']?['ASSESS'] =
        dataConvertManager.heartRateConversion(int.parse(heartRate));

    await setEcgData();
    medicalController.saveCachedRecord();

    /// 判断数据是否完整
    if (ecgPoint.isNotEmpty && ecgPoint.length < 125 * 30) {
      // print("数据不完整 ⭐⭐⭐⭐⭐⭐⭐");
      showResetButton = true;
    }

    /// FIXME 解除下方注释
    // try {
    //   medicalController.saveCachedRecord();
    // } catch (e) {
    //   print(e);
    // }
    // print(medicalController.diagnosisDataValue);
    setState(() {});
  }

  /// 设置最终数据
  Future<void> setEcgData() async {
    EcgViewController ecgViewController = Get.find<EcgViewController>();
    medicalController.diagnosisDataValue['Heart']?['ECG'] =
        await ecgViewController.getFullDataImageBase64();
    medicalController.diagnosisDataValue['Heart']?['ECG_POINT'] =
        jsonEncode(ecgViewController.allPoints);
  }
}