import 'package:flutter/material.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/sugar.dart';
import 'package:vnote_device_plugin/models/exams/error.dart';
import 'package:vnote_device_plugin/models/exams/sugar.dart';
import 'package:vitalapp/managers/interfaces/models/device.dart';
import 'package:vitalapp/pages/check/widgets/exam_configurable/exam_card.dart';

import 'package:vitalapp/components/dialog_number.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:fis_common/logger/logger.dart';

// ignore: must_be_immutable
class BloodSugar extends StatefulWidget {
  const BloodSugar({
    super.key,
  });

  @override
  State<BloodSugar> createState() => _ExamBloodSugarState();
}

class _ExamBloodSugarState extends State<BloodSugar> {
  var controller = Get.find<MedicalController>();
  late DeviceControllerManager sugar;
  SugarDeviceWorker? worker;
  bool isConnectFail = false;
  WorkerStatus _connectStatus = WorkerStatus.connecting;
  int errorCount = 0;
  String _bloodStatus = '';

  late String _value = controller.diagnosisDataValue['GLU']?['sugar'] ?? '';
  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      initSugar();
    });
    super.initState();
  }

  void loadListeners() {
    worker!.successEvent.addListener(_onSuccess);
    worker!.connectErrorEvent.addListener(_onConnectFail);
    worker!.connectedEvent.addListener(_onConnectSuccess);
    worker!.disconnectedEvent.addListener(_onDisconnected);
    worker!.warnEvent.addListener(_onWarn);
    worker!.statusEvent.addListener(_onstatus);
  }

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

    loadListeners();
    connect();
  }

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

  Future<void> initSugar() async {
    currentDevice();
    await initData();
  }

  Future<void> initData() async {
    _value = controller.diagnosisDataValue['GLU']?['sugar'] ?? '';
    logger.i('_ExamBloodSugarState initData sugar:$_value');
    setState(() {});
  }

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

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

  void releaseListeners() {
    worker!.connectErrorEvent.removeListener(_onConnectFail);
    worker!.connectedEvent.removeListener(_onConnectSuccess);
    worker!.successEvent.removeListener(_onSuccess);
    worker!.disconnectedEvent.removeListener(_onDisconnected);
    worker!.warnEvent.removeListener(_onWarn);
    worker!.statusEvent.removeListener(_onstatus);
  }

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

  void _onWarn(_, ExamError e) {
    _bloodStatus = e.message ?? '';
    logger.i("BloodSugar - warn: $_bloodStatus.");
    setState(() {});
  }

  void _onstatus(_, ExamError e) {
    _bloodStatus = e.message ?? '';
    logger.i("BloodSugar - status: $_bloodStatus.");
    setState(() {});
  }

  void _onSuccess(_, SugarExamData e) {
    logger.i("BloodSugar - value callback: ${e.sugar}.");
    setState(() {
      _value = e.sugar.toString();
      controller.diagnosisDataValue['GLU'] = {'sugar': _value};
      controller.saveCachedRecord();
      _connectStatus = WorkerStatus.connected;
    });
  }

  void _onConnectFail(sender, e) {
    logger.i("BloodSugar - connect fail.");
    if (errorCount < 3) {
      errorCount++;
      tryReconnect();
    } else {
      isConnectFail = true;
    }
    _bloodStatus = '';

    _connectStatus = WorkerStatus.connectionFailed;
    setState(() {});
  }

  void _onConnectSuccess(sender, e) {
    logger.i("BloodSugar - connect success.");

    _connectStatus = WorkerStatus.connected;
    errorCount = 0;
    _bloodStatus = '';

    isConnectFail = false;
    setState(() {});
  }

  void _onDisconnected(sender, e) {
    logger.i("BloodSugar - disconnected.");
    errorCount = 0;
    tryReconnect();
    _bloodStatus = '';

    _connectStatus = WorkerStatus.disconnected;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        _buildSugar(),
        if (!isConnectFail)
          DeviceStatusPosition(
            deviceStatus: DeviceStatus(connectStatus: _connectStatus),
          )
        else
          _buildErrorButton(),
        Positioned(
          right: 10,
          top: 60,
          child: Text(
            _bloodStatus,
            style: const TextStyle(
              fontSize: 18,
            ),
          ),
        ),
      ],
    );
  }

  /// 需要封装一下
  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,
          ),
        ],
      ),
    );
  }

  Widget _buildSugar() {
    return ExamCard(
      title: '',
      clickCard: () {
        _inputSugar();
      },
      content: Row(
        children: [
          const SizedBox(
            width: 25,
          ),
          const Text(
            '血糖',
            style: TextStyle(fontSize: 25),
          ),
          const Expanded(
            child: SizedBox(),
          ),
          SizedBox(
            height: 100,
            child: FittedBox(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Text(
                    _value.isEmpty ? '--' : _value,
                    style: const TextStyle(
                      fontSize: 80,
                      color: Colors.black,
                    ),
                  ),
                  const Text(
                    '    mmol/L',
                    style: TextStyle(fontSize: 25),
                  ),
                  const SizedBox(
                    width: 15,
                  )
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Future<void> _inputSugar() async {
    String? result = await VDialogNumber(
      title: '血糖',
      initialValue: _value,
    ).show();
    if (result?.isNotEmpty ?? false) {
      _value = result ?? '';
      controller.diagnosisDataValue['GLU'] = {'sugar': _value};
      controller.saveCachedRecord();
    }
    setState(() {});
  }
}
