import { PageHeader } from "@ant-design/pro-layout";
import { useMutation, useQuery } from "@apollo/client/react";
import { Button, Divider, Form, Popconfirm, Space } from "antd";
import queryString from "query-string";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import { DELETE_BILL_LINE, INSERT_NEW_BILL_LINES, UPDATE_BILL_LINE } from "../../graphql/bill-lines.queries";
import { QUERY_BILL_BY_PK, UPDATE_BILL } from "../../graphql/bills.queries";
import { insertAuditTrail } from "../../redux/application/application.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
import dayjs from "../../utils/day";
import { buildBillUpdateAuditDetails } from "../../utils/auditTrailDetails";
import AlertComponent from "../alert/alert.component";
import BillFormContainer from "../bill-form/bill-form.container";
import BillMarkExportedButton from "../bill-mark-exported-button/bill-mark-exported-button.component";
import BillPrintButton from "../bill-print-button/bill-print-button.component";
import BillReeportButtonComponent from "../bill-reexport-button/bill-reexport-button.component";
import JobDocumentsGallery from "../jobs-documents-gallery/jobs-documents-gallery.container";
import JobsDocumentsLocalGallery from "../jobs-documents-local-gallery/jobs-documents-local-gallery.container";
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
import BillDetailEditReturn from "./bill-detail-edit-return.component";

const mapStateToProps = createStructuredSelector({
  bodyshop: selectBodyshop
});
const mapDispatchToProps = (dispatch) => ({
  insertAuditTrail: ({ jobid, operation, type }) => dispatch(insertAuditTrail({ jobid, operation, type }))
});

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

export function BillDetailEditcontainer({ insertAuditTrail, bodyshop }) {
  const search = queryString.parse(useLocation().search);

  const { t } = useTranslation();
  const [form] = Form.useForm();
  const [open, setOpen] = 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 [deleteBillLine] = useMutation(DELETE_BILL_LINE);

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

  // ... rest of the code remains the same

  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
    )
      setOpen(true);
    else {
      form.submit();
    }
  };

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

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

    billlines.forEach((l) => {
      delete l.selected;
    });

    //Find bill lines that were deleted.
    const deletedJobLines = [];

    data?.bills_by_pk?.billlines.forEach((a) => {
      const matchingRecord = billlines.find((b) => b.id === a.id);
      if (!matchingRecord) {
        deletedJobLines.push(a);
      }
    });

    deletedJobLines.forEach((d) => {
      updates.push(deleteBillLine({ variables: { id: d.id } }));
    });

    billlines.forEach((billline) => {
      // eslint-disable-next-line no-unused-vars
      const { deductedfromlbr, inventories, jobline, original_actual_price, create_ppc, ...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);

    const details = buildBillUpdateAuditDetails({
      originalBill: data?.bills_by_pk,
      bill,
      billlines
    });

    insertAuditTrail({
      jobid: bill.jobid ?? data?.bills_by_pk?.jobid,
      billid: search.billid,
      operation: AuditTrailMapping.billupdated(bill.invoice_number, details),
      type: "billupdated"
    });

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

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

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

  return (
    <>
      {loading && <LoadingSkeleton />}
      {data && (
        <>
          <PageHeader
            title={data && `${data?.bills_by_pk?.invoice_number} - ${data?.bills_by_pk?.vendor?.name}`}
            extra={
              <Space>
                <BillDetailEditReturn data={data} />
                <BillPrintButton billid={search.billid} />
                <Popconfirm
                  open={open}
                  onConfirm={() => form.submit()}
                  onCancel={() => setOpen(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?.bills_by_pk} />
                <BillMarkExportedButton bill={data?.bills_by_pk} />
              </Space>
            }
          />
          <Form form={form} onFinish={handleFinish} initialValues={transformData(data)} layout="vertical">
            <BillFormContainer form={form} billEdit disabled={exported} disableInHouse={isinhouse} />
            <Divider titlePlacement="left">{t("general.labels.media")}</Divider>
            {bodyshop.uselocalmediaserver ? (
              <JobsDocumentsLocalGallery
                job={{ id: data ? data?.bills_by_pk?.jobid : null }}
                invoice_number={data ? data?.bills_by_pk?.invoice_number : null}
                vendorid={data ? data?.bills_by_pk?.vendorid : null}
              />
            ) : (
              <JobDocumentsGallery
                jobId={data ? data?.bills_by_pk?.jobid : null}
                billId={search.billid}
                documentsList={data ? data?.bills_by_pk?.documents : []}
                billsCallback={refetch}
              />
            )}
          </Form>
        </>
      )}
    </>
  );
}

const transformData = (data) => {
  return data?.bills_by_pk
    ? {
        ...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?.federal || false,
              state: i.applicable_taxes?.state || false,
              local: i.applicable_taxes?.local || false
            }
          };
        }),
        date: data.bills_by_pk ? dayjs(data.bills_by_pk.date) : null
      }
    : {};
};
