import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/domain/entities/cargo_type.dart';
import 'package:fcs/domain/entities/carton_size.dart';
import 'package:fcs/domain/entities/fcs_shipment.dart';
import 'package:fcs/domain/entities/package.dart';
import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/domain/vo/delivery_address.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/carton/carton_cargo_table.dart';
import 'package:fcs/pages/carton/carton_package_table.dart';
import 'package:fcs/pages/carton_size/carton_size_list.dart';
import 'package:fcs/pages/delivery_address/delivery_address_list.dart';
import 'package:fcs/pages/delivery_address/delivery_address_row.dart';
import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/package/model/package_model.dart';
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
import 'package:fcs/pages/user_search/user_serach.dart';
import 'package:fcs/pages/widgets/defalut_delivery_address.dart';
import 'package:fcs/pages/widgets/display_text.dart';
import 'package:fcs/pages/widgets/fcs_id_icon.dart';
import 'package:fcs/pages/widgets/length_picker.dart';
import 'package:fcs/pages/widgets/local_button.dart';
import 'package:fcs/pages/widgets/local_dropdown.dart';
import 'package:fcs/pages/widgets/local_radio_buttons.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/local_title.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:provider/provider.dart';
import 'cargo_type_addtion.dart';
import 'cargo_type_editor.dart';
import 'model/carton_model.dart';
import '../carton_size/model/carton_size_model.dart';
import 'package_carton_editor.dart';
import 'widgets.dart';

class CartonEditor extends StatefulWidget {
  final Carton box;
  CartonEditor({this.box});

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

class _CartonEditorState extends State<CartonEditor> {
  TextEditingController _widthController = new TextEditingController();
  TextEditingController _heightController = new TextEditingController();
  TextEditingController _lengthController = new TextEditingController();

  Carton _carton;
  bool _isLoading = false;
  bool _isNew;
  DeliveryAddress _deliveryAddress = new DeliveryAddress();
  User _user;
  String _selectedCartonType;
  double volumetricRatio = 0;
  double shipmentWeight = 0;
  FcsShipment _fcsShipment;
  List<FcsShipment> _fcsShipments;
  Carton _mixCarton;
  List<Carton> _mixCartons;

  List<Carton> _cartons = [];

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

    //for shipment weight
    volumetricRatio = Provider.of<ShipmentRateModel>(context, listen: false)
        .rate
        .volumetricRatio;
    _lengthController.addListener(_calShipmentWeight);
    _widthController.addListener(_calShipmentWeight);
    _heightController.addListener(_calShipmentWeight);

    if (widget.box != null) {
      _carton = widget.box;
      _deliveryAddress = _carton.deliveryAddress;
      _widthController.text = _carton.width.toString();
      _heightController.text = _carton.height.toString();
      _lengthController.text = _carton.length.toString();
      _selectedCartonType = _carton.cartonType;
      _isNew = false;
      _user = User(fcsID: _carton.fcsID, name: _carton.userName);
      _loadPackages();
    } else {
      _carton = Carton(
        cargoTypes: [],
        packages: [],
      );
      _lengthController.text = "";
      _widthController.text = "";
      _heightController.text = "";
      _isNew = true;
      _selectedCartonType = carton_from_packages;
      _loadFcsShipments();
      // _cartons = [
      //   Carton(cartonNumber: "A100B-1#1"),
      //   Carton(cartonNumber: "A100B-1#2"),
      //   Carton(cartonNumber: "A100B-1#3")
      // ];
    }
  }

  _loadFcsShipments() async {
    FcsShipmentModel fcsShipmentModel =
        Provider.of<FcsShipmentModel>(context, listen: false);
    var fcsShipments = await fcsShipmentModel.getActiveFcsShipments();
    var fcsShipment = fcsShipments
        .firstWhere((e) => e.id == _carton.fcsShipmentID, orElse: () => null);
    setState(() {
      _fcsShipments = fcsShipments;
      _fcsShipment = fcsShipment;
    });
  }

  _loadPackages() async {
    if (_user == null) return;
    PackageModel packageModel =
        Provider.of<PackageModel>(context, listen: false);
    List<Package> packages = await packageModel.getPackages(
        _user.id, [package_processed_status, package_packed_status]);
    if (_isNew) {
      String prevCompare;
      packages.forEach((p) {
        String compare = (p.deliveryAddress?.fullName ?? "") +
            (p.deliveryAddress?.phoneNumber ?? "");
        if (prevCompare != null && compare == prevCompare) {
          p.isChecked = true;
        } else {
          p.isChecked = false;
        }
        if (prevCompare == null) {
          p.isChecked = true;
          prevCompare = compare;
        }
      });
    } else {
      packages.forEach((p) {
        if (_carton.packages.contains(p)) {
          p.isChecked = _carton.packages.firstWhere((cp) => cp == p).isChecked;
        } else {
          p.isChecked = false;
        }
      });
    }

    setState(() {
      _carton.packages = packages;
    });
    _populateDeliveryAddress();
  }

  _populateDeliveryAddress() {
    if (_carton.packages == null) return;
    var d = _carton.packages
        .firstWhere((p) => p.isChecked && p.deliveryAddress != null,
            orElse: () => null)
        ?.deliveryAddress;
    setState(() {
      _deliveryAddress = d;
    });
  }

  _loadMixCartons() async {
    if (_fcsShipment == null || _fcsShipment.id == null) return;
    if (_selectedCartonType != carton_small_bag) return;

    CartonModel cartonModel = Provider.of<CartonModel>(context, listen: false);
    List<Carton> cartons =
        await cartonModel.getMixCartonsByFcsShipment(_fcsShipment.id);
    setState(() {
      _mixCartons = cartons;
    });
  }

  _calShipmentWeight() {
    double l = double.parse(_lengthController.text, (s) => 0);
    double w = double.parse(_widthController.text, (s) => 0);
    double h = double.parse(_heightController.text, (s) => 0);
    setState(() {
      shipmentWeight = l * w * h / volumetricRatio;
    });
  }

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

  @override
  Widget build(BuildContext context) {
    var boxModel = Provider.of<CartonModel>(context);
    bool isMixBox = _selectedCartonType == carton_mix_box;
    bool isSmallBag = _selectedCartonType == carton_small_bag;
    final shipmentBox = DisplayText(
      text: _carton.fcsShipmentNumber,
      labelTextKey: "box.fcs_shipment_num",
      iconData: Ionicons.ios_airplane,
    );
    final mixCartonNumberBox = DisplayText(
      text: _carton.mixCartonNumber,
      labelTextKey: "box.mix.carton",
      iconData: MaterialCommunityIcons.package,
    );
    var fcsShipmentsBox = Container(
        padding: EdgeInsets.only(top: 10),
        child: LocalDropdown<FcsShipment>(
          callback: (v) {
            setState(() {
              _fcsShipment = v;
            });
            _loadMixCartons();
          },
          labelKey: "shipment.pack.fcs.shipment",
          iconData: Ionicons.ios_airplane,
          display: (u) => u.shipmentNumber,
          selectedValue: _fcsShipment,
          values: _fcsShipments,
        ));

    var mixCartonsBox = Container(
        padding: EdgeInsets.only(top: 10),
        child: LocalDropdown<Carton>(
          callback: (v) {
            setState(() {
              _mixCarton = v;
            });
          },
          labelKey: "box.mix.carton",
          iconData: MaterialCommunityIcons.package,
          display: (u) => u.cartonNumber,
          selectedValue: _mixCarton,
          values: _mixCartons,
        ));

    final fcsIDBox = Container(
        padding: EdgeInsets.only(top: 10),
        child: Row(
          children: <Widget>[
            Expanded(
                child: DisplayText(
              text: _user?.fcsID ?? "",
              labelTextKey: "box.fcs.id",
              icon: FcsIDIcon(),
            )),
            _isNew
                ? IconButton(
                    icon: Icon(Icons.search, color: primaryColor),
                    onPressed: () =>
                        searchUser(context, callbackUserSelect: (u) {
                          setState(() {
                            this._user = u;
                            _loadPackages();
                          });
                        }))
                : Container(),
          ],
        ));

    final namebox = DisplayText(
      text: _user?.name ?? "",
      labelTextKey: "box.name",
      iconData: Icons.person,
    );

    final lengthBox = LengthPicker(
      controller: _lengthController,
      lableKey: "box.length",
      isReadOnly: true,
    );
    final widthBox = LengthPicker(
      controller: _widthController,
      lableKey: "box.width",
      isReadOnly: true,
    );
    final heightBox = LengthPicker(
      controller: _heightController,
      lableKey: "box.height",
      isReadOnly: true,
    );

    final dimBox = Row(
      mainAxisAlignment: MainAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(right: 8.0),
          child: Icon(FontAwesome.arrow_circle_right, color: primaryColor),
        ),
        SizedBox(child: lengthBox, width: 80),
        SizedBox(child: widthBox, width: 80),
        SizedBox(child: heightBox, width: 80),
      ],
    );

    final shipmentWeightBox = DisplayText(
      text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(2) : "",
      labelTextKey: "box.shipment_weight",
      iconData: MaterialCommunityIcons.weight,
    );

    final createBtn = LocalButton(
      textKey: "box.complete.packaging",
      callBack: _save,
    );

    final saveBtn = LocalButton(
      textKey: "box.cargo.save.btn",
      callBack: _save,
    );

    final cartonTypeBox = LocalRadioButtons(
        readOnly: !_isNew,
        values: boxModel.cartonTypes,
        selectedValue: _selectedCartonType,
        callback: (v) {
          setState(() {
            _selectedCartonType = v;
          });
        });

    final cargoTableTitleBox = LocalTitle(
      textKey: "box.cargo.type",
      trailing: IconButton(
          icon: Icon(
            Icons.add_circle,
            color: primaryColor,
          ),
          onPressed: () async {
            // CargoType cargo = await Navigator.push<CargoType>(context,
            //     CupertinoPageRoute(builder: (context) => CargoTypeEditor()));
            // _addCargo(cargo);
            List<CargoType> cargos = await Navigator.push<List<CargoType>>(
                context,
                CupertinoPageRoute(builder: (context) => CargoTypeAddition()));
            if (cargos == null) return;
            setState(() {
              _carton.cargoTypes.clear();
              _carton.cargoTypes.addAll(cargos);
            });
          }),
    );

    final cargoTableBox = CargoTable(
      cargoTypes: _carton.cargoTypes,
      onAdd: (c) => _addCargo(c),
      onRemove: (c) => _removeCargo(c),
    );

    final cartonTitleBox = Container(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          Text("Cartons (${_cartons.length})"),
          IconButton(
              icon: Icon(
                Icons.add_circle,
                color: primaryColor,
              ),
              onPressed: () async {
                Carton _carton = await Navigator.push(
                  context,
                  CupertinoPageRoute(
                      builder: (context) => PackageCartonEditor()),
                );
                _addCarton(_carton);
              }),
        ],
      ),
    );

    return LocalProgress(
      inAsyncCall: _isLoading,
      child: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          leading: new IconButton(
            icon: new Icon(CupertinoIcons.back, color: primaryColor, size: 30),
            onPressed: () {
              if (isDataChanged()) {
                showConfirmDialog(context, "back.button_confirm", () {
                  Navigator.of(context).pop();
                });
              } else {
                Navigator.of(context).pop();
              }
            },
          ),
          shadowColor: Colors.transparent,
          backgroundColor: Colors.white,
          title: LocalText(
            context,
            "box.info.title",
            fontSize: 20,
            color: primaryColor,
          ),
          // title: _isNew
          //     ? LocalText(
          //         context,
          //         "boxes.create.title",
          //         fontSize: 20,
          //         color: primaryColor,
          //       )
          //     : LocalText(
          //         context,
          //         "box.edit.title",
          //         fontSize: 20,
          //         color: primaryColor,
          //       ),
        ),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: ListView(
            shrinkWrap: true,
            children: [
              _isNew
                  ? Container()
                  : Center(child: getCartonNumberStatus(context, _carton)),
              LocalTitle(textKey: "box.type.title"),
              cartonTypeBox,
              LocalTitle(textKey: "box.shipment_info"),
              _isNew ? fcsShipmentsBox : shipmentBox,
              isSmallBag
                  ? _isNew
                      ? mixCartonsBox
                      : mixCartonNumberBox
                  : Container(),
              ...(isMixBox
                  ? [
                      // CartonMixTable(
                      //   cartons: _carton.cartons,
                      //   onSelect: (c, check) {
                      //     setState(() {
                      //       c.isChecked = check;
                      //     });
                      //   },
                      // )
                    ]
                  : [
                      fcsIDBox,
                      namebox,
                      CartonPackageTable(
                        packages: _carton.packages,
                        onSelect: (p, checked) {
                          if (checked &&
                              _deliveryAddress != null &&
                              p.deliveryAddress?.id != _deliveryAddress.id) {
                            return;
                          }
                          setState(() {
                            p.isChecked = checked;
                          });
                          _populateDeliveryAddress();
                        },
                      ),
                      cartonTitleBox,
                      Column(
                          children: _getCartons(
                        context,
                        this._cartons,
                      )),
                      // cargoTableTitleBox,
                      // cargoTableBox,
                      // isSmallBag
                      //     ? Container()
                      //     : LocalTitle(textKey: "box.dimension"),
                      // isSmallBag ? Container() : cartonSizeDropdown(),
                      // isSmallBag ? Container() : dimBox,
                      // isSmallBag ? Container() : shipmentWeightBox,
                      // LocalTitle(textKey: "box.delivery_address"),
                      // DefaultDeliveryAddress(
                      //   deliveryAddress: _deliveryAddress,
                      //   labelKey: "box.delivery_address",
                      //   onTap: () async {
                      //     DeliveryAddress _address = await Navigator.push(
                      //         context,
                      //         CupertinoPageRoute(
                      //             builder: (context) => DeliveryAddressList(
                      //                 isAdminCreation: true,
                      //                 deliveryAddress: _deliveryAddress)));
                      //     if (_address == null) return;
                      //     setState(() {
                      //       _deliveryAddress = _address;
                      //     });
                      //   },
                      // ),
                    ]),
              SizedBox(
                height: 20,
              ),
              _isNew ? createBtn : saveBtn,
              SizedBox(
                height: 20,
              ),
            ],
          ),
        ),
      ),
    );
  }

  _addCarton(Carton carton) {
    if (carton == null) return;
    this._cartons.add(carton);
    setState(() {});
  }

  List<Widget> _getCartons(BuildContext context, List<Carton> cartons) {
    return cartons.map((c) {
      return Container(
        decoration: BoxDecoration(
          border: Border(
            bottom: BorderSide(color: Colors.grey[300]),
          ),
        ),
        child: InkWell(
          onTap: () {},
          child: Row(
            children: <Widget>[
              Expanded(
                child: new Padding(
                  padding: const EdgeInsets.symmetric(vertical: 10.0),
                  child: new Row(
                    children: <Widget>[
                      new Padding(
                        padding:
                            new EdgeInsets.symmetric(horizontal: 15.0 - 5 / 2),
                        child: Stack(
                          alignment: AlignmentDirectional.bottomEnd,
                          children: [
                            Icon(
                              MaterialCommunityIcons.package,
                              color: primaryColor,
                              size: 30,
                            ),
                          ],
                        ),
                      ),
                      new Expanded(
                        child: new Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            new Text(
                              c.cartonNumber == null ? "" : c.cartonNumber,
                              style: new TextStyle(fontSize: 15.0),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    }).toList();
  }

  CartonSize selectedCatonSize;
  Widget cartonSizeDropdown() {
    List<CartonSize> _cartonSizes =
        Provider.of<CartonSizeModel>(context).getCartonSizes;

    return Padding(
      padding: const EdgeInsets.only(top: 10),
      child: Row(
        children: [
          Padding(
            padding: const EdgeInsets.only(left: 0, right: 10),
            child: Icon(AntDesign.CodeSandbox, color: primaryColor),
          ),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Padding(
                  padding: const EdgeInsets.only(right: 18.0),
                  child: LocalText(
                    context,
                    "box.carton_size",
                    color: Colors.black54,
                    fontSize: 16,
                  ),
                ),
                DropdownButton<CartonSize>(
                  isDense: true,
                  value: selectedCatonSize,
                  style: TextStyle(color: Colors.black, fontSize: 14),
                  underline: Container(
                    height: 1,
                    color: Colors.grey,
                  ),
                  onChanged: (CartonSize newValue) {
                    setState(() {
                      if (newValue.name == MANAGE_CARTONSIZE) {
                        selectedCatonSize = null;
                        _manageCartonSize();
                        return;
                      }
                      selectedCatonSize = newValue;
                      _widthController.text =
                          selectedCatonSize.width.toString();
                      _heightController.text =
                          selectedCatonSize.height.toString();
                      _lengthController.text =
                          selectedCatonSize.length.toString();
                    });
                  },
                  isExpanded: true,
                  items: _cartonSizes
                      .map<DropdownMenuItem<CartonSize>>((CartonSize value) {
                    return DropdownMenuItem<CartonSize>(
                      value: value,
                      child: Text(value.name ?? "",
                          overflow: TextOverflow.ellipsis,
                          style: TextStyle(
                              color: value.name == MANAGE_CARTONSIZE
                                  ? secondaryColor
                                  : primaryColor)),
                    );
                  }).toList(),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  _manageCartonSize() {
    Navigator.push<Package>(
      context,
      CupertinoPageRoute(builder: (context) => CartonSizeList()),
    );
  }

  List<Widget> getAddressList(
      BuildContext context, List<DeliveryAddress> addresses) {
    return addresses.asMap().entries.map((s) {
      return InkWell(
        onTap: () {},
        child: DeliveryAddressRow(deliveryAddress: s.value),
      );
    }).toList();
  }

  _addCargo(CargoType cargo) {
    if (cargo == null) return;
    setState(() {
      _carton.cargoTypes.remove(cargo);
      _carton.cargoTypes.add(cargo);
    });
  }

  _removeCargo(CargoType cargo) {
    setState(() {
      _carton.cargoTypes.remove(cargo);
    });
  }

  _save() async {
    bool isFromShipment = _selectedCartonType == carton_from_shipments;
    bool isSmallBag = _selectedCartonType == carton_small_bag;
    if (_user == null && (isFromShipment || isSmallBag)) {
      showMsgDialog(context, "Error", "Please select customer");
      return;
    }
    if (_fcsShipment == null && _isNew) {
      showMsgDialog(context, "Error", "Please select FCS shipment");
      return;
    }
    if ((_carton.cargoTypes?.length ?? 0) == 0 &&
        (isFromShipment || isSmallBag)) {
      showMsgDialog(context, "Error", "Expect at least one cargo type");
      return;
    }
    double l = double.parse(_lengthController.text, (s) => 0);
    double w = double.parse(_widthController.text, (s) => 0);
    double h = double.parse(_heightController.text, (s) => 0);
    if ((l <= 0 || w <= 0 || h <= 0) && isFromShipment) {
      showMsgDialog(context, "Error", "Invalid dimension");
      return;
    }
    if (_deliveryAddress == null && (isFromShipment || isSmallBag)) {
      showMsgDialog(context, "Error", "Invalid delivery address");
      return;
    }
    if (isSmallBag && _mixCarton == null && _isNew) {
      showMsgDialog(context, "Error", "Invalid mix carton");
      return;
    }

    Carton carton = Carton();
    carton.id = _carton.id;
    carton.cartonType = _selectedCartonType;
    carton.fcsShipmentID = _isNew ? _fcsShipment.id : _carton.fcsShipmentID;
    carton.userID = _user?.id;
    carton.cargoTypes = _carton.cargoTypes;
    carton.packages = _carton.packages.where((e) => e.isChecked).toList();
    carton.mixCartonID = _mixCarton?.id;
    carton.length = l;
    carton.width = w;
    carton.height = h;
    carton.deliveryAddress = _deliveryAddress;
    setState(() {
      _isLoading = true;
    });
    try {
      CartonModel cartonModel =
          Provider.of<CartonModel>(context, listen: false);
      if (_isNew) {
        await cartonModel.createCarton(carton);
      } else {
        await cartonModel.updateCarton(carton);
      }
      Navigator.pop(context, true);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  isDataChanged() {
    if (_isNew) {
      return _fcsShipment != null || _user != null || _cartons.isNotEmpty;
    } else {
      return true;
    }
  }
}
