import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vitalapp/managers/device_controller_manager.dart';
import 'package:vitalapp/managers/interfaces/organization.dart';
import 'package:vitalapp/pages/medical/widgets/device_status_position.dart';
import 'package:vnote_device_plugin/consts/types.dart';
import 'package:vnote_device_plugin/devices/nibp.dart';
import 'package:vnote_device_plugin/models/exams/nibp.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:vitalapp/managers/interfaces/models/device.dart';
import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_card.dart';
import 'package:vitalapp/pages/medical/controller.dart';
import 'package:vitalapp/pages/medical/models/item.dart';
import 'package:vitalapp/pages/medical/models/worker.dart';
import 'package:vitalapp/pages/medical/widgets/device_status.dart';

// ignore: must_be_immutable
class BloodPressure extends StatefulWidget {
  const BloodPressure({
    super.key,
  });
  @override
  State<BloodPressure> createState() => _BloodPressureState();
}

class _BloodPressureState extends State<BloodPressure> {
  var controller = Get.find<MedicalController>();
  PressureDeviceStatus pressureDeviceStatus = PressureDeviceStatus.start;
  bool isConnectFail = false;
  late DeviceControllerManager nibp;
  NibpDeviceWorker? worker;
  int liveValue = 0;
  int errorCount = 0;

  WorkerStatus _connectStatus = WorkerStatus.connecting;
  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      currentDevice();
    });
    super.initState();
  }

  @override
  void didUpdateWidget(BloodPressure oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  Future<void> currentDevice() async {
    DeviceModel? device = await controller.getDevice(DeviceTypes.NIBP);
    if (device == null) {
      _connectStatus = WorkerStatus.unboundDevice;
      worker = null;
      setState(() {});
      return;
    }
    nibp = DeviceControllerManager(DeviceTypes.NIBP, device.model, device.mac);
    worker = nibp.worker as NibpDeviceWorker;
    _connectStatus = nibp.connectStatus;

    loadListeners();
    connect();
  }

  void loadListeners() {
    worker!.liveUpdateEvent.addListener(_onLiveUpdate);
    worker!.resultUpdateEvent.addListener(_onSuccess);
    worker!.connectErrorEvent.addListener(_onConnectFail);
    worker!.connectedEvent.addListener(_onConnectSuccess);
    worker!.disconnectedEvent.addListener(_onDisconnected);
  }

  void releaseListeners() {
    if (worker != null) {
      worker!.connectErrorEvent.removeListener(_onConnectFail);
      worker!.connectedEvent.removeListener(_onConnectSuccess);
      worker!.liveUpdateEvent.removeListener(_onLiveUpdate);
      worker!.resultUpdateEvent.removeListener(_onSuccess);
      worker!.disconnectedEvent.removeListener(_onDisconnected);
    }
  }

  Future<void> connect() async {
    try {
      if (worker != null) {
        await worker!.connect();
      }
    } catch (err) {
      print(err);
    }
  }

  Future<void> disconnect() async {
    try {
      if (worker != null) {
        await worker!.disconnect();
      }
    } catch (err) {
      print(err);
    }
  }

  /// 尝试重连
  Future<void> tryReconnect() async {
    if (worker != null) {
      await disconnect();
      await connect();
    }
  }

  @override
  void dispose() {
    nibp.dispose();
    releaseListeners();
    disconnect();
    worker?.dispose();
    super.dispose();
  }

  void _onLiveUpdate(_, int e) {
    if (controller.diagnosisDataValue['NIBP'] != null) {
      controller.diagnosisDataValue['NIBP'] = null;
    }
    setState(() {
      liveValue = e;
    });
  }

  /// TODO 需求不清，检测的数据需要传给体检，但是检测又不区分左右侧血压
  void _onSuccess(_, NibpExamValue e) async {
    logger.i(
        '检测完成，高压：${e.systolicPressure},低压：${e.diastolicPressure},脉率：${e.pulse}');
    int sbp = e.systolicPressure;
    int dbp = e.diastolicPressure;

    final orgManager = Get.find<IOrganizationManager>();
    final paramSbp = await orgManager.getDynamicParamByKey("Sbp");
    if (paramSbp != null) {
      sbp = nibp.handleExamValueSpecially(sbp, paramSbp);
      logger.i('NIBP Value handle specially - Sbp: $sbp.');
    }
    final paramDbp = await orgManager.getDynamicParamByKey("Sbp");
    if (paramDbp != null) {
      dbp = nibp.handleExamValueSpecially(dbp, paramDbp);
      logger.i('NIBP Value handle specially -  Dbp：$dbp.');
    }
    setState(() {
      pressureDeviceStatus = PressureDeviceStatus.end;

      /// 这是第三方需要的数据
      controller.diagnosisDataValue['NIBP'] = {
        'Sbp': sbp.toString(),
        'Dbp': dbp.toString(),
        'Pulse_Beat': e.pulse.toString(),
      };
      controller.saveCachedRecord();
    });
  }

  void _onConnectFail(sender, e) {
    logger.i("连接设备失败:${worker!.mac}");
    print('连接设备失败:${worker!.mac},errorCount:$errorCount，${DateTime.now()}');
    if (errorCount < 3) {
      print('连接设备失败:${worker!.mac},$errorCount,${DateTime.now()}');
      logger.i('连接设备失败:${worker!.mac},$errorCount,${DateTime.now()}');
      errorCount++;
      tryReconnect();
    } else {
      print('连接设备失败:${worker!.mac},$errorCount,${DateTime.now()}');
      logger.i('连接设备失败:${worker!.mac},$errorCount,${DateTime.now()}');
      isConnectFail = true;
    }
    _connectStatus = WorkerStatus.connectionFailed;
    setState(() {});
  }

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

  void _onConnectSuccess(sender, e) {
    logger.i("设备连接成功:$e");
    print("设备连接成功:$e");

    setState(() {
      _connectStatus = WorkerStatus.connected;
      errorCount = 0;
      isConnectFail = false;
    });
  }

  Widget _buildValue() {
    if (controller.diagnosisDataValue['NIBP'] == null) {
      return _buildLiveWidget();
    }
    //收缩压（高压）
    var hightValue =
        controller.diagnosisDataValue['NIBP']?['Sbp']?.toString() ?? '';
    //舒张压（低压）
    var lowValue =
        controller.diagnosisDataValue['NIBP']?['Dbp']?.toString() ?? '';

    if (hightValue.isNotEmpty || lowValue.isNotEmpty) {
      return _buildResultWidget();
    }
    return _buildLiveWidget();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        ExamCard(
          title: '',
          content: Column(
            children: [
              Row(
                children: [
                  const SizedBox(
                    width: 25,
                  ),
                  const Text(
                    '血压',
                    style: TextStyle(fontSize: 25),
                  ),
                  const Expanded(child: SizedBox()),
                  InkWell(
                    child: _SideBar(
                      value: _buildValue(),
                      unit: 'mmHg',
                    ),
                  ),
                ],
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  const SizedBox(
                    width: 25,
                  ),
                  const Text(
                    '脉率',
                    style: TextStyle(fontSize: 25),
                  ),
                  const Expanded(child: SizedBox()),
                  Text(
                    controller.diagnosisDataValue['NIBP']?['Pulse_Beat']
                            .toString() ??
                        '',
                    style: const TextStyle(
                      fontSize: 45,
                      color: Colors.black,
                    ),
                  ),
                  const Text(
                    '       bpm',
                    style: TextStyle(fontSize: 25),
                  ),
                  const SizedBox(
                    width: 30,
                  ),
                ],
              ),
            ],
          ),
        ),
        if (isConnectFail) ...[
          _buildErrorButton(),
        ] else ...[
          Positioned(
            right: 10,
            top: 10,
            child: DeviceStatus(connectStatus: _connectStatus),
          ),
        ],
      ],
    );
  }

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

  Widget _buildLiveWidget() {
    return SizedBox(
      height: 130,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Container(
            alignment: Alignment.center,
            child: Text(
              liveValue.toString() == '0' ? '--' : liveValue.toString(),
              style: const TextStyle(
                fontSize: 80,
                color: Colors.black,
              ),
            ),
          ),
          const Text(
            '  mmHg',
            style: TextStyle(fontSize: 25),
          ),
          const SizedBox(
            width: 30,
          )
        ],
      ),
    );
  }

  Widget _buildResultWidget() {
    const textStyle = TextStyle(
      fontSize: 45,
      color: Colors.black,
    );
    var normalStyle = const TextStyle(
      fontSize: 25,
      color: Colors.black,
    );
    var uuitText = const Text(
      '  mmHg',
      style: TextStyle(
        fontSize: 25,
        color: Colors.black,
      ),
    );
    return Stack(
      children: [
        Column(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Row(
              children: [
                Text(
                  '收缩压',
                  style: normalStyle,
                ),
                Container(
                  alignment: Alignment.centerRight,
                  width: 200,
                  child: Text(
                    controller.diagnosisDataValue['NIBP']['Sbp'],
                    style: textStyle,
                  ),
                ),
                uuitText,
                const SizedBox(
                  width: 30,
                ),
              ],
            ),
            Row(
              children: [
                Text(
                  '舒张压',
                  style: normalStyle,
                ),
                Container(
                  alignment: Alignment.centerRight,
                  width: 200,
                  child: Text(
                    controller.diagnosisDataValue['NIBP']['Dbp'],
                    style: textStyle,
                  ),
                ),
                uuitText,
                const SizedBox(
                  width: 30,
                ),
              ],
            ),
          ],
        ),
      ],
    );
  }
}

class _SideBar extends StatelessWidget {
  final Widget value;
  final String unit;

  const _SideBar({
    required this.value,
    required this.unit,
  });

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.end,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Container(
          alignment: Alignment.bottomRight,
          child: FittedBox(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                value,
              ],
            ),
          ),
        ),
      ],
    );
  }
}
