import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/cargo_type.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/carton/carton_package_table.dart';
import 'package:fcs/pages/carton/model/carton_model.dart';
import 'package:fcs/pages/carton/widgets.dart';
import 'package:fcs/pages/delivery/model/delivery_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/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_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_vector_icons/flutter_vector_icons.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

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

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

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

class _DeliveryInfoState extends State<DeliveryInfo> {
  bool _isLoading = false;
  late Carton _box;
  late String _selectedCartonType;
  List<Package> _packages = [];
  List<Carton> _mixBoxes = [];
  Carton _selectedShipmentBox = new Carton();
  List<CargoType> _cargoTypes = [];
  DeliveryAddress _deliveryAddress = new DeliveryAddress();
  TextEditingController _widthController = new TextEditingController();
  TextEditingController _heightController = new TextEditingController();
  TextEditingController _lengthController = new TextEditingController();
  double volumetricRatio = 0;
  double shipmentWeight = 0;

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

  @override
  void initState() {
    super.initState();
    if (widget.box != null) _box = widget.box!;
    _selectedCartonType = _box.cartonType ?? '';

    //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();
    _cargoTypes = _box.cargoTypes;
    _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 ?? false)
            ? 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,
      labelTextKey: "box.fcs.id",
      icon: FcsIDIcon(),
    );

    final customerNameBox = DisplayText(
      text: _box.userName,
      labelTextKey: "box.name",
      iconData: Icons.person,
    );

    final shipmentBoxTitle = Container(
      padding: EdgeInsets.only(left: 15, right: 10.0, top: 20),
      child: Row(
        children: <Widget>[
          Expanded(
            child:
                LocalText(context, 'box.shipment_number', color: Colors.grey),
          ),
          LocalText(context, 'box.shipment.desc', color: Colors.grey),
        ],
      ),
    );

    final shipmentBoxRow = Container(
      padding: EdgeInsets.only(left: 15.0, right: 10.0, top: 5.0, bottom: 5.0),
      child: Row(
        children: <Widget>[
          Expanded(
              child: new Text(
            _selectedShipmentBox.shipmentNumber ?? "",
            style: textStyle,
          )),
          new Text(
            _selectedShipmentBox.desc ?? "",
            style: textStyle,
          ),
        ],
      ),
    );

    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.toStringAsFixed(0),
      labelTextKey: "box.shipment_weight",
      iconData: MaterialCommunityIcons.weight,
    );
    final mixCartonNumberBox = DisplayText(
      text: _box.mixCartonNumber,
      labelTextKey: "box.mix.carton",
      iconData: MaterialCommunityIcons.package,
    );
    final deliverBtn = LocalButton(
      textKey: "delivery.deliver.btn",
      callBack: _deliver,
    );

    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,
            "delivery.info.title",
            fontSize: 20,
            color: primaryColor,
          ),
        ),
        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.delivery_address"),
            isMixBox
                ? Container()
                : DefaultDeliveryAddress(
                    deliveryAddress: _deliveryAddress,
                    labelKey: "box.delivery_address",
                  ),
            SizedBox(
              height: 20,
            ),
            !isMixBox && _box.status == carton_shipped_status
                ? deliverBtn
                : Container(),
            SizedBox(
              height: 20,
            )
          ]),
        ),
      ),
    );
  }

  _deliver() {
    showConfirmDialog(context, "delivery.deliver.confirm", () {
      _deliverCarton();
    });
  }

  _deliverCarton() async {
    setState(() {
      _isLoading = true;
    });
    try {
      var deliveryModel = Provider.of<DeliveryModel>(context, listen: false);
      await deliveryModel.deliver(this._box);
      Navigator.pop(context, true);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }
}
