import { useMutation, useQuery } from "@apollo/client";
import {
  Button,
  Drawer,
  Form,
  Grid,
  PageHeader,
  Popconfirm,
  Space,
} from "antd";
import moment from "moment";
import queryString from "query-string";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useHistory } from "react-router-dom";
import {
  INSERT_NEW_BILL_LINES,
  UPDATE_BILL_LINE,
} from "../../graphql/bill-lines.queries";
import { QUERY_BILL_BY_PK, UPDATE_BILL } from "../../graphql/bills.queries";
import AlertComponent from "../alert/alert.component";
import BillFormContainer from "../bill-form/bill-form.container";
import JobDocumentsGallery from "../jobs-documents-gallery/jobs-documents-gallery.container";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
import BillReeportButtonComponent from "../bill-reexport-button/bill-reexport-button.component";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { setModalContext } from "../../redux/modals/modals.actions";
import { insertAuditTrail } from "../../redux/application/application.actions";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import BillMarkExportedButton from "../bill-mark-exported-button/bill-mark-exported-button.component";

const mapStateToProps = createStructuredSelector({
  //currentUser: selectCurrentUser
});
const mapDispatchToProps = (dispatch) => ({
  setPartsOrderContext: (context) =>
    dispatch(setModalContext({ context: context, modal: "partsOrder" })),
  insertAuditTrail: ({ jobid, operation }) =>
    dispatch(insertAuditTrail({ jobid, operation })),
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(BillDetailEditcontainer);

export function BillDetailEditcontainer({
  setPartsOrderContext,
  insertAuditTrail,
}) {
  const search = queryString.parse(useLocation().search);
  const history = useHistory();
  const { t } = useTranslation();
  const [form] = Form.useForm();
  const [visible, setVisible] = useState(false);
  const [updateLoading, setUpdateLoading] = useState(false);
  const [update_bill] = useMutation(UPDATE_BILL);
  const [insertBillLine] = useMutation(INSERT_NEW_BILL_LINES);
  const [updateBillLine] = useMutation(UPDATE_BILL_LINE);

  const selectedBreakpoint = Object.entries(Grid.useBreakpoint())
    .filter((screen) => !!screen[1])
    .slice(-1)[0];

  const bpoints = {
    xs: "100%",
    sm: "100%",
    md: "100%",
    lg: "100%",
    xl: "80%",
    xxl: "80%",
  };
  const drawerPercentage = selectedBreakpoint
    ? bpoints[selectedBreakpoint[0]]
    : "100%";

  const { loading, error, data, refetch } = useQuery(QUERY_BILL_BY_PK, {
    variables: { billid: search.billid },
    skip: !!!search.billid,
    fetchPolicy: "network-only",
    nextFetchPolicy: "network-only",
  });

  const handleSave = () => {
    //It's got a previously deducted bill line!
    if (
      data.bills_by_pk.billlines.filter((b) => b.deductedfromlbr).length > 0 ||
      form.getFieldValue("billlines").filter((b) => b.deductedfromlbr).length >
        0
    )
      setVisible(true);
    else {
      form.submit();
    }
  };

  const handleFinish = async (values) => {
    setUpdateLoading(true);
    //let adjustmentsToInsert = {};

    const { billlines, upload, ...bill } = values;
    const updates = [];
    updates.push(
      update_bill({
        variables: { billId: search.billid, bill: bill },
      })
    );

    billlines.forEach((billline) => {
      const { deductedfromlbr, ...il } = billline;
      delete il.__typename;

      if (il.id) {
        updates.push(
          updateBillLine({
            variables: {
              billLineId: il.id,
              billLine: {
                ...il,
                deductedfromlbr: deductedfromlbr,
                joblineid: il.joblineid === "noline" ? null : il.joblineid,
              },
            },
          })
        );
      } else {
        //It's a new line, have to insert it.
        updates.push(
          insertBillLine({
            variables: {
              billLines: [
                {
                  ...il,
                  deductedfromlbr: deductedfromlbr,
                  billid: search.billid,
                  joblineid: il.joblineid === "noline" ? null : il.joblineid,
                },
              ],
            },
          })
        );
      }
    });
    await Promise.all(updates);

    insertAuditTrail({
      jobid: bill.jobid,
      billid: search.billid,
      operation: AuditTrailMapping.billupdated(bill.invoice_number),
    });

    await refetch();
    form.setFieldsValue(transformData(data));
    form.resetFields();
    setVisible(false);
    setUpdateLoading(false);
  };

  useEffect(() => {
    if (search.billid && data) {
      form.resetFields();
    }
  }, [form, search.billid, data]);

  if (error) return <AlertComponent message={error.message} type="error" />;
  if (!search.billid) return <></>; //<div>{t("bills.labels.noneselected")}</div>;

  const exported = data && data.bills_by_pk && data.bills_by_pk.exported;

  return (
    <Drawer
      width={drawerPercentage}
      onClose={() => {
        delete search.billid;
        history.push({ search: queryString.stringify(search) });
      }}
      visible={search.billid}
    >
      {loading && <LoadingSkeleton />}
      {!loading && (
        <>
          <PageHeader
            title={
              data &&
              `${data.bills_by_pk.invoice_number} - ${data.bills_by_pk.vendor.name}`
            }
            extra={
              <Space>
                <Button
                  disabled={data.bills_by_pk.is_credit_memo}
                  onClick={() => {
                    delete search.billid;
                    history.push({ search: queryString.stringify(search) });
                    setPartsOrderContext({
                      actions: {},
                      context: {
                        jobId: data.bills_by_pk.jobid,
                        vendorId: data.bills_by_pk.vendorid,
                        returnFromBill: data.bills_by_pk.id,
                        invoiceNumber: data.bills_by_pk.invoice_number,
                        linesToOrder: data.bills_by_pk.billlines.map((i) => {
                          return {
                            line_desc: i.line_desc,
                            //  db_price: i.actual_price,
                            act_price: i.actual_price,
                            cost: i.actual_cost,
                            quantity: i.quantity,
                            joblineid: i.joblineid,
                          };
                        }),
                        isReturn: true,
                      },
                    });
                  }}
                >
                  {t("bills.actions.return")}
                </Button>

                <Popconfirm
                  visible={visible}
                  onConfirm={() => form.submit()}
                  onCancel={() => setVisible(false)}
                  okButtonProps={{ loading: updateLoading }}
                  title={t("bills.labels.editadjwarning")}
                >
                  <Button
                    htmlType="submit"
                    disabled={exported}
                    onClick={handleSave}
                    loading={updateLoading}
                    type="primary"
                  >
                    {t("general.actions.save")}
                  </Button>
                </Popconfirm>
                <BillReeportButtonComponent bill={data && data.bills_by_pk} />
                <BillMarkExportedButton bill={data && data.bills_by_pk} />
              </Space>
            }
          />
          <Form
            form={form}
            onFinish={handleFinish}
            initialValues={transformData(data)}
            layout="vertical"
          >
            <BillFormContainer form={form} billEdit disabled={exported} />
            <JobDocumentsGallery
              jobId={data ? data.bills_by_pk.jobid : null}
              billId={search.billid}
              documentsList={data ? data.bills_by_pk.documents : []}
              billsCallback={refetch}
            />
          </Form>
        </>
      )}
    </Drawer>
  );
}

const transformData = (data) => {
  return data
    ? {
        ...data.bills_by_pk,

        billlines: data.bills_by_pk.billlines.map((i) => {
          return {
            ...i,
            joblineid: !!i.joblineid ? i.joblineid : "noline",
            applicable_taxes: {
              federal:
                (i.applicable_taxes && i.applicable_taxes.federal) || false,
              state: (i.applicable_taxes && i.applicable_taxes.state) || false,
              local: (i.applicable_taxes && i.applicable_taxes.local) || false,
            },
          };
        }),
        date: data.bills_by_pk ? moment(data.bills_by_pk.date) : null,
      }
    : {};
};
