import 'package:fcs/domain/entities/cargo_type.dart';
import 'package:fcs/domain/entities/discount.dart';
import 'package:fcs/domain/entities/invoice.dart';
import 'package:fcs/domain/entities/rate.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

typedef OnDiscountSelected(Discount discount);
typedef OnDeliveryFeeSelected(bool selected);
typedef OnRemove(InvoiceTableRow row);
final formatter = new NumberFormat("#,###.00");

enum InvoiceDataType {
  CargoDataType,
  DiscountDataType,
  CustomFeeDataType,
  HandlingFeeType,
  DeliveryFeeType,
}

class InvoiceTableRow {
  final dynamic data;
  final String id;
  final InvoiceDataType invoiceDataType;
  final String desc;
  final String rate;
  final String amount;

  InvoiceTableRow(
      {this.id,
      this.data,
      this.invoiceDataType,
      this.desc,
      this.rate,
      this.amount});
}

class InvoiceTable extends StatelessWidget {
  final Invoice invoice;
  final Rate rate;
  final OnDiscountSelected discountSelected;
  final OnDeliveryFeeSelected deliveryFeeSelected;
  final OnRemove onRemove;

  const InvoiceTable(
      {Key key,
      this.invoice,
      this.discountSelected,
      this.deliveryFeeSelected,
      this.onRemove,
      this.rate})
      : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Column(children: getRows(context));
  }

  List<InvoiceTableRow> getTableRows() {
    List<InvoiceTableRow> tableRows = [];
    // add cargo types
    List<CargoType> _cargoTypes = invoice.getCargoTypes(rate) ?? [];
    _cargoTypes.forEach((c) {
      tableRows.add(InvoiceTableRow(
          invoiceDataType: InvoiceDataType.CargoDataType,
          desc: c.name,
          rate:
              "${c.calWeight.toStringAsFixed(2)} x ${c.calRate.toStringAsFixed(2)}",
          amount: "${c.calAmount.toStringAsFixed(2)}"));
    });
    invoice.shipments.where((ss) => (ss.isSelected ?? false)).forEach((s) {
      tableRows.add(InvoiceTableRow(
          data: s,
          invoiceDataType: InvoiceDataType.HandlingFeeType,
          desc: "Handling fee\n${s.shipmentNumber}",
          rate: "",
          amount: "${s.handlingFee.toStringAsFixed(2)}"));
    });
    // // add custom fee
    invoice.customDuties.forEach((c) {
      tableRows.add(InvoiceTableRow(
          data: c,
          invoiceDataType: InvoiceDataType.CustomFeeDataType,
          desc: "${c.productType} custom fee",
          rate: "",
          amount: "${c.fee.toStringAsFixed(2)}"));
    });
    // // add delivery fee
    tableRows.add(InvoiceTableRow(
        data: invoice.deliveryFee == null || invoice.deliveryFee == 0
            ? null
            : invoice.deliveryFee,
        invoiceDataType: InvoiceDataType.DeliveryFeeType,
        desc: "Delivery fee",
        rate: "",
        amount: "${invoice?.deliveryFee?.toStringAsFixed(2) ?? '0'}"));

    // // add discounts
    if (invoice.discount != null) {
      tableRows.add(InvoiceTableRow(
          data: invoice.discount,
          invoiceDataType: InvoiceDataType.DiscountDataType,
          desc: "Discount\n${invoice?.discount?.code ?? ""}",
          rate: "",
          amount: "(${invoice?.discount?.amount?.toStringAsFixed(2) ?? ''})"));
    }

    return tableRows;
  }

  getRows(BuildContext context) {
    List<InvoiceTableRow> tableRows = getTableRows();

    List<Widget> dataRow = tableRows.map((r) {
      return Container(
        decoration: BoxDecoration(
            border: Border(bottom: BorderSide(color: Colors.grey))),
        padding: const EdgeInsets.only(
            left: 5.0, right: 5.0, top: 10.0, bottom: 10.0),
        child: Row(
          children: [
            Expanded(
                flex: 2,
                child: Row(
                  children: [
                    Flexible(child: Text('${r.desc}')),
                    SizedBox(
                      width: 5,
                    ),
                    r.data == null || onRemove == null
                        ? Container()
                        : InkWell(
                            onTap: () => onRemove(r),
                            child: Icon(
                              Icons.remove_circle,
                              color: Colors.black45,
                            ),
                          )
                  ],
                )),
            Expanded(
                flex: 1,
                child: Text(
                  '${r.rate}',
                  textAlign: TextAlign.end,
                  style: TextStyle(fontSize: 12),
                )),
            Expanded(
                flex: 1,
                child: Text('\$ ${r.amount}',
                    textAlign: TextAlign.end,
                    style: TextStyle(
                      fontSize: 14,
                      fontWeight: FontWeight.bold,
                    )))
          ],
        ),
      );
    }).toList();
    dataRow.insert(
        0,
        Container(
          padding: const EdgeInsets.only(
              left: 5.0, right: 5.0, top: 15.0, bottom: 15.0),
          decoration: BoxDecoration(
              border: Border(bottom: BorderSide(color: Colors.grey))),
          child: Row(
            children: [
              Expanded(
                  flex: 2,
                  child: Text(getLocalString(context, 'invoice.box.desc'),
                      style: TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.bold,
                          color: Colors.grey))),
              Expanded(
                  flex: 2,
                  child: Text(
                      getLocalString(context, 'invoice.weight') +
                          ' x ' +
                          getLocalString(context, 'invoice.rate'),
                      textAlign: TextAlign.center,
                      style: TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.bold,
                          color: Colors.grey))),
              Expanded(
                  child: Text(getLocalString(context, 'invoice.amount'),
                      textAlign: TextAlign.end,
                      style: TextStyle(
                          fontSize: 12,
                          fontWeight: FontWeight.bold,
                          color: Colors.grey)))
            ],
          ),
        ));

    dataRow.insert(
        dataRow.length,
        Container(
          padding: const EdgeInsets.only(
              left: 5.0, right: 5.0, top: 10.0, bottom: 10.0),
          child: Row(
            children: [
              Expanded(
                flex: 1,
                child: Container(
                  alignment: Alignment.centerRight,
                  child: LocalText(
                    context,
                    'invoice.total',
                    color: Colors.black,
                  ),
                ),
              ),
              SizedBox(width: 20),
              Text(
                '\$ ${invoice.getNetAmount(rate).toStringAsFixed(2)}',
                style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
                textAlign: TextAlign.end,
              )
            ],
          ),
        ));

    return dataRow;
  }
}
