/*
 * @Descripttion: 
 * @version: 
 * @Author: guanxiaoxin
 * @Date: 2023-10-16 20:14:45
 * @LastEditors: guanxiaoxin
 * @LastEditTime: 2023-10-21 15:06:15
 * @FilePath: \VNoteApp\lib\pages\check\widgets\configurable_card.dart
 */
import 'dart:convert';

import 'package:fis_jsonrpc/rpc.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vnoteapp/architecture/storage/text_storage.dart';
import 'package:vnoteapp/components/button.dart';
import 'package:vnoteapp/components/dialog_input.dart';
import 'package:vnoteapp/components/dialog_number.dart';
import 'package:vnoteapp/components/dynamic_drawer.dart';
import 'package:vnoteapp/managers/interfaces/template.dart';
import 'package:vnoteapp/pages/check/models/form.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_blood_pressure.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_blood_sugar.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_body_temperature.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_body_weight.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_boold_oxygen.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_check_box.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_input.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_number_input.dart';
import 'dart:math' as math;

import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_radio.dart';
import 'package:vnoteapp/pages/check/widgets/exam_configurable/exam_radio_score.dart';

const double _width = 170;
const double _height = 38;
String tw = '00.0';

class ConfigurableCard extends StatefulWidget {
  final String cardKey;
  final Function(String, String, dynamic) callBack;
  final Widget? followUpWidget;
  final String? patientCode;
  final String? examData;
  const ConfigurableCard({
    super.key,
    required this.cardKey,
    required this.callBack,
    this.followUpWidget,
    this.patientCode,
    this.examData,
  });

  @override
  State<ConfigurableCard> createState() => _ConfigurableFormState();
}

class _ConfigurableFormState extends State<ConfigurableCard> {
  /// 当前最新的模板的键值对
  Map<String, dynamic> templateRelation = {};

  /// 当前模板数据
  List<FormObject> currentTemplate = [];

  /// 当前title的下标
  int currentTitleIndex = 0;

  Map<String, dynamic> formValue = {};
  var scaffoldKey = GlobalKey<ScaffoldState>();

  final _templateManager = Get.find<ITemplateManager>();
  final arrowHeight = math.tan(120 / 180) * (_height / 2);

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

  @override
  void dispose() {
    super.dispose();
  }

  /// TODO BAKA 替换manager
  Future<void> fetchTemplateIndex() async {
    try {
      /// 获取模板的键值对
      String? templates;
      templates = await _templateManager.readTemplate('templateRelation');
      templateRelation = jsonDecode(templates!);
      fetchTemplate(widget.cardKey);

      TextStorage t = TextStorage(
        fileName: widget.cardKey,
        directory: "patient/${widget.patientCode}/exam/2023",
      );
      String value = await t.read() ?? '';

      print(value);
      if (value.isNotEmpty) {
        formValue = jsonDecode(value);
      }
      // formValue = jsonDecode(value);
      if (widget.examData?.isNotEmpty ?? false) {
        formValue = jsonDecode(widget.examData!);
      }
      formValue.forEach(
        (key, value) {
          if (value is List) {
            formValue[key] = List<String>.from(formValue[key]);
          }
        },
      );
      setState(() {});
      print(formValue);
    } catch (error) {
      print('发生错误: $error');
    }
  }

  Future<void> fetchTemplate(String key) async {
    try {
      if (templateRelation[key] == null) {
        currentTemplate = [];
        setState(() {});
        return;
      }
      var template =
          await _templateManager.readTemplate(templateRelation[key]!);
      String templateContent =
          TemplateDTO.fromJson(jsonDecode(template!)).templateContent!;
      List<Map<String, dynamic>> list =
          jsonDecode(templateContent).cast<Map<String, dynamic>>();
      for (var i in list) {
        if (i['children'] != null) {
          List<FormObject> currentChildren = [];
          for (var j in i['children']) {
            currentChildren.add(FormObject.fromJson(j));
          }
          i['children'] = currentChildren;
        }
        currentTemplate.add(FormObject.fromJson(i));
      }

      // var list = jsonDecode(templateContent).cast<Map<String, dynamic>>();
      // if (list == null) {
      //   currentTemplate = [];
      // } else {
      //   currentTemplate = updateChildren(list);
      // }

      // TextStorage t = TextStorage(
      //   fileName: key,
      //   directory: "template",
      // );
      // await t.save(jsonEncode(currentTemplate));

      print(currentTemplate);
      setState(() {});
    } catch (error) {
      print('发生错误: $error');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      endDrawer: VDynamicDrawerWrapper(scaffoldKey: scaffoldKey),
      resizeToAvoidBottomInset: false,
      body: Column(
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const SizedBox(
                width: 16,
              ),
              Container(
                margin: const EdgeInsets.only(top: 8),
                width: 130,
                height: 54,
                child: VButton(
                  onTap: () => {Get.back()},
                  child: const Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(Icons.arrow_back_ios_new, size: 24),
                      SizedBox(
                        width: 8,
                      ),
                      Text("返回", style: TextStyle(fontSize: 20)),
                    ],
                  ),
                ),
              ),
              Expanded(
                child: Container(
                  padding:
                      const EdgeInsets.symmetric(vertical: 16, horizontal: 10),
                  child: _buildTitleList(),
                ),
              ),
              Container(
                margin: const EdgeInsets.only(top: 8, right: 16),
                width: 130,
                height: 54,
                child: VButton(
                  onTap: () {
                    widget
                        .callBack(
                          widget.cardKey,
                          templateRelation[widget.cardKey]!,
                          jsonEncode(formValue),
                        )
                        .call();
                    Get.back();
                  },
                  child: const Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(Icons.save, size: 24),
                      SizedBox(
                        width: 8,
                      ),
                      Text("保存", style: TextStyle(fontSize: 20)),
                    ],
                  ),
                ),
              ),
            ],
          ),
          Expanded(
            child: Stack(
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    _buildDiagram(),
                    _buildContent(),
                  ],
                ),
                if (currentTitleIndex != currentTemplate.length - 1)
                  _buildPositionedButton(
                    () async {
                      currentTitleIndex++;
                      setState(() {});
                    },
                    right: -30,
                  ),
              ],
            ),
          )
        ],
      ),
    );
  }

  Widget buildSingleItem(Widget item, int span) {
    return FractionallySizedBox(
      widthFactor: span == 24 ? 1 : 0.5,
      child: item,
    );
  }

  Widget buildWidget(FormObject? currentFormObject) {
    Map<String, Widget Function(FormObject)> widgetMap = {
      'checkbox': _buildCheckBox,
      'numberInput': _buildNumberInput,
      'input': _buildInput,
      'radio': _buildRadio,
      'radioScore': _buildRadioScore,
      'bloodPressure': _buildBloodPressure,
      'bodyTemperature': _buildBodyTemperature,
      'weight': _buildBodyWeight,
      'sugar': _buildBodySugar,
      'bloodOxygen': _buildBloodOxygen,
    };
    Widget Function(FormObject) builder =
        widgetMap[currentFormObject?.type] ?? _buildInput;
    return builder(currentFormObject!);
  }

  Widget waterCardList() {
    int itemCount = 0;
    if (currentTemplate.isNotEmpty) {
      itemCount = currentTemplate[currentTitleIndex].children?.length ?? 0;
    }
    List<Widget> items = List.generate(itemCount, (index) {
      FormObject? currentFormObject =
          currentTemplate[currentTitleIndex].children?[index];
      int span = currentFormObject?.span ?? 12;
      return buildSingleItem(buildWidget(currentFormObject), span);
    });

    return Scrollbar(
      thumbVisibility: true,
      child: SingleChildScrollView(
        child: Container(
          alignment: Alignment.topCenter,
          padding: const EdgeInsets.all(15),
          child: Wrap(
            runSpacing: 20, // 纵向元素间距
            alignment: WrapAlignment.start,
            children: items,
          ),
        ),
      ),
    );
  }

  /// title标签
  Widget _buildTitleList() {
    return Wrap(
      runSpacing: 10, // 设置子小部件之间的间距
      spacing: -12,
      alignment: WrapAlignment.start,
      children: currentTemplate.asMap().entries.map(
        (e) {
          /// TODO 这边需要改下
          MaterialColor currentColors = Colors.grey;
          e.value.children?.forEach((element) {
            if (formValue.containsKey(element.key)) {
              currentColors = Colors.green;
            }
          });
          return TitleClipRect(
            title: e.value.label ?? '',
            color: currentTitleIndex == e.key ? null : currentColors,
            arrowHeight: arrowHeight,
            clickTitle: () {
              currentTitleIndex = e.key;
              setState(() {});
            },
          );
        },
      ).toList(),
    );
  }

  /// 示意图
  Widget _buildDiagram() {
    return Expanded(
      flex: 1,
      child: Stack(
        children: [
          /// TODO BAKA-优化
          ['GXY', 'TNB'].contains(widget.cardKey)
              ? widget.followUpWidget!
              : Container(
                  alignment: Alignment.topCenter,
                  margin: const EdgeInsets.all(16).copyWith(top: 0),
                  child: Image.asset(
                    'assets/images/exam/normalMeasurementChart.png',
                    height: double.infinity,
                    fit: BoxFit.fitWidth, // 设置图像的适应方式
                  ),
                ),
          if (currentTitleIndex != 0)
            _buildPositionedButton(
              () async {
                if (currentTitleIndex == 0) {
                  Get.back();
                } else {
                  currentTitleIndex--;
                  setState(() {});
                }
              },
              left: -30,
            ),
        ],
      ),
    );
  }

  /// 按钮
  Widget _buildPositionedButton(Function onTap, {double? right, double? left}) {
    return Positioned(
      right: right,
      left: left,
      bottom: 0,
      top: 0,
      child: Container(
        width: 100,
        height: 100,
        alignment: Alignment.centerLeft,
        child: InkWell(
          onTap: () => onTap.call(),
          child: Container(
            width: 100,
            height: 100,
            padding: const EdgeInsets.all(20),
            alignment:
                right.isNull ? Alignment.centerRight : Alignment.centerLeft,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(50),
              color: Theme.of(context).primaryColor.withOpacity(
                    .8,
                  ),
            ),
            child: Image.asset(
              right.isNull
                  ? "assets/images/exam/left-arrow.png"
                  : "assets/images/exam/right-arrow.png",
              width: 40,
              height: 40,
              color: Colors.white,
              fit: BoxFit.contain,
            ),
          ),
        ),
      ),
    );
  }

  /// 主页面
  Widget _buildContent() {
    return Expanded(
      flex: 2,
      child: waterCardList(),
    );
  }

  /// 多选框组件
  Widget _buildCheckBox(FormObject currentFormObject) {
    List<Option> options = currentFormObject.options ?? [];
    List<String> currentSelectedCheckBox =
        formValue[currentFormObject.key!] ?? [];

    void selectCheckBoxChange(Option e) {
      if (currentSelectedCheckBox.contains(e.value)) {
        currentSelectedCheckBox.remove(e.value);
      } else {
        currentSelectedCheckBox.add(e.value ?? '');
      }
      formValue[currentFormObject.key!] = currentSelectedCheckBox;
      setState(() {});
    }

    return ExamCheckBox(
      options: options,
      currentSelectedCheckBox: currentSelectedCheckBox,
      currentFormObject: currentFormObject,
      selectCheckBoxChange: selectCheckBoxChange,
    );
  }

  /// 数字输入框组件
  Widget _buildNumberInput(FormObject currentFormObject) {
    String currentInputValue = formValue[currentFormObject.key!] ?? '';
    if ((formValue['Height']?.isNotEmpty ?? false) &&
        (formValue['Weight']?.isNotEmpty ?? false)) {
      formValue['Bmi'] = (double.parse(formValue['Weight']) /
              ((double.parse(formValue['Height']) / 100) *
                  (double.parse(formValue['Height']) / 100)))
          .toStringAsFixed(2);
    }
    Future<void> commonInput() async {
      String? result = await VDialogNumber(
        title: currentFormObject.label,
        initialValue: formValue[currentFormObject.key],
      ).show();

      if (result?.isNotEmpty ?? false) {
        formValue[currentFormObject.key!] = result;
        currentInputValue = formValue[currentFormObject.key!];

        setState(() {});
      }
    }

    void specialInput(String value) {
      formValue[currentFormObject.key!] = value;
      currentInputValue = formValue[currentFormObject.key!];
      setState(() {});
    }

    return ExamNumberInput(
      currentInputValue: currentInputValue,
      commonInput: commonInput,
      specialInput: specialInput,
      currentFormObject: currentFormObject,
    );
  }

  Widget _buildInput(FormObject currentFormObject) {
    String currentInputValue = formValue[currentFormObject.key!] ?? '';
    Future<void> commonInput() async {
      String? result = await VDialogInput(
        title: currentFormObject.label,
        initialValue: formValue[currentFormObject.key],
      ).show();
      if (result?.isNotEmpty ?? false) {
        formValue[currentFormObject.key!] = result;
        currentInputValue = formValue[currentFormObject.key!];
        setState(() {});
      }
    }

    return ExamInput(
      currentInputValue: currentInputValue,
      commonInput: commonInput,
      currentFormObject: currentFormObject,
    );
  }

  /// 血压组件
  Widget _buildBloodPressure(FormObject currentFormObject) {
    String? highPressureKey = currentFormObject.childrenKey?.first;
    String? lowPressureKey = currentFormObject.childrenKey?.last;
    List<String> currentBloodPressureValue = [
      formValue[highPressureKey] ?? '',
      formValue[lowPressureKey] ?? ''
    ];
    Future<void> commonBloodPressure() async {
      // String? result = await VDialogBloodPressure(
      //   title: currentFormObject.label,
      //   placeholder: '请输入',
      //   initialValue: currentBloodPressureValue,
      // ).show();
      // if (result?.isNotEmpty ?? false) {
      //   List resultList = jsonDecode(result!);
      //   formValue[highPressureKey!] = resultList.first;
      //   formValue[lowPressureKey!] = resultList.last;
      //   currentBloodPressureValue = [
      //     formValue[highPressureKey] ?? '',
      //     formValue[lowPressureKey] ?? ''
      //   ];
      //   formValue['Left'] = '111';
      //   setState(() {});
      // }
    }

    return const ExamBloodPressure(
        // currentFormObject: currentFormObject,
        // currentBloodPressureValue: currentBloodPressureValue,
        // bloodPressure: commonBloodPressure,
        );
  }

  /// 单选框组件
  Widget _buildRadio(FormObject currentFormObject) {
    List<Option> options = currentFormObject.options ?? [];
    String currentSelected = formValue[currentFormObject.key!] ?? "";

    void selectRaidoChange(Option e) {
      currentSelected = e.value ?? '';
      formValue[currentFormObject.key!] = currentSelected;
      setState(() {});
    }

    return ExamRadio(
      options: options,
      currentFormObject: currentFormObject,
      selectRaidoChange: selectRaidoChange,
      currentSelected: currentSelected,
    );
  }

  Widget _buildRadioScore(FormObject currentFormObject) {
    print(currentFormObject.toJson());
    List<Option> options = currentFormObject.options ?? [];
    String currentSelected =
        formValue[currentFormObject.childrenKey!.first] ?? "";

    void selectRaidoChange(Option e) {
      currentSelected = e.value ?? '';
      formValue[currentFormObject.childrenKey!.first] = currentSelected;
      setState(() {});
    }

    return ExamRadioScore(
      options: options,
      currentFormObject: currentFormObject,
      selectRaidoChange: selectRaidoChange,
      currentSelected: currentSelected,
    );
  }

  /// 体温组件
  Widget _buildBodyTemperature(FormObject currentFormObject) {
    String currentInputValue = formValue[currentFormObject.key!] ?? '';

    void bodyTemperatureInput(String value) {
      formValue[currentFormObject.key!] = value;
      currentInputValue = formValue[currentFormObject.key!];
      setState(() {});
    }

    return ExamBodyTemperature(
      currentInputValue: currentInputValue,
      bodyTemperatureInput: bodyTemperatureInput,
      currentFormObject: currentFormObject,
    );
  }

  /// 血氧
  Widget _buildBloodOxygen(FormObject currentFormObject) {
    Map<String, dynamic> currentValue = formValue;

    void bloodOxygenInput(Map<String, dynamic> bloodOxygen) {
      formValue['Pulse_Frequency'] = bloodOxygen['Pulse_Frequency'];
      formValue['Spo2'] = bloodOxygen['Spo2'];
      currentValue = bloodOxygen;
      setState(() {});
    }

    return ExamBloodOxygen(
      currentValue: currentValue,
      bloodOxygenInput: bloodOxygenInput,
    );
  }

  /// 体重
  Widget _buildBodyWeight(FormObject currentFormObject) {
    String currentInputValue = formValue[currentFormObject.key!] ?? '';

    void bodyWeightInput(String value) {
      formValue[currentFormObject.key!] = value;
      currentInputValue = formValue[currentFormObject.key!];
      setState(() {});
    }

    return ExamBodyWeight(
      currentInputValue: currentInputValue,
      bodyWeightInput: bodyWeightInput,
      currentFormObject: currentFormObject,
    );
  }

  /// 血糖
  Widget _buildBodySugar(FormObject currentFormObject) {
    String currentInputValue = formValue[currentFormObject.key!] ?? '';

    void bloodSugarInput(String value) {
      formValue[currentFormObject.key!] = value;
      currentInputValue = formValue[currentFormObject.key!];
      setState(() {});
    }

    return ExamBloodSugar(
      currentInputValue: currentInputValue,
      bloodSugarInput: bloodSugarInput,
      currentFormObject: currentFormObject,
    );
  }
}

class TitleClipRect extends StatelessWidget {
  const TitleClipRect({
    super.key,
    this.color = Colors.grey,
    required this.title,
    required this.arrowHeight,
    required this.clickTitle,
  });

  final Color? color;
  final String title;
  final double arrowHeight;
  final Function clickTitle;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        clickTitle.call();
      },
      customBorder: HoleShapeBorder(arrowHeight),
      child: Card(
        margin: const EdgeInsets.all(0),
        shape: HoleShapeBorder(arrowHeight),
        color: color,
        elevation: color == null ? 5 : 0,
        shadowColor: Theme.of(context).primaryColor.withOpacity(0.8),
        child: ClipPath(
          clipper: _TitleClipPath(arrowHeight),
          child: Container(
            width: _width,
            height: _height,
            padding: const EdgeInsets.symmetric(
              horizontal: 15,
            ),
            decoration: BoxDecoration(
              boxShadow: [
                BoxShadow(
                  color: Theme.of(context).primaryColor.withOpacity(1),
                ),
              ],
              color: color,
            ),
            alignment: Alignment.center,
            child: FittedBox(
              child: Text(
                title,
                style: const TextStyle(color: Colors.white, fontSize: 20),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

class _TitleClipPath extends CustomClipper<Path> {
  final double arrowHeight;

  _TitleClipPath(this.arrowHeight);

  @override
  Path getClip(Size size) {
    final height = size.height;
    final arrowBase = height / 2;
    // final arrowPLine = math.tan(120 / 180) * arrowBase;
    final path = Path();
    path.moveTo(0, 0); // 左上角
    path.lineTo(size.width - arrowHeight, 0); // 右上角
    path.lineTo(size.width, arrowBase); // 右端点
    path.lineTo(size.width - arrowHeight, height); // 右下角

    path.lineTo(0, height); // 左下角
    path.lineTo(arrowHeight, arrowBase); // 左端点
    path.lineTo(0, 0); // 左上角

    return path;
  }

  @override
  bool shouldReclip(covariant CustomClipper<Path> oldClipper) {
    return false;
  }
}

class HoleShapeBorder extends ShapeBorder {
  final Offset offset;
  final double size;
  final double arrowHeight;
  const HoleShapeBorder(this.arrowHeight,
      {this.offset = const Offset(0, 0), this.size = 0});

  @override
  EdgeInsetsGeometry get dimensions => throw UnimplementedError();

  @override
  void paint(Canvas canvas, Rect rect, {TextDirection? textDirection}) {}

  @override
  Path getOuterPath(Rect rect, {TextDirection? textDirection}) {
    var path = Path();

    final height = rect.size.height;
    final arrowBase = height / 2;
    path.moveTo(0, 0); // 左上角
    path.lineTo(rect.size.width - arrowHeight, 0); // 右上角
    path.lineTo(rect.size.width, arrowBase); // 右端点
    path.lineTo(rect.size.width - arrowHeight, height); // 右下角

    path.lineTo(0, height); // 左下角
    path.lineTo(arrowHeight, arrowBase); // 左端点
    path.lineTo(0, 0); // 左上角

    return path;
  }

  @override
  ShapeBorder scale(double t) {
    // TODO: implement scale
    throw UnimplementedError();
  }

  @override
  Path getInnerPath(Rect rect, {TextDirection? textDirection}) {
    // TODO: implement getInnerPath
    throw UnimplementedError();
  }
}

// ClipPath(
//                                                     clipper: TriangleClipper(),
//                                                     child: Container(
//                                                       width: 50,
//                                                       height: 50,
//                                                       padding:
//                                                           const EdgeInsets.all(
//                                                               2),
//                                                       alignment:
//                                                           Alignment.topRight,
//                                                       decoration:
//                                                           const BoxDecoration(
//                                                         color: Colors.blue,
//                                                         borderRadius:
//                                                             BorderRadius.only(
//                                                           topRight:
//                                                               Radius.circular(
//                                                             8,
//                                                           ),
//                                                         ),
//                                                       ),
//                                                       child: const Icon(
//                                                         Icons.check,
//                                                         color: Colors.white,
//                                                       ),
//                                                     ))
// class TriangleClipper extends CustomClipper<Path> {
//   @override
//   Path getClip(Size size) {
//     final path = Path()
//       ..moveTo(size.width, 0)
//       ..lineTo(0, 0)
//       ..lineTo(size.width, size.height)
//       ..close();
//     return path;
//   }

//   @override
//   bool shouldReclip(CustomClipper<Path> oldClipper) => false;
// }
