/// 计算公式 - 泡沫原液量
///
///

import 'package:flutter/material.dart';
import 'package:amos_flutter_ui/amos_flutter_ui.dart';

import './common_formula.dart';

/// 泡沫原液量
class FoamFluid extends StatefulWidget {
  const FoamFluid({Key key}) : super(key: key);

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

class _FoamFluidState extends State<FoamFluid> {
  GlobalKey<FormState> formKey = GlobalKey<FormState>();
  Map<String, dynamic> _config = {'mixRatio': 0.01, 'gunType': 4};

  @override
  Widget build(BuildContext context) {
    return FormulaButtonSubmit(
      title: '泡沫原液量计算',
      formChild: AmosForm(
        formKey: formKey,
        children: renderAmosForm(context),
        onChanged: (value) {
          print('AmosForm changed: ${value.toString()}');
          _config = value;
        },
      ),
      onSubmit: onSubmit,
      onReset: onReset,
    );
  }

  List<Widget> renderAmosForm(BuildContext context) {
    return <Widget>[
      FormItem(
        layout: FormLayout.vertical,
        label: '泡沫混合液供给强度(L/s·m²)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'strength',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '泡沫混合比',
        invert: true,
        formfield: AmosRadioGroup(
          fieldKey: 'mixRatio',
          initialValue: _config['mixRatio'],
          layout: RadioGroupLayout.horizontal,
          mini: true,
          options: const [
            {'title': '1%', 'value': 0.01},
            {'title': '2%', 'value': 0.02},
            {'title': '6%', 'value': 0.06},
          ],
        ),
      ),
      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(
          fieldKey: 'time',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '泡沫枪型号',
        invert: true,
        formfield: AmosRadioGroup(
          fieldKey: 'gunType',
          initialValue: _config['gunType'],
          layout: RadioGroupLayout.horizontal,
          mini: true,
          options: const [
            {'title': 'PQ4', 'value': 4},
            {'title': 'PQ8', 'value': 8},
            {'title': 'PQ16', 'value': 16},
          ],
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '泡沫炮流量(L/s)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'liquidRate',
          maxLines: 1,
        ),
      ),
      FormItem(
        layout: FormLayout.vertical,
        label: '泡沫钩管流量(L/s)',
        invert: true,
        formfield: AmosTextNumberField(
          fieldKey: 'hookRate',
          maxLines: 1,
        ),
      ),
    ];
  }

  void onSubmit(context) {
    if (!FoamFluidValue.check(_config)) {
      shortMessage('计算参数不能为空');
      return;
    }

    FoamFluidValue ffv = FoamFluidValue.fromMap(_config);

    showBottomSheetDialog(
        context: context,
        builder: (BuildContext context) {
          return CalcResultPanel(results: FoamFluidValue.getResult(ffv));
        });
  }

  void onReset() {
    formKey.currentState.reset();
  }
}

class FoamFluidValue {
  /// v1
  double strength;

  /// v2
  double mixRatio;

  /// v3
  double area;

  /// v4
  double time;

  /// v5
  int gunType;

  /// v6
  double liquidRate;

  /// v7
  double hookRate;

  FoamFluidValue(
      {this.strength,
      this.mixRatio,
      this.area,
      this.time,
      this.gunType,
      this.liquidRate,
      this.hookRate});

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

  static bool check(Map<String, dynamic> map) {
    String strength = map['strength'];
    double mixRatio = map['mixRatio'];
    String area = map['area'];
    String time = map['time'];
    int gunType = map['gunType'];
    String liquidRate = map['liquidRate'];
    String hookRate = map['hookRate'];

    if (strength == null ||
        strength.isEmpty ||
        mixRatio == null ||
        area == null ||
        area.isEmpty ||
        time == null ||
        time.isEmpty ||
        gunType == null ||
        liquidRate == null ||
        liquidRate.isEmpty ||
        hookRate == null ||
        hookRate.isEmpty) {
      return false;
    }
    return true;
  }

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

  /// 需泡沫原液量(L)
  static double calcLiquid(FoamFluidValue ffv) {
    double liquid = ffv.strength * ffv.mixRatio * ffv.area * ffv.time * 60;

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

  static String calcLiquidStr(FoamFluidValue ffv) {
    double liquid = calcLiquid(ffv);
    return '${liquid}L  或  ${(liquid / 1000).toStringAsFixed(4)}吨';
  }

  /// 需泡沫枪数量(支), 向上取整
  static int calcGun(FoamFluidValue ffv) {
    double gun = ffv.strength * ffv.area / ffv.gunType;

    /// 保留两位小数
    return gun.ceil();
  }

  /// 需泡沫炮数量(门), 向上取整
  static int calcCannon(FoamFluidValue ffv) {
    double gun = ffv.strength * ffv.area / ffv.liquidRate;

    /// 保留两位小数
    return gun.ceil();
  }

  /// 需泡沫枪数量(架), 向上取整
  static int calcGuns(FoamFluidValue ffv) {
    double gun = ffv.strength * ffv.area / ffv.hookRate;

    /// 保留两位小数
    return gun.ceil();
  }

  /// 计算结果
  static List<Map<String, dynamic>> getResult(FoamFluidValue ffv) {
    String liquid = calcLiquidStr(ffv);
    int gun = calcGun(ffv);
    int cann = calcCannon(ffv);
    int gun2 = calcGuns(ffv);
    
    List<Map<String, dynamic>> res = [];
    res.add({'title': '需泡沫原液量', 'value': '$liquid'});
    res.add({'title': '需泡沫枪数量', 'value': '$gun 支 或$gun2 架'});
    res.add({'title': '需泡沫炮数量', 'value': '$cann 门'});
    return res;
  }
}
