import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:vitalapp/managers/device_controller_manager.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/components/alert_dialog.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/controllers/nibp.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';
import 'package:vitalapp/pages/medical/widgets/switch_button.dart';

/// TODO 需要优化
/// 小弹窗输入
class VDialogBloodPressure extends StatelessWidget {
  /// 标题
  final String? title;

  /// 描述
  final String? description;

  /// 输入占位符
  final String? placeholder;

  /// 初始值
  final List<String>? initialValue;

  const VDialogBloodPressure({
    super.key,
    this.title,
    this.description,
    this.placeholder,
    this.initialValue,
  });

  Future<String?> show<String>() => VAlertDialog.showDialog<String>(this);

  @override
  Widget build(BuildContext context) {
    final controller1 = TextEditingController(text: initialValue?.first);
    final controller2 = TextEditingController(text: initialValue?.last);
    return VAlertDialog(
      title: title,
      width: 440,
      contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
      content: _buildContent(context, controller1, controller2),
      showCancel: true,
      onConfirm: () {
        Get.back(result: json.encode([controller1.text, controller2.text]));
      },
    );
  }

  Widget _buildContent(
    BuildContext context,
    TextEditingController controller1,
    TextEditingController controller2,
  ) {
    final children = <Widget>[];
    if (description != null) {
      children.add(
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 4),
          child: Text(
            description!,
            style: const TextStyle(color: Colors.black87, fontSize: 18),
          ),
        ),
      );
      children.add(const SizedBox(height: 8));
    } else {
      children.add(const SizedBox(height: 12));
    }
    children.add(_buildInputWidget(context, controller1, controller2));
    return SingleChildScrollView(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: children,
      ),
    );
  }

  Widget _buildInputWidget(
    BuildContext context,
    TextEditingController controller1,
    TextEditingController controller2,
  ) {
    const fontSize = 20.0;
    onSubmitted() {
      Get.back(result: json.encode([controller1.text, controller2.text]));
    }

    return Row(
      children: [
        _buildItem(context, controller1, '收缩压', onSubmitted),
        const Text(
          '/',
          style: TextStyle(fontSize: fontSize),
        ),
        _buildItem(context, controller2, '舒张压', onSubmitted),
      ],
    );
  }

  Widget _buildItem(
    BuildContext context,
    TextEditingController controller,
    String hintText,
    void Function() onSubmitted,
  ) {
    const fontSize = 20.0;
    const height = 56.0;
    return Expanded(
      child: SizedBox(
        height: height,
        child: TextField(
          controller: controller,
          readOnly: false,
          autofocus: true,
          keyboardType: const TextInputType.numberWithOptions(
              decimal: true), // 允许输入数字和小数点
          inputFormatters: [
            FilteringTextInputFormatter.allow(
              RegExp(r'^\d+\.?\d{0,2}'),
            ), // 只允许输入数字和小数点,俩位小数
          ],
          style: const TextStyle(fontSize: fontSize),
          decoration: InputDecoration(
            border: const UnderlineInputBorder(
              borderRadius: BorderRadius.zero,
              borderSide: BorderSide(),
            ),
            enabledBorder: const UnderlineInputBorder(
              borderRadius: BorderRadius.zero,
              borderSide: BorderSide(
                color: Colors.black54,
              ),
            ),
            focusedBorder: UnderlineInputBorder(
              borderRadius: BorderRadius.zero,
              borderSide: BorderSide(
                color: Theme.of(context).primaryColor.withOpacity(.4),
              ),
            ),
            filled: true,
            fillColor: Colors.white,
            contentPadding: const EdgeInsets.symmetric(
              vertical: (height - fontSize * 1.2) / 2,
              horizontal: 8,
            ),
            hintStyle: const TextStyle(fontSize: fontSize),
            labelStyle: const TextStyle(fontSize: fontSize),
            hintText: hintText,
            isCollapsed: true,
          ),
          onSubmitted: (value) {
            onSubmitted.call();
          },
        ),
      ),
    );
  }
}

// ignore: must_be_immutable
class BloodPressure extends StatefulWidget {
  const BloodPressure({
    super.key,
    // required this.currentValue,
    // required this.bloodPressure,
  });
  // Map<String, dynamic> currentValue;
  // Function(Map<String, dynamic>) bloodPressure;
  @override
  State<BloodPressure> createState() => _ExamBloodPressureState();
}

class _ExamBloodPressureState extends State<BloodPressure> {
  var controller = Get.find<MedicalController>();
  PressureStatus pressureStatus = PressureStatus.left;
  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();
  }

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

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

        worker!.connectErrorEvent.removeListener(_onConnectFail);
        worker!.connectedEvent.removeListener(_onConnectSuccess);
        worker!.liveUpdateEvent.removeListener(_onLiveUpdate);
        worker!.resultUpdateEvent.removeListener(_onSuccess);
        worker!.disconnectedEvent.removeListener(_onDisconnected);
      }
    } catch (err) {
      print(err);
    }
  }

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

  void _onLiveUpdate(_, int e) {
    logger.i("血压值更新：$e");
    setState(() {
      liveValue = e;
    });
  }

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

      /// 这是第三方需要的数据
      controller.diagnosisDataValue['NIBP'] = {
        'Sbp': e.systolicPressure.toString(),
        'Dbp': e.diastolicPressure.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++;
      disconnect();
      loadListeners();
    } 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}');
    if (errorCount < 3) {
      print('设备连接中断:${worker!.mac},$errorCount');
      errorCount++;
      disconnect();
      loadListeners();
    } else {
      isConnectFail = true;
    }
    _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;
              worker?.connect();
              setState(() {
                _connectStatus = WorkerStatus.connecting;
                isConnectFail = false;
              });
            },
            icon: const Icon(Icons.refresh),
            iconSize: 32,
          ),
        ],
      ),
    );
  }

  Widget _buildLeftOrRightBloodPressure() {
    return Positioned(
      top: 130,
      left: 38,
      child: AnimatedToggle(
        values: const ['左侧', '右侧'],
        onToggleCallback: (value) {
          pressureStatus = value;
          setState(() {});
        },
        statusValue: pressureStatus,
        buttonColor: Theme.of(context).primaryColor,
        backgroundColor: const Color(0xFFB5C1CC),
        textColor: const Color(0xFFFFFFFF),
      ),
      // child: Text('Toggle Value : $_toggleValue'),
    );
  }

  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,
              ],
            ),
          ),
        ),
      ],
    );
  }
}
