import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/domain/entities/package.dart';
import 'package:fcs/domain/vo/delivery_address.dart';
import 'package:fcs/helpers/theme.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/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_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:intl/intl.dart';
import 'package:provider/provider.dart';

import 'carton_cargo_table.dart';
import 'carton_editor.dart';
import 'carton_package_table.dart';
import 'model/carton_model.dart';
import 'widgets.dart';

final DateFormat dateFormat = DateFormat("d MMM yyyy");

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

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

class _CartonInfoState extends State<CartonInfo> {
  bool _isLoading = false;
  Carton _box;
  DeliveryAddress _deliveryAddress = new DeliveryAddress();
  TextEditingController _widthController = new TextEditingController();
  TextEditingController _heightController = new TextEditingController();
  TextEditingController _lengthController = new TextEditingController();
  double volumetricRatio = 0;
  double shipmentWeight = 0;

  bool isMixBox;
  bool isFromShipments;
  bool isFromPackages;
  bool isSmallBag;
  bool isEdiable;

  @override
  void initState() {
    super.initState();
    _box = widget.box;

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

    _updateBoxData();
    _loadPackages();
  }

  _updateBoxData() {
    _widthController.text = _box.width.toString();
    _heightController.text = _box.height.toString();
    _lengthController.text = _box.length.toString();
    _deliveryAddress = _box.deliveryAddress;
    isMixBox = _box.cartonType == carton_mix_box;
    isFromShipments = _box.cartonType == carton_from_shipments;
    isFromPackages = _box.cartonType == carton_from_packages;
    isSmallBag = _box.cartonType == carton_small_bag;
    isEdiable = !isMixBox &&
        (isFromPackages || isSmallBag) &&
        _box.status == carton_packed_status;
  }

  _loadPackages() async {
    if (!isFromPackages && !isSmallBag) return;

    if (_box.cartonType == carton_from_packages && _box.userID == null) return;
    PackageModel packageModel =
        Provider.of<PackageModel>(context, listen: false);
    List<Package> packages = await packageModel.getPackages(_box.userID, [
      package_processed_status,
      package_packed_status,
      package_shipped_status,
      package_delivered_status
    ]);
    packages = packages.where((p) => _box.packageIDs.contains(p.id)).toList();
    packages.forEach((p) {
      p.isChecked = true;
    });

    setState(() {
      _box.packages = packages;
    });
  }

  _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();
  }

  final DateFormat dateFormat = DateFormat("d MMM yyyy");

  @override
  Widget build(BuildContext context) {
    var cartonModel = Provider.of<CartonModel>(context);

    final cartonTypeBox = LocalRadioButtons(
        readOnly: true,
        values: cartonModel.cartonTypesInfo,
        selectedValue:
            _box.isShipmentCarton ? carton_from_shipments : _box.cartonType);
    final shipmentBox = DisplayText(
      text: _box.fcsShipmentNumber,
      labelTextKey: "box.fcs_shipment_num",
      iconData: Ionicons.ios_airplane,
    );
    final fcsIDBox = DisplayText(
      text: _box.fcsID == null ? "" : _box.fcsID,
      labelTextKey: "box.fcs.id",
      icon: FcsIDIcon(),
    );

    final customerNameBox = DisplayText(
      text: _box.userName == null ? "" : _box.userName,
      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(0) : "",
      labelTextKey: "box.shipment_weight",
      iconData: MaterialCommunityIcons.weight,
    );
    final cargoTableBox = CargoTable(
      cargoTypes: _box.cargoTypes,
    );
    final mixCartonNumberBox = DisplayText(
      text: _box.mixCartonNumber,
      labelTextKey: "box.mix.carton",
      iconData: MaterialCommunityIcons.package,
    );

    return LocalProgress(
      inAsyncCall: _isLoading,
      child: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          leading: new IconButton(
            icon: new Icon(CupertinoIcons.back, color: primaryColor, size: 30),
            onPressed: () => Navigator.of(context).pop(),
          ),
          shadowColor: Colors.transparent,
          backgroundColor: Colors.white,
          title: LocalText(
            context,
            "box.info.title",
            fontSize: 20,
            color: primaryColor,
          ),
          actions: isEdiable
              ? <Widget>[
                  IconButton(
                    icon: Icon(Icons.edit, color: primaryColor),
                    onPressed: _gotoEditor,
                  ),
                  IconButton(
                    icon: Icon(Icons.delete, color: primaryColor),
                    onPressed: _delete,
                  ),
                ]
              : [],
        ),
        body: Padding(
          padding: const EdgeInsets.all(10.0),
          child: ListView(children: <Widget>[
            Center(child: getCartonNumberStatus(context, _box)),
            LocalTitle(textKey: "box.type.title"),
            cartonTypeBox,
            LocalTitle(textKey: "box.shipment_info"),
            shipmentBox,
            isSmallBag ? mixCartonNumberBox : Container(),
            isMixBox ? Container() : fcsIDBox,
            isMixBox ? Container() : customerNameBox,
            isFromPackages || isSmallBag
                ? CartonPackageTable(
                    packages: _box.packages,
                  )
                : Container(),
            isMixBox ? Container() : LocalTitle(textKey: "box.cargo.type"),
            isMixBox ? Container() : cargoTableBox,
            ...(isFromPackages
                ? [
                    LocalTitle(textKey: "box.dimension"),
                    dimBox,
                    shipmentWeightBox,
                  ]
                : []),
            isMixBox
                ? Container()
                : LocalTitle(textKey: "box.delivery_address"),
            isMixBox
                ? Container()
                : DefaultDeliveryAddress(
                    deliveryAddress: _deliveryAddress,
                    labelKey: "box.delivery_address",
                  ),
            SizedBox(
              height: 20,
            )
          ]),
        ),
      ),
    );
  }

  _gotoEditor() async {
    bool updated = await Navigator.push<bool>(
      context,
      CupertinoPageRoute(builder: (context) => CartonEditor(box: widget.box)),
    );
    if (updated ?? false) {
      var cartonModel = Provider.of<CartonModel>(context, listen: false);
      var c = await cartonModel.getCarton(widget.box.id);
      setState(() {
        _box = c;
        _updateBoxData();
      });
      _loadPackages();
    }
  }

  _delete() {
    showConfirmDialog(context, "box.delete.confirm", () {
      _deleteCarton();
    });
  }

  _deleteCarton() async {
    setState(() {
      _isLoading = true;
    });
    try {
      var cartonModel = Provider.of<CartonModel>(context, listen: false);
      await cartonModel.deleteCarton(widget.box);
      Navigator.pop(context, true);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }
}
