import 'dart:io';

import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/invoice.dart';
import 'package:fcs/domain/entities/payment.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/localization/app_translations.dart';
import 'package:fcs/pages/invoice/model/invoice_model.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/img_picker.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/local_title.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

class PaymentPage extends StatefulWidget {
  final Invoice invoice;
  final bool forCustomer;
  PaymentPage({this.invoice, this.forCustomer});

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

class _PaymentPageState extends State<PaymentPage> {
  TextEditingController _amountController = new TextEditingController();
  var dateFormatter = new DateFormat('dd MMM yyyy');

  Invoice _invoice = new Invoice();
  bool _isLoading = false;

  bool isNew;
  File _file;
  bool _hasBalance;

  @override
  void initState() {
    super.initState();
    _invoice = widget.invoice;
    _hasBalance = widget.invoice.balance > 0;
    _loadInvoice();
  }

  _loadInvoice() async {
    InvoiceModel invoiceModel =
        Provider.of<InvoiceModel>(context, listen: false);
    Invoice i = await invoiceModel.getInvoice(_invoice.id);
    setState(() {
      _invoice = i;
    });
  }

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

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

  @override
  Widget build(BuildContext context) {
    final amountBox = InputText(
        labelTextKey: 'pm.amount',
        controller: _amountController,
        iconData: FontAwesomeIcons.moneyBill);

    final receiptFileBox = Row(children: [
      Padding(
        padding: const EdgeInsets.only(right: 8.0),
        child: Text("Attach receipt"),
      ),
      LocalImagePicker(
        color: primaryColor,
        title: "Receipt",
        onFile: (f) => _file = f,
      )
    ]);

    final payBtnBox = LocalButton(
      callBack: _pay,
      textKey: "pm.pay",
    );

    return LocalProgress(
      inAsyncCall: _isLoading,
      child: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          leading: new IconButton(
            icon: new Icon(CupertinoIcons.back),
            onPressed: () => Navigator.of(context).pop(),
          ),
          backgroundColor: primaryColor,
          title: Text(AppTranslations.of(context).text("pm_.title")),
        ),
        body: ListView(
          padding: const EdgeInsets.all(10.0),
          children: <Widget>[
            _hasBalance ? amountBox : Container(),
            SizedBox(height: 10),
            _hasBalance
                ? Align(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: receiptFileBox,
                    ),
                    alignment: Alignment.centerLeft,
                  )
                : Container(),
            _hasBalance ? payBtnBox : Container(),
            SizedBox(height: 15),
            LocalTitle(textKey: "pm.receipt"),
            Column(
              children: getCustomFeeRows(context),
            ),
            SizedBox(height: 25),
          ],
        ),
      ),
    );
  }

  getCustomFeeRows(BuildContext context) {
    List<Widget> dataRow = [];

    dataRow = _invoice?.payments?.map((p) {
          return Container(
            decoration: BoxDecoration(
                border: Border(bottom: BorderSide(color: Colors.grey))),
            padding: const EdgeInsets.only(
                left: 5.0, right: 5.0, top: 5.0, bottom: 5.0),
            child: Row(
              children: [
                Expanded(
                    flex: 1,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Padding(
                          padding: const EdgeInsets.only(left: 8.0),
                          child: Text(
                              '${p.paymentDate != null ? dateFormatter.format(p.paymentDate) : ""}'),
                        ),
                        SizedBox(
                          height: 5,
                        ),
                        LocalImagePicker(
                          key: ValueKey(p.id),
                          enabled: false,
                          initialImgUrl: p.paymentReceiptURL,
                          title: "Receipt",
                          color: primaryColor,
                        )
                      ],
                    )),
                Expanded(
                    flex: 1,
                    child: Center(
                        child: Column(
                      children: [Text('\$ ${p.amount}'), Text('${p.status}')],
                    ))),
                widget.forCustomer
                    ? Container()
                    : Expanded(
                        flex: 1,
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: p.status == payment_pending_status
                              ? [
                                  InkWell(
                                    onTap: () => _confirm(p),
                                    child: Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: Icon(
                                        Icons.check,
                                        color: primaryColor,
                                      ),
                                    ),
                                  ),
                                  InkWell(
                                    onTap: () => _cancel(p),
                                    child: Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: Icon(Icons.close,
                                          color: primaryColor),
                                    ),
                                  ),
                                ]
                              : [],
                        )),
              ],
            ),
          );
        })?.toList() ??
        [];

    dataRow.insert(
        0,
        Container(
          decoration: BoxDecoration(
              border: Border(bottom: BorderSide(color: Colors.grey))),
          padding: const EdgeInsets.only(
              left: 5.0, right: 5.0, top: 10.0, bottom: 15.0),
          child: Row(
            children: [
              Expanded(
                  flex: 1,
                  child: Text('Receipt', style: TextStyle(color: Colors.grey))),
              Expanded(
                  flex: 1,
                  child: Text('Amount',
                      textAlign: TextAlign.center,
                      style: TextStyle(color: Colors.grey))),
              widget.forCustomer
                  ? Container()
                  : Expanded(
                      flex: 1,
                      child: Text('Actions',
                          textAlign: TextAlign.center,
                          style: TextStyle(color: Colors.grey))),
            ],
          ),
        ));

    dataRow.insert(
        dataRow.length,
        Container(
          padding: const EdgeInsets.only(
              left: 5.0, right: 5.0, top: 15.0, bottom: 15.0),
          child: Row(
            children: [
              Expanded(
                flex: 1,
                child: Center(
                  child: LocalText(
                    context,
                    'pm.remaining_balance',
                    color: Colors.black,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
              Expanded(
                  flex: 1,
                  child: Center(
                      child: Text(
                          '\$ ${widget.invoice.balance.toStringAsFixed(2)}',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                              fontWeight: FontWeight.bold, fontSize: 16.0)))),
              widget.forCustomer
                  ? Container()
                  : Expanded(
                      flex: 1,
                      child: Container(),
                    ),
            ],
          ),
        ));
    return dataRow;
  }

  _confirm(Payment payment) {
    payment.status = payment_confirmed_status;
    showConfirmDialog(context, "invoice.payment.confirm.confirm",
        () => _updatePayment(payment));
  }

  _cancel(Payment payment) {
    payment.status = payment_canceled_status;
    showConfirmDialog(context, "invoice.payment.cancel.confirm",
        () => _updatePayment(payment));
  }

  _updatePayment(Payment payment) async {
    payment.invoiceID = widget.invoice.id;
    setState(() {
      _isLoading = true;
    });
    try {
      InvoiceModel invoiceModel =
          Provider.of<InvoiceModel>(context, listen: false);
      await invoiceModel.updatePaymentStatus(payment);
      Navigator.pop(context, true);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  _pay() async {
    if (_file == null) {
      showMsgDialog(context, "Error", "Expect receipt attachment");
      return;
    }
    double amount = double.tryParse(_amountController.text) ?? 0;
    if (amount <= 0) {
      showMsgDialog(context, "Error", "Expect valid amount");
      return;
    }
    Payment payment = Payment(invoiceID: _invoice.id, amount: amount);
    setState(() {
      _isLoading = true;
    });
    try {
      InvoiceModel invoiceModel =
          Provider.of<InvoiceModel>(context, listen: false);
      await invoiceModel.pay(payment, _file);
      Navigator.pop(context, true);
    } catch (e) {
      showMsgDialog(context, "Error", e.toString());
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }
}
