import { createTypedReducerWithImmer } from "@insite/client-framework/Common/CreateTypedReducer";
import { Cart } from "@insite/client-framework/Services/CartService";
import OnePageCheckoutState from "@insite/client-framework/Store/Pages/OnePageCheckout/OnePageCheckoutState";
import { BillToModel, CountryModel, ShipToModel } from "@insite/client-framework/Types/ApiModels";
import { Draft } from "immer";

const initialState: OnePageCheckoutState = {
    isSavingShipping: false,
    isBillingAddressTheSameAsShipping: true,
    isBillingAddressUpdateRequired: false,
    isShippingAddressUpdateRequired: false,
    isUpdatingCustomer: false,
    paymentDetailsState: "waiting",
    isPlacingOrder: false,
};

const reducer = {
    "Pages/OnePageCheckout/SetCartId": (draft: Draft<OnePageCheckoutState>, action: { cartId?: string }) => {
        draft.cartId = action.cartId;
    },
    "Pages/OnePageCheckout/SetInitialValues": (
        draft: Draft<OnePageCheckoutState>,
        action: {
            cart: Cart;
            shipTo?: ShipToModel;
            billTo: BillToModel;
            country?: CountryModel;
        },
    ) => {
        const { cart } = action;
        draft.isBillingAddressTheSameAsShipping = cart.billToId === cart.shipToId;

        if (action.country) {
            action.billTo.country = action.country;
            if (action.shipTo) {
                action.shipTo.country = action.country;
            }
        }

        draft.billingAddressFormState = {
            address: action.billTo,
            formErrors: {},
        };

        if (action.shipTo) {
            draft.shippingAddressFormState = {
                address: action.shipTo,
                formErrors: {},
            };
        }

        draft.additionalEmails = cart.additionalEmails;
    },
    "Pages/OnePageCheckout/BeginSaveShipping": (draft: Draft<OnePageCheckoutState>) => {
        draft.isSavingShipping = true;
    },
    "Pages/OnePageCheckout/CompleteSaveShipping": (draft: Draft<OnePageCheckoutState>) => {
        draft.isSavingShipping = false;
    },
    "Pages/OnePageCheckout/SetBillingAddress": (
        draft: Draft<OnePageCheckoutState>,
        action: { address: BillToModel },
    ) => {
        if (!draft.billingAddressFormState) {
            return;
        }

        draft.billingAddressFormState.address = action.address;
    },
    "Pages/OnePageCheckout/SetBillingAddressFormErrors": (
        draft: Draft<OnePageCheckoutState>,
        action: { formErrors: { [key: string]: React.ReactNode } },
    ) => {
        if (!draft.billingAddressFormState) {
            return;
        }

        draft.billingAddressFormState.formErrors = action.formErrors;
    },
    "Pages/OnePageCheckout/SetShippingAddress": (
        draft: Draft<OnePageCheckoutState>,
        action: { address: ShipToModel },
    ) => {
        if (!draft.shippingAddressFormState) {
            return;
        }

        draft.shippingAddressFormState.address = action.address;
    },
    "Pages/OnePageCheckout/SetShippingAddressFormErrors": (
        draft: Draft<OnePageCheckoutState>,
        action: { formErrors: { [key: string]: React.ReactNode } },
    ) => {
        if (!draft.shippingAddressFormState) {
            return;
        }

        draft.shippingAddressFormState.formErrors = action.formErrors;
    },
    "Pages/OnePageCheckout/SetIsBillingAddressTheSameAsShipping": (
        draft: Draft<OnePageCheckoutState>,
        action: { isBillingAddressTheSameAsShipping: boolean },
    ) => {
        draft.isBillingAddressTheSameAsShipping = action.isBillingAddressTheSameAsShipping;
    },
    "Pages/OnePageCheckout/BeginUpdateShipTo": (draft: Draft<OnePageCheckoutState>) => {
        draft.isUpdatingCustomer = true;
    },
    "Pages/OnePageCheckout/CompleteUpdateShipTo": (
        draft: Draft<OnePageCheckoutState>,
        action: { shipTo: ShipToModel },
    ) => {
        draft.shippingAddressFormState = {
            address: action.shipTo,
            formErrors: {},
        };
        draft.isUpdatingCustomer = false;
    },
    "Pages/OnePageCheckout/BeginUpdateBillTo": (draft: Draft<OnePageCheckoutState>) => {
        draft.isUpdatingCustomer = true;
    },
    "Pages/OnePageCheckout/CompleteUpdateBillTo": (
        draft: Draft<OnePageCheckoutState>,
        action: { billTo: BillToModel },
    ) => {
        draft.billingAddressFormState = {
            address: action.billTo,
            formErrors: {},
        };
        draft.isUpdatingCustomer = false;
    },
    "Pages/OnePageCheckout/SetIsBillingAddressUpdateRequired": (
        draft: Draft<OnePageCheckoutState>,
        action: { isBillingAddressUpdateRequired: boolean },
    ) => {
        draft.isBillingAddressUpdateRequired = action.isBillingAddressUpdateRequired;
    },
    "Pages/OnePageCheckout/SetIsShippingAddressUpdateRequired": (
        draft: Draft<OnePageCheckoutState>,
        action: { isShippingAddressUpdateRequired: boolean },
    ) => {
        draft.isShippingAddressUpdateRequired = action.isShippingAddressUpdateRequired;
    },
    "Pages/OnePageCheckout/SetPaymentDetailsState": (
        draft: Draft<OnePageCheckoutState>,
        action: { paymentDetailsState: "waiting" | "active" | "complete" },
    ) => {
        draft.paymentDetailsState = action.paymentDetailsState;
    },
    "Pages/OnePageCheckout/SetIsPlacingOrder": (
        draft: Draft<OnePageCheckoutState>,
        action: { isPlacingOrder: boolean },
    ) => {
        draft.isPlacingOrder = action.isPlacingOrder;
    },
    "Pages/OnePageCheckout/BeginPlaceOrder": (draft: Draft<OnePageCheckoutState>) => {
        draft.isPlacingOrder = true;
        draft.placeOrderErrorMessage = undefined;
    },
    "Pages/OnePageCheckout/SetPlaceOrderErrorMessage": (
        draft: Draft<OnePageCheckoutState>,
        action: { errorMessage?: string },
    ) => {
        draft.placeOrderErrorMessage = action.errorMessage;
    },
    "Pages/OnePageCheckout/CompletePlaceOrder": (draft: Draft<OnePageCheckoutState>) => {
        draft.isPlacingOrder = false;
        draft.cartId = undefined;
        draft.requestedDeliveryDate = undefined;
        draft.paymentDetailsState = "waiting";
        draft.additionalEmails = undefined;
    },
    "Pages/OnePageCheckout/FailedToPlaceOrder": (
        draft: Draft<OnePageCheckoutState>,
        action: { errorMessage?: string },
    ) => {
        draft.isPlacingOrder = false;
        draft.placeOrderErrorMessage = action.errorMessage;
    },
    "Pages/OnePageCheckout/BeginPlaceOrderForApproval": (draft: Draft<OnePageCheckoutState>) => {
        draft.isPlacingOrder = true;
        draft.placeOrderErrorMessage = undefined;
    },
    "Pages/OnePageCheckout/CompletePlaceOrderForApproval": (draft: Draft<OnePageCheckoutState>) => {
        draft.isPlacingOrder = false;
        draft.cartId = undefined;
        draft.requestedDeliveryDate = undefined;
    },
    "Pages/OnePageCheckout/SetRequestedDeliveryDate": (
        draft: Draft<OnePageCheckoutState>,
        action: { requestedDeliveryDate?: Date; requestedDeliveryDateDisabled?: boolean },
    ) => {
        draft.requestedDeliveryDate = action.requestedDeliveryDate;
        draft.requestedDeliveryDateDisabled = action.requestedDeliveryDateDisabled;
    },
    "Pages/OnePageCheckout/SetRequestedPickUpDate": (
        draft: Draft<OnePageCheckoutState>,
        action: { requestedPickUpDate?: Date; requestedPickUpDateDisabled?: boolean },
    ) => {
        draft.requestedPickupDate = action.requestedPickUpDate;
        draft.requestedPickUpDateDisabled = action.requestedPickUpDateDisabled;
    },
    "Pages/OnePageCheckout/SetNotes": (draft: Draft<OnePageCheckoutState>, action: { notes: string }) => {
        draft.editedCartNotes = action.notes;
    },
    "Pages/OnePageCheckout/SetAdditionalEmails": (
        draft: Draft<OnePageCheckoutState>,
        action: { additionalEmails: string },
    ) => {
        draft.additionalEmails = action.additionalEmails;
    },
};

export default createTypedReducerWithImmer(initialState, reducer);
