import {useMutation, useQuery} from "@apollo/client";
import {Button, Form, Popconfirm, Space} from "antd";
import dayjs from "../../utils/day";
import queryString from "query-string";
import React, { 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 { setModalContext } from "../../redux/modals/modals.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AuditTrailMapping from "../../utils/AuditTrailMappings";
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";
import {PageHeader} from "@ant-design/pro-layout";

const mapStateToProps = createStructuredSelector({
    bodyshop: selectBodyshop,
});
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, bodyshop,}) {
    const search = queryString.parse(useLocation().search);

    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 [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
        )
            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((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) => {
            const {deductedfromlbr, inventories, jobline, ...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);
    };

    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 (
    <>
      {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
                  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} />

                        {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
        ? {
            ...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 ? dayjs(data.bills_by_pk.date) : null,
        }
        : {};
};
