import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/domain/entities/shipment.dart';
import 'package:fcs/domain/vo/delivery_address.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart';
import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/shipment/model/shipment_model.dart';
import 'package:fcs/pages/widgets/defalut_delivery_address.dart';
import 'package:fcs/pages/widgets/delivery_address_selection.dart';
import 'package:fcs/pages/widgets/display_text.dart';
import 'package:fcs/pages/widgets/fcs_id_icon.dart';
import 'package:fcs/pages/widgets/input_date.dart';
import 'package:fcs/pages/widgets/input_time.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:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';

import 'box_row.dart';
import 'shipment_box_editor.dart';
import 'widgets.dart';

class ShipmentEditor extends StatefulWidget {
  final Shipment shipment;
  ShipmentEditor({this.shipment});

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

class _ShipmentEditorState extends State<ShipmentEditor> {
  var dateFormatter = new DateFormat('dd MMM yyyy');
  var timeFormatter = new DateFormat('jm');

  TextEditingController _fromTimeEditingController =
      new TextEditingController();
  TextEditingController _toTimeEditingController = new TextEditingController();
  TextEditingController _pickupDate = new TextEditingController();

  Shipment _shipment;
  bool _isLoading = false;
  var now = new DateTime.now();
  bool _isNew;

  String _selectedShipmentType;

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

    if (widget.shipment != null) {
      _isNew = false;
      _shipment = widget.shipment;
      _selectedShipmentType = _shipment.shipmentType;
      _fromTimeEditingController.text = _shipment.pickupTimeStart;
      _toTimeEditingController.text = _shipment.pickupTimeEnd;
      _pickupDate.text = dateFormatter.format(_shipment.pickupDate ?? now);
    } else {
      _isNew = true;
      _selectedShipmentType = shipment_local_pickup;
      _pickupDate.text = dateFormatter.format(now);
      _fromTimeEditingController.text = "${timeFormatter.format(now)}";
      _toTimeEditingController.text = "${timeFormatter.format(now)}";
      _shipment = Shipment(boxes: []);
      var shipmentModel =
          Provider.of<DeliveryAddressModel>(context, listen: false);
      _shipment.pickupAddress = shipmentModel.defalutAddress;
      _pickupDate.text = dateFormatter.format(now);
    }
  }

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

  @override
  Widget build(BuildContext context) {
    MainModel mainModel = Provider.of<MainModel>(context);
    ShipmentModel pickupModel = Provider.of<ShipmentModel>(context);
    final shipmentNumberBox = getShipmentNumberStatus(context, _shipment);
    bool isLocalPickup = _selectedShipmentType == shipment_local_pickup;
    bool isCourierPickup = _selectedShipmentType == shipment_courier_pickup;
    bool isLocalDropoff = _selectedShipmentType == shipment_local_dropoff;
    bool isCourierDropoff = _selectedShipmentType == shipment_courier_dropoff;
    final fromTimeBox = InputTime(
        labelTextKey: 'shipment.from',
        iconData: Icons.timer,
        controller: _fromTimeEditingController);

    final toTimeBox = Container(
        width: 150,
        child: InputTime(
            iconData: Icons.timer_off,
            labelTextKey: 'shipment.to',
            controller: _toTimeEditingController));

    final pickupDateBox = InputDate(
      labelTextKey: "shipment.date",
      iconData: Icons.date_range,
      controller: _pickupDate,
    );
    final curierDropoffAddress = Padding(
        padding: EdgeInsets.all(8),
        child: FloatingActionButton.extended(
          onPressed: _openCourierWebsite,
          icon: Icon(Icons.open_in_new, color: primaryColor),
          label: Text(
            'Visit courier websie \nfor nearest drop-off',
            style: TextStyle(fontSize: 16, color: primaryColor),
          ),
          backgroundColor: Colors.white,
        ));
    final pickupAddressBox = DefaultDeliveryAddress(
      deliveryAddress: _shipment.pickupAddress,
      iconData: Icons.location_on,
      labelKey: "shipment.location",
      onTap: () async {
        DeliveryAddress address = await Navigator.push<DeliveryAddress>(
          context,
          CupertinoPageRoute(
              builder: (context) => DeliveryAddressSelection(
                    deliveryAddress: _shipment.pickupAddress,
                  )),
        );
        if (address == null) return;
        setState(() {
          _shipment.pickupAddress = address;
        });
      },
    );
    var localDropoffAddressBox = Row(children: [
      FcsIDIcon(),
      Expanded(
        child: DisplayText(
          text: mainModel.setting.usaAddress,
        ),
      )
    ]);
    final createBtn = LocalButton(
      textKey: "shipment.create",
      callBack: _save,
    );

    final updateBtn = LocalButton(
      textKey: "shipment.update",
      callBack: _save,
    );

    return LocalProgress(
      inAsyncCall: _isLoading,
      child: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          leading: new IconButton(
            icon: new Icon(
              CupertinoIcons.back,
              color: primaryColor,
            ),
            onPressed: () => Navigator.of(context).pop(),
          ),
          shadowColor: Colors.transparent,
          backgroundColor: Colors.white,
          title: LocalText(
            context,
            _isNew ? "shipment.new.title" : "shipment.edit.title",
            fontSize: 20,
            color: primaryColor,
          ),
        ),
        body: Padding(
          padding: const EdgeInsets.all(10.0),
          child: ListView(
            children: <Widget>[
              _isNew ? Container() : Center(child: shipmentNumberBox),
              LocalTitle(textKey: "shipment.type"),
              LocalRadioButtons(
                  values: pickupModel.shipmentTypes,
                  selectedValue: _selectedShipmentType,
                  callback: (v) {
                    setState(() {
                      _selectedShipmentType = v;
                    });
                  }),
              ...(isLocalDropoff
                  ? [
                      LocalTitle(textKey: "shipment.location.dropoff"),
                      localDropoffAddressBox
                    ]
                  : []),
              ...(isCourierDropoff
                  ? [
                      LocalTitle(textKey: "shipment.courier.dropoff"),
                      curierDropoffAddress
                    ]
                  : []),
              ...(isCourierPickup || isLocalPickup
                  ? [
                      LocalTitle(textKey: "shipment.location"),
                      pickupAddressBox,
                      LocalTitle(textKey: "shipment.date.time"),
                      pickupDateBox,
                      fromTimeBox,
                      toTimeBox,
                    ]
                  : []),
              LocalTitle(
                textKey: "boxes.name",
                trailing: IconButton(
                  icon: Icon(
                    Icons.add_circle,
                    color: primaryColor,
                  ),
                  onPressed: () async {
                    Carton box = await Navigator.push(
                      context,
                      CupertinoPageRoute(
                          builder: (context) => ShipmentBoxEditor()),
                    );
                    _addBox(box);
                  },
                ),
              ),
              Column(
                children: getBoxList(context, _shipment.boxes),
              ),
              _isNew ? createBtn : updateBtn,
            ],
          ),
        ),
      ),
    );
  }

  List<Widget> getBoxList(BuildContext context, List<Carton> boxes) {
    return boxes.asMap().entries.map((_box) {
      return InkWell(
        onTap: () async {
          Carton box = await Navigator.of(context).push(CupertinoPageRoute(
              builder: (context) => ShipmentBoxEditor(box: _box.value)));
          _saveBox(box);
        },
        child: Row(
          children: [
            Expanded(child: BoxRow(box: _box.value)),
            InkWell(
              onTap: () => _removeBox(_box.value),
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Icon(Icons.remove_circle, color: primaryColor),
              ),
            ),
          ],
        ),
      );
    }).toList();
  }

  _addBox(Carton box) {
    if (box == null) return;
    box.cartonType = carton_from_shipments;
    _shipment.boxes.add(box);
    setState(() {});
  }

  _saveBox(Carton box) {
    if (box == null) return;
    setState(() {});
  }

  _removeBox(Carton box) {
    if (box == null) return;
    _shipment.boxes.remove(box);
    setState(() {});
  }

  _save() async {
    _shipment.shipmentType = this._selectedShipmentType;
    _shipment.pickupDate = dateFormatter.parse(_pickupDate.text);
    _shipment.pickupTimeStart = _fromTimeEditingController.text;
    _shipment.pickupTimeEnd = _toTimeEditingController.text;
    setState(() {
      _isLoading = true;
    });
    try {
      ShipmentModel shipmentModel =
          Provider.of<ShipmentModel>(context, listen: false);
      if (_isNew) {
        await shipmentModel.createShipment(_shipment);
      } else {
        await shipmentModel.updateShipment(_shipment);
      }
      Navigator.pop(context, true);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  _openCourierWebsite() {
    MainModel mainModel = Provider.of<MainModel>(context, listen: false);
    launch("${mainModel.setting.courierWebsite}");
  }
}
