import {useMutation, useQuery} from "@apollo/client";
import {
    Button,
    Descriptions,
    InputNumber,
    Modal,
    Space,
    notification,
} from "antd";
import axios from "axios";
import dayjs from "../../utils/day";
import React, {useState} from "react";
import {useTranslation} from "react-i18next";
import {
    GET_REFUNDABLE_AMOUNT_BY_JOBID,
    INSERT_PAYMENT_RESPONSE,
    QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID,
} from "../../graphql/payment_response.queries";
import {INSERT_NEW_PAYMENT} from "../../graphql/payments.queries";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import {DateTimeFormatter} from "../../utils/DateFormatter";

const {confirm} = Modal;

const openNotificationWithIcon = (type, t) => {
    notification[type]({
        message: t("job_payments.notifications.error.title"),
        description: t("job_payments.notifications.error.description"),
    });
};

const PaymentExpandedRowComponent = ({record, bodyshop}) => {
    const [refundAmount, setRefundAmount] = useState(0);
    const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
    const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
    const {t} = useTranslation();

    const {loading, error, data} = useQuery(
        QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID,
        {
            variables: {
                paymentid: record.id,
                fetchPolicy: "network-only",
                nextFetchPolicy: "network-only",
            },
        }
    );

    const {data: refundable_amount, refetch} = useQuery(
        GET_REFUNDABLE_AMOUNT_BY_JOBID,
        {
            variables: {
                jobid: record.jobid,
            },
        }
    );

    const insertPayments = async (payment_response, refund_response) => {
        await insertPayment({
            variables: {
                paymentInput: {
                    amount: -refund_response.data.amount,
                    transactionid: payment_response.response.receiptelements.transid,
                    payer: record.payer,
                    type: "Refund",
                    jobid: payment_response.jobid,
                    date: dayjs(Date.now()),
                },
            },
            update(cache, {data}) {
                cache.modify({
                    id: cache.identify({
                        id: payment_response.jobid,
                        __typename: "jobs",
                    }),
                    fields: {
                        payments(payments) {
                            return [...data.insert_payments.returning, ...payments];
                        },
                    },
                });
            },
        });

        await insertPaymentResponse({
            variables: {
                paymentResponse: {
                    amount: -refund_response.data.amount,
                    bodyshopid: payment_response.bodyshopid,
                    paymentid: payment_response.paymentid,
                    jobid: payment_response.jobid,
                    declinereason: "Refund",
                    ext_paymentid: payment_response.ext_paymentid,
                    successful: true,
                    response: refund_response.data,
                },
            },
        });
    };

    const showConfirm = (payment_response) => {
        confirm({
            title: "Do you want to refund payment?",
            content:
                "The payment will be refunded. Click OK to confirm and Cancel to dismiss.",
            async onOk() {
                const refundResponse = await axios.post("/intellipay/payment_refund", {
                    bodyshop,
                    amount: refundAmount,
                    paymentid: payment_response.ext_paymentid,
                });

                if (refundResponse.data.status < 0) {
                    openNotificationWithIcon("error", t);
                    return;
                }

                insertPayments(payment_response, refundResponse);

                // refetch refundable amount
                refetch();
            },
            onCancel() {
            },
        });
    };

    if (loading) return null;

    if (error) return <p>Error loading data. Please Reload</p>;

    const payment_response = data.payment_response[0];
    const max_refundable_amount =
        refundable_amount?.payment_response_aggregate.aggregate.sum.amount;

    return (
        <div>
            <Descriptions
                title={t("job_payments.titles.descriptions")}
                contentStyle={{fontWeight: "600"}}
                column={4}
            >
                <Descriptions.Item label={t("job_payments.titles.payer")}>
                    {record.payer}
                </Descriptions.Item>
                <Descriptions.Item label={t("job_payments.titles.payername")}>
                    {payment_response?.response?.nameOnCard ?? ""}
                </Descriptions.Item>
                <Descriptions.Item label={t("job_payments.titles.amount")}>
                    <CurrencyFormatter>{record.amount}</CurrencyFormatter>
                </Descriptions.Item>
                <Descriptions.Item label={t("job_payments.titles.dateOfPayment")}>
                    {<DateTimeFormatter>{record.created_at}</DateTimeFormatter>}
                </Descriptions.Item>
                <Descriptions.Item label={t("job_payments.titles.transactionid")}>
                    {record.transactionid}
                </Descriptions.Item>
                <Descriptions.Item label={t("job_payments.titles.paymentid")}>
                    {payment_response?.response?.paymentreferenceid ?? ""}
                </Descriptions.Item>
                <Descriptions.Item label={t("job_payments.titles.paymenttype")}>
                    {record.type}
                </Descriptions.Item>
                <Descriptions.Item label={t("job_payments.titles.paymentnum")}>
                    {record.paymentnum}
                </Descriptions.Item>
                {payment_response && (
                    <Descriptions.Item label={t("job_payments.titles.refundamount")}>
                        <Space>
                            <InputNumber
                                onChange={setRefundAmount}
                                max={max_refundable_amount}
                                min={0}
                            />

                            <Button onClick={() => showConfirm(payment_response)}>
                                {t("job_payments.buttons.refundpayment")}
                            </Button>
                        </Space>
                    </Descriptions.Item>
                )}
            </Descriptions>
        </div>
    );
};

export default PaymentExpandedRowComponent;
