/// 计算公式 - 立罐灭火冷却用水量
///
///
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';
import './common_formula.dart';

/// 立罐灭火冷却用水量
class VerticalTankWater extends StatefulWidget {
  const VerticalTankWater({Key key}) : super(key: key);

  @override
  _VerticalTankWaterState createState() => _VerticalTankWaterState();
}

class _VerticalTankWaterState extends State<VerticalTankWater>
    with SingleTickerProviderStateMixin {
  TabController tabController;
  GlobalKey<FormState> oneformKeyformKey = GlobalKey<FormState>();
  Map<String, dynamic> _oneConfig = {
    'strength': '0.167',
    'ratio': 0.97,
    'time': '30.0'
  };

  GlobalKey<FormState> twoformKeyformKey = GlobalKey<FormState>();
  Map<String, dynamic> _twoConfig = {'strength': '0.6', 'time': '6'};

  GlobalKey<FormState> threeformKeyformKey = GlobalKey<FormState>();
  Map<String, dynamic> _threeConfig = {'strength': '0.35', 'time': '6'};

  @override
  void initState() {
    super.initState();
    tabController = TabController(length: 3, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return FormulaButtonSubmit(
        title: '立罐灭火冷却用水量',
        onSubmit: onSubmit,
        onReset: onReset,
        body: Container(
            child: Column(
          children: [
            Container(
                height: 42,
                child: TabBar(
                  labelColor: Colors.black,
                  isScrollable: true,
                  unselectedLabelColor: Colors.black54,
                  indicatorSize: TabBarIndicatorSize.label,
                  indicatorColor: Colors.lightBlue,
                  tabs: const [
                    Tab(text: '配置泡沫用水量'),
                    Tab(text: '着火罐冷却用水量'),
                    Tab(text: '冷近罐冷却用水量')
                  ],
                  controller: tabController,
                )),
            Expanded(
                child: TabBarView(
              children: [
                CommonFormulaContent(
                  formChild: AmosForm(
                    formKey: oneformKeyformKey,
                    children: renderTabOneForm(context),
                    onChanged: (value) {
                      _oneConfig = value;
                    },
                  ),
                  hasFooter: false,
                ),
                CommonFormulaContent(
                  formChild: AmosForm(
                    formKey: twoformKeyformKey,
                    children: renderTabTwoForm(context),
                    onChanged: (value) {
                      _twoConfig = value;
                    },
                  ),
                  hasFooter: false,
                ),
                CommonFormulaContent(
                  formChild: AmosForm(
                    formKey: threeformKeyformKey,
                    children: renderTabThreeForm(context),
                    onChanged: (value) {
                      _threeConfig = value;
                    },
                  ),
                  hasFooter: false,
                ),
              ],
              controller: tabController,
            ))
          ],
        )));
  }

  List<Widget> renderTabOneForm(BuildContext context) {
    return <Widget>[
      FormItem(
        layout: FormLayout.vertical,
        label: '泡沫混合液供给强度(L/s·m²)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'strength',
          initialValue: _oneConfig['strength'],
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '泡沫混合液含水率',
        invert: true,
        formfield: AmosRadioGroup(
          fieldKey: 'ratio',
          initialValue: _oneConfig['ratio'],
          options: const [
            {'title': '99%', 'value': 0.99},
            {'title': '97%', 'value': 0.97},
            {'title': '94%', 'value': 0.94},
          ],
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '液体燃烧面积(L/s·m²)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'area',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '供液时间(分钟)',
        invert: true,
        formfield: AmosTextNumberField(
          initialValue: _oneConfig['time'],
          fieldKey: 'time',
          maxLines: 1,
        ),
      )
    ];
  }

  List<Widget> renderTabTwoForm(BuildContext context) {
    return <Widget>[
      FormItem(
        layout: FormLayout.vertical,
        label: '着火罐直径(m)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'diameter',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '着火罐冷却水供给强度(L/s·m²)',
        invert: true,
        formfield: AmosTextNumberField(
          initialValue: _twoConfig['strength'],
          fieldKey: 'strength',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '着火罐数量(个)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'count',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '冷却持续时间(小时)',
        invert: true,
        formfield: AmosTextNumberField(
          initialValue: _twoConfig['time'],
          fieldKey: 'time',
          maxLines: 1,
        ),
      )
    ];
  }

  List<Widget> renderTabThreeForm(BuildContext context) {
    return <Widget>[
      FormItem(
        layout: FormLayout.vertical,
        label: '冷近罐直径(m)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'diameter',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '冷近罐冷却水供给强度(L/s·m²)',
        invert: true,
        formfield: AmosTextNumberField(
          initialValue: _threeConfig['strength'],
          fieldKey: 'strength',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '冷近罐数量(个)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'count',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '冷却持续时间(小时)',
        invert: true,
        formfield: AmosTextNumberField(
          initialValue: _threeConfig['time'],
          fieldKey: 'time',
          maxLines: 1,
        ),
      )
    ];
  }

  Widget renderFooter(BuildContext context) {
    return FormFooter(
      padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 15.0),
      child: Flex(direction: Axis.horizontal, children: [
        Expanded(
          flex: 1,
          child: GradientButton(
              color: const Color(0xff345fa6),
              child: const Text('计算'),
              onPressed: () {
                onSubmit(context);
              }),
        ),
        Expanded(
          flex: 1,
          child: GradientButton(
            color: const Color(0xffe3e3e3),
            textColor: const Color(0xff333333),
            child: const Text('重置'),
            onPressed: onReset,
          ),
        )
      ]),
    );
  }

  void onSubmit(context) {
    if (tabController.index == 0) {
      if (!ConfigFoamWaterValue.check(_oneConfig)) {
        shortMessage('计算参数不能为空');
        return;
      }
      ConfigFoamWaterValue ffv = ConfigFoamWaterValue.fromMap(_oneConfig);
      showBottomSheetDialog(
          context: context,
          builder: (BuildContext context) {
            return CalcResultPanel(
                results: ConfigFoamWaterValue.getResult(ffv));
          });
    }
    if (tabController.index == 1) {
      if (!CatchFireValue.check(_twoConfig)) {
        shortMessage('计算参数不能为空');
        return;
      }
      CatchFireValue ffv = CatchFireValue.fromMap(_twoConfig);
      showBottomSheetDialog(
          context: context,
          builder: (BuildContext context) {
            return CalcResultPanel(results: CatchFireValue.getResult(ffv));
          });
    }
    if (tabController.index == 2) {
      if (!ColdFireValue.check(_threeConfig)) {
        shortMessage('计算参数不能为空');
        return;
      }
      ColdFireValue ffv = ColdFireValue.fromMap(_threeConfig);
      showBottomSheetDialog(
          context: context,
          builder: (BuildContext context) {
            return CalcResultPanel(results: ColdFireValue.getResult(ffv));
          });
    }
  }

  void onReset() {
    if (tabController.index == 0) {
      oneformKeyformKey.currentState.reset();
    }
    if (tabController.index == 1) {
      twoformKeyformKey.currentState.reset();
    }
    if (tabController.index == 2) {
      threeformKeyformKey.currentState.reset();
    }
  }
}

/// 配置泡沫用水量
class ConfigFoamWaterValue {
  /// 泡沫混合液供给强度
  double strength;

  /// 泡沫混合液含水率
  double ratio;

  /// 液体燃烧面积
  double area;

  /// 供液时间
  double time;

  ConfigFoamWaterValue({this.strength, this.ratio, this.area, this.time});

  Map toJson() {
    Map map = <String, dynamic>{};
    map['strength'] = strength;
    map['ratio'] = ratio;
    map['area'] = area;
    map['time'] = time;
    return map;
  }

  static bool check(Map<String, dynamic> map) {
    String strength = map['strength'];
    double ratio = map['ratio'];
    String area = map['area'];
    String time = map['time'];

    if (strength == null ||
        strength.isEmpty ||
        ratio == null ||
        area == null ||
        area.isEmpty ||
        time == null ||
        time.isEmpty) {
      return false;
    }
    return true;
  }

  static ConfigFoamWaterValue fromMap(Map<String, dynamic> map) {
    ConfigFoamWaterValue ffv = ConfigFoamWaterValue(
        strength: double.parse(map['strength'] ?? ''),
        ratio: map['ratio'],
        area: double.parse(map['area'] ?? ''),
        time: double.parse(map['time'] ?? ''));
    return ffv;
  }

  /// 计算配置泡沫用水流量(L/s)
  static double calcOne(ConfigFoamWaterValue ffv) {
    double liquid = ffv.strength * ffv.ratio * ffv.area;

    /// 保留两位小数
    return double.parse(liquid.toStringAsFixed(2));
  }

  /// 计算配置泡沫用水量(t)
  static double calcTwo(ConfigFoamWaterValue ffv) {
    double liquid = ffv.strength * ffv.ratio * ffv.area * ffv.time * 60;
    double param = double.parse(liquid.toStringAsFixed(2));
    return double.parse((param / 1000).toStringAsFixed(2));
  }

  /// 计算结果
  static List<Map<String, dynamic>> getResult(ConfigFoamWaterValue ffv) {
    double one = calcOne(ffv);
    double two = calcTwo(ffv);
    List<Map<String, dynamic>> res = [];
    res.add({'title': '配置泡沫用水流量', 'value': '$one L/s'});
    res.add({'title': '配置泡沫用水量', 'value': '$two t'});
    return res;
  }
}

/// 着火罐冷却用水量
class CatchFireValue {
  /// 着火罐冷却水供给强度
  double strength;

  /// 着火罐数量
  double count;

  /// 着火罐直径
  double diameter;

  /// 冷却持续时间
  double time;

  CatchFireValue({this.strength, this.diameter, this.count, this.time});

  Map toJson() {
    Map map = <String, dynamic>{};
    map['strength'] = strength;
    map['diameter'] = diameter;
    map['count'] = count;
    map['time'] = time;
    return map;
  }

  static bool check(Map<String, dynamic> map) {
    String strength = map['strength'];
    String diameter = map['diameter'];
    String count = map['count'];
    String time = map['time'];

    if (strength == null ||
        strength.isEmpty ||
        diameter == null ||
        diameter.isEmpty ||
        count == null ||
        count.isEmpty ||
        time == null ||
        time.isEmpty) {
      return false;
    }
    return true;
  }

  static CatchFireValue fromMap(Map<String, dynamic> map) {
    CatchFireValue ffv = CatchFireValue(
        strength: double.parse(map['strength'] ?? ''),
        diameter: double.parse(map['diameter'] ?? ''),
        count: double.parse(map['count'] ?? ''),
        time: double.parse(map['time'] ?? ''));
    return ffv;
  }

  /// 计算着火罐冷却用水流量(L/s)
  static double calcOne(CatchFireValue ffv) {
    double liquid = double.parse(
        (pi * ffv.diameter * ffv.strength * ffv.count).toStringAsFixed(2));
    return liquid;
  }

  /// 计算着火罐冷却用水量(t)
  static double calcTwo(CatchFireValue ffv) {
    double liquid = double.parse(
        (pi * ffv.diameter * ffv.strength * ffv.count * ffv.time * 3600)
            .toStringAsFixed(2));

    return double.parse((liquid / 1000).toStringAsFixed(2));
  }

  /// 计算结果
  static List<Map<String, dynamic>> getResult(CatchFireValue ffv) {
    double one = calcOne(ffv);
    double two = calcTwo(ffv);
    List<Map<String, dynamic>> res = [];
    res.add({'title': '着火罐冷却用水流量', 'value': '$one L/s'});
    res.add({'title': '着火罐冷却用水量', 'value': '$two t'});
    return res;
  }
}

/// 冷近罐冷却用水量
class ColdFireValue {
  /// 冷近罐冷却水供给强度
  double strength;

  /// 冷近罐数量
  double count;

  /// 冷近罐直径
  double diameter;

  /// 冷却持续时间
  double time;

  ColdFireValue({this.strength, this.diameter, this.count, this.time});

  Map toJson() {
    Map map = <String, dynamic>{};
    map['strength'] = strength;
    map['diameter'] = diameter;
    map['count'] = count;
    map['time'] = time;
    return map;
  }

  static bool check(Map<String, dynamic> map) {
    String strength = map['strength'];
    String diameter = map['diameter'];
    String count = map['count'];
    String time = map['time'];

    if (strength == null ||
        strength.isEmpty ||
        diameter == null ||
        diameter.isEmpty ||
        count == null ||
        count.isEmpty ||
        time == null ||
        time.isEmpty) {
      return false;
    }
    return true;
  }

  static ColdFireValue fromMap(Map<String, dynamic> map) {
    ColdFireValue ffv = ColdFireValue(
        strength: double.parse(map['strength'] ?? ''),
        diameter: double.parse(map['diameter'] ?? ''),
        count: double.parse(map['count'] ?? ''),
        time: double.parse(map['time'] ?? ''));
    return ffv;
  }

  /// 计算冷近罐冷却用水量(L/s)
  static double calcOne(ColdFireValue ffv) {
    double liquid = double.parse(
        (pi * ffv.diameter * ffv.strength * ffv.count * 0.5)
            .toStringAsFixed(2));
    return liquid;
  }

  /// 计算着火罐冷却用水量(t)
  static double calcTwo(ColdFireValue ffv) {
    double liquid = double.parse(
        (pi * ffv.diameter * ffv.strength * ffv.count * ffv.time * 3600 * 0.5)
            .toStringAsFixed(2));

    return double.parse((liquid / 1000).toStringAsFixed(2));
  }

  /// 计算结果
  static List<Map<String, dynamic>> getResult(ColdFireValue ffv) {
    double one = calcOne(ffv);
    double two = calcTwo(ffv);
    List<Map<String, dynamic>> res = [];
    res.add({'title': '冷近罐冷却用水流量', 'value': '$one L/s'});
    res.add({'title': '冷近罐冷却用水量', 'value': '$two t'});
    return res;
  }
}
