import 'package:fcs/domain/entities/fcs_shipment.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/localization/app_translations.dart';
import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
import 'package:fcs/pages/main/model/language_model.dart';
import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/widgets/display_text.dart';
import 'package:fcs/pages/widgets/input_date.dart';
import 'package:fcs/pages/widgets/input_text.dart';
import 'package:fcs/pages/widgets/local_button.dart';
import 'package:fcs/pages/widgets/local_text.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:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

import '../main/util.dart';

class FcsShipmentEditor extends StatefulWidget {
  final FcsShipment shipment;
  FcsShipmentEditor({this.shipment});

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

class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
  var dateFormatter = new DateFormat('dd MMM yyyy');
  TextEditingController _shipmentNumberController = new TextEditingController();
  TextEditingController _cutoffDateController = new TextEditingController();
  TextEditingController _arrivalDateController = new TextEditingController();
  TextEditingController _departureDateControler = new TextEditingController();
  TextEditingController _consigneeController = new TextEditingController();
  TextEditingController _portController = new TextEditingController();
  TextEditingController _destinationController = new TextEditingController();
  TextEditingController _statusController = new TextEditingController();

  FcsShipment _shipment = new FcsShipment();
  bool _isLoading = false;
  String _currentShipmentType;
  bool _isNew = false;

  @override
  void initState() {
    super.initState();
    _isNew = widget.shipment == null;
    if (widget.shipment != null) {
      _shipment = widget.shipment;
      _shipmentNumberController.text = _shipment.shipmentNumber;
      _cutoffDateController.text = dateFormatter.format(_shipment.cutoffDate);
      _arrivalDateController.text = dateFormatter.format(_shipment.arrivalDate);
      _departureDateControler.text =
          dateFormatter.format(_shipment.departureDate);
      _statusController.text = _shipment.status;
      _currentShipmentType = _shipment.shipType;
      _consigneeController.text = _shipment.consignee;
      _portController.text = _shipment.port;
      _destinationController.text = _shipment.destination;
    }
  }

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

  @override
  Widget build(BuildContext context) {
    var languageModel = Provider.of<LanguageModel>(context);
    var mainModel = Provider.of<MainModel>(context);

    final createBtn = LocalButton(
      textKey: "FCSshipment.create",
      callBack: _create,
    );

    final updateBtn = LocalButton(
      textKey: "FCSshipment.update",
      callBack: _update,
    );

    return LocalProgress(
      inAsyncCall: _isLoading,
      child: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          shadowColor: Colors.transparent,
          leading: new IconButton(
            icon: new Icon(CupertinoIcons.back, color: primaryColor),
            onPressed: () => Navigator.of(context).pop(),
          ),
          backgroundColor: Colors.white,
          title: LocalText(
            context,
            "FCSshipment.form.title",
            color: primaryColor,
            fontSize: 18,
          ),
        ),
        body: Padding(
          padding: const EdgeInsets.all(10.0),
          child: ListView(children: <Widget>[
            InputText(
              labelTextKey: "FCSshipment.number",
              iconData: Ionicons.ios_airplane,
              controller: _shipmentNumberController,
            ),
            InputDate(
              labelTextKey: "FCSshipment.cutoff_date",
              iconData: Icons.date_range,
              controller: _cutoffDateController,
            ),
            InputDate(
              labelTextKey: "FCSshipment.departure_date",
              iconData: Icons.date_range,
              controller: _departureDateControler,
            ),
            InputDate(
              labelTextKey: "FCSshipment.ETA",
              iconData: Icons.date_range,
              controller: _arrivalDateController,
            ),
            DropdownButtonFormField(
              value: _currentShipmentType == "" ? null : _currentShipmentType,
              decoration: InputDecoration(
                  enabledBorder: UnderlineInputBorder(
                      borderSide: BorderSide(color: primaryColor)),
                  fillColor: Colors.white,
                  labelStyle: languageModel.isEng
                      ? newLabelStyle(color: Colors.black54, fontSize: 20)
                      : newLabelStyleMM(color: Colors.black54, fontSize: 20),
                  labelText: AppTranslations.of(context)
                      .text('FCSshipment.shipment_type'),
                  icon: Icon(Ionicons.ios_airplane, color: primaryColor)),
              items: mainModel.setting.shipmentTypes
                  .map((e) => DropdownMenuItem(child: Text(e), value: e))
                  .toList(),
              onChanged: (selected) => {
                setState(() {
                  _currentShipmentType = selected;
                })
              },
            ),
            InputText(
                labelTextKey: 'FCSshipment.consignee',
                iconData: Icons.work,
                controller: _consigneeController),
            InputText(
                labelTextKey: 'FCSshipment.port_of_loading',
                iconData: FontAwesomeIcons.ship,
                controller: _portController),
            InputText(
                labelTextKey: 'FCSshipment.final_destination',
                iconData: MaterialCommunityIcons.location_enter,
                controller: _destinationController),
            _isNew
                ? Container()
                : Container(
                    padding: EdgeInsets.only(top: 5),
                    child: DisplayText(
                      text: _statusController.text,
                      iconData: Icons.av_timer,
                      labelTextKey: 'FCSshipment.status',
                    )),
            _isNew ? createBtn : updateBtn,
            SizedBox(height: 15)
          ]),
        ),
      ),
    );
  }

  FcsShipment _getPayload() {
    FcsShipment fcsShipment = FcsShipment();
    fcsShipment.id = _shipment.id;
    fcsShipment.shipmentNumber = _shipmentNumberController.text;
    fcsShipment.shipType = _currentShipmentType;
    fcsShipment.consignee = _consigneeController.text;
    fcsShipment.port = _portController.text;
    fcsShipment.destination = _destinationController.text;
    try {
      var cutoffDate = _cutoffDateController.text;
      var arrivalDate = _arrivalDateController.text;
      var depDate = _departureDateControler.text;
      fcsShipment.cutoffDate =
          cutoffDate == "" ? null : dateFormatter.parse(cutoffDate);
      fcsShipment.arrivalDate =
          arrivalDate == "" ? null : dateFormatter.parse(arrivalDate);
      fcsShipment.departureDate =
          depDate == "" ? null : dateFormatter.parse(depDate);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString()); // shold never happen
    }
    return fcsShipment;
  }

  Future<bool> _validate(FcsShipment fcsShipment) async {
    if (fcsShipment.shipmentNumber == "") {
      await showMsgDialog(context, "Error", "Invalid shipment number!");
      return false;
    }
    if (fcsShipment.shipType == null) {
      await showMsgDialog(context, "Error", "Invalid shipment type!");
      return false;
    }
    if (fcsShipment.cutoffDate == null) {
      await showMsgDialog(context, "Error", "Invalid cutoff date!");
      return false;
    }
    if (fcsShipment.arrivalDate == null) {
      await showMsgDialog(context, "Error", "Invalid ETA date!");
      return false;
    }
    if (fcsShipment.departureDate == null) {
      await showMsgDialog(context, "Error", "Invalid departure date!");
      return false;
    }
    return true;
  }

  Future<void> _create() async {
    FcsShipment fcsShipment = _getPayload();
    bool valid = await _validate(fcsShipment);
    if (!valid) {
      return;
    }
    setState(() {
      _isLoading = true;
    });
    var shipmentModel = Provider.of<FcsShipmentModel>(context, listen: false);
    try {
      await shipmentModel.create(fcsShipment);
      Navigator.pop(context);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  Future<void> _update() async {
    FcsShipment fcsShipment = _getPayload();
    bool valid = await _validate(fcsShipment);
    if (!valid) {
      return;
    }
    setState(() {
      _isLoading = true;
    });
    var shipmentModel = Provider.of<FcsShipmentModel>(context, listen: false);
    try {
      await shipmentModel.update(fcsShipment);
      Navigator.pop(context, true);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }
}
