import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/domain/vo/privilege.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/localization/app_translations.dart';
import 'package:fcs/pages/main/model/language_model.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/staff/model/staff_model.dart';
import 'package:fcs/pages/widgets/display_text.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:provider/provider.dart';

typedef void FindCallBack();

class StaffEditor extends StatefulWidget {
  final User staff;
  const StaffEditor({this.staff});
  @override
  _StaffEditorState createState() => _StaffEditorState();
}

class _StaffEditorState extends State<StaffEditor> {
  TextEditingController _phoneInput = new TextEditingController();

  bool _isLoading = false;
  User user;
  User selectedUser;
  List<Privilege> privileges = [];
  bool isNew = true;

  @override
  void initState() {
    super.initState();
    privileges = Provider.of<StaffModel>(context, listen: false).privileges;
    isNew = widget.staff == null;
    user = User();
    if (!isNew) {
      user =
          User(name: widget.staff.name, phoneNumber: widget.staff.phoneNumber);
      user.privileges = widget.staff.privileges;
      privileges.forEach((p) => user.privileges.contains(p.id)
          ? p.isChecked = true
          : p.isChecked = false);
    } else {
      user.name = "";
      user.phoneNumber = "";
      privileges.forEach((p) => p.isChecked = false);
    }
  }

  List<Widget> showprivilegeList(BuildContext context) {
    return privileges.map((p) {
      return new ListTile(
          title: InkWell(
        onTap: () {
          setState(() {
            p.isChecked = p.isChecked == null ? true : !p.isChecked;
          });
        },
        child: new Row(
          children: <Widget>[
            new Checkbox(
                value: p.isChecked == null ? false : p.isChecked,
                activeColor: primaryColor,
                onChanged: (bool value) {
                  setState(() {
                    p.isChecked = value;
                  });
                }),
            Padding(
              padding: const EdgeInsets.only(right: 8.0),
              child: Icon(p.iconData, size: 50, color: Colors.black38),
            ),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  new Text(
                    p.name,
                    style: TextStyle(fontSize: 15.0, color: primaryColor),
                  ),
                  Text(p.desc,
                      style: TextStyle(fontSize: 13, color: Colors.grey[600]))
                ],
              ),
            ),
          ],
        ),
      ));
    }).toList();
  }

  Widget phoneSearchbox(BuildContext context, FindCallBack findCallBack) {
    var languageModel = Provider.of<LanguageModel>(context);
    return Container(
        padding: EdgeInsets.only(
          bottom: 25,
          left: 8,
        ),
        child: Stack(
          alignment: const Alignment(1, 1.0),
          children: <Widget>[
            TextFormField(
              controller: _phoneInput,
              autofocus: false,
              cursorColor: primaryColor,
              keyboardType: TextInputType.phone,
              style: textStyle,
              decoration: new InputDecoration(
                labelText:
                    AppTranslations.of(context).text('staff.phone.search'),
                labelStyle: languageModel.isEng ? labelStyle : labelStyleMM,
                // icon: Icon(
                //   Icons.search,
                //   color: primaryColor,
                // ),
                enabledBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: primaryColor, width: 1.0)),
                focusedBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: primaryColor, width: 1.0)),
              ),
            ),
            new IconButton(
                onPressed: () {
                  findCallBack();
                },
                icon: new Icon(Icons.search, size: 25, color: primaryColor))
          ],
        ));
  }

  @override
  Widget build(BuildContext context) {
    final namebox = DisplayText(
      text: user.name,
      labelTextKey: "customer.name",
      iconData: Icons.person,
    );
    var phoneNumberBox = Row(
      children: <Widget>[
        Expanded(
            child: DisplayText(
          text: user.phoneNumber,
          labelTextKey: "customer.phone",
          iconData: Icons.phone,
        )),
        isNew
            ? Container()
            : IconButton(
                icon: Icon(Icons.open_in_new, color: primaryColor),
                onPressed: () => call(context, user.phoneNumber)),
      ],
    );

    final updateButton = fcsButton(
      context,
      getLocalString(context, 'staff.update'),
      callack: _save,
    );
    final addButton = fcsButton(
      context,
      getLocalString(context, 'staff.add'),
      callack: _add,
    );

    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,
              "staff.form.title",
              fontSize: 20,
              color: primaryColor,
            ),
          ),
          body: Padding(
            padding: const EdgeInsets.only(left: 12.0, right: 12),
            child: ListView(
              children: <Widget>[
                isNew
                    ? phoneSearchbox(context, () => _findUser(context))
                    : Container(),
                phoneNumberBox,
                namebox,
                Padding(
                  padding: const EdgeInsets.only(top: 18.0),
                  child: Text("Privileges"),
                ),
                Column(
                  children: showprivilegeList(context),
                ),
                SizedBox(
                  height: 10,
                ),
                Container(
                  child: isNew ? addButton : updateButton,
                ),
                SizedBox(
                  height: 10,
                )
              ],
            ),
          ),
        ));
  }

  _add() async {
    if (isNew && selectedUser == null) {
      showMsgDialog(context, "Error", "Invalid user!");
      return;
    }
    setState(() {
      _isLoading = true;
    });
    StaffModel staffModel = Provider.of<StaffModel>(context, listen: false);
    try {
      await staffModel.updatePrivileges(this.selectedUser.id, privilegesIDs());
      Navigator.pop(context);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  List<String> privilegesIDs() {
    return this.privileges.where((p) => p.isChecked).map((p) => p.id).toList();
  }

  _save() async {
    setState(() {
      _isLoading = true;
    });
    if (widget.staff == null) return;
    StaffModel staffModel = Provider.of<StaffModel>(context, listen: false);
    try {
      await staffModel.updatePrivileges(widget.staff.id, privilegesIDs());
      Navigator.pop(context);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  _findUser(BuildContext context) async {
    StaffModel staffModel = Provider.of<StaffModel>(context, listen: false);
    if (_phoneInput.text == "") return;

    setState(() {
      _isLoading = true;
    });
    try {
      User _user = await staffModel.findUser(_phoneInput.text);
      if (_user == null) {
        showMsgDialog(context, "Error", _phoneInput.text + " not found!");
        return;
      }
      this.selectedUser = _user;
      this.user = _user;
      setState(() {
        if (user.privileges != null) {
          privileges.forEach((p) => user.privileges.contains(p.id)
              ? p.isChecked = true
              : p.isChecked = false);
        }
      });
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }
}
