'use client'
/*
  @author: Hemal
  File: Payment.tsx
  Description: This file contains the Payment component, which displays the payment page for a property.
  It also handles navigation to the payment page for a property.
*/
import { AppDispatch, RootState } from '@/redux/slices'
import { bookingActions } from '@/redux/slices/Booking/booking'
import { commonActions } from '@/redux/slices/Common/commonSlice'
import getViewPropertyAvailability, { cancelBooking, createBooking, getBookingSummary, getViewBooking, paymentDetailsAddEdit } from '@/redux/thunks/Booking/booking.thunk'
import RadioPayment from '@/src/components/RadioPayment'
import { Toast } from '@/src/components/Toast'
import { BookingContent } from '@/src/types/StaticContent/booking.content.type'
import { PropertyDetailContent } from '@/src/types/StaticContent/propertydetail.content.type'
import { scrollToTop } from '@/src/utils/commonFunctions'
import useIsClient from '@/src/utils/customHooks/useIsClient'
import useIsMobile from '@/src/utils/customHooks/useIsMobile'
import Routes from '@/src/utils/RouteConstants'
import { zodResolver } from "@hookform/resolvers/zod"
import { BookingSummary, BookingTimer } from 'blankbase-packages'
import { useRouter } from 'next/navigation'
import { useEffect, useState } from 'react'
import { FormProvider, useForm } from "react-hook-form"
import { useDispatch, useSelector } from 'react-redux'
import { z } from "zod"


const Payment = ({ slug, bookingId, BOOKING, PropertyDetailContent }: { PropertyDetailContent: PropertyDetailContent, slug: string; bookingId?: string, BOOKING: BookingContent }) => {
    const router = useRouter();
    const dispatch = useDispatch<AppDispatch>();

    // Mobile accordion
    const isMobile = useIsMobile();
    const isClient = useIsClient();
    const [selectedPaymentData, setSelectedPaymentData] = useState(null);
    const { viewBookingData, viewPropertyAvailability, bookingSummary, isbookingSummaryLoading } = useSelector((state: RootState) => state.booking);
    const { showDraftedModal, afterDraftedNavigation, isBookingFlow } = useSelector((state: RootState) => state.common)
    const [propertySpaceIds, setPropertySpaceIds] = useState<string[]>([])

    useEffect(() => {
        if (viewBookingData) {
            if (viewBookingData?.data?.isColivingBooking) {
                const bedroomIds = viewBookingData?.data?.propertySpaceData?.map((item: any) => item.propertySpaceId)
                setPropertySpaceIds(bedroomIds || []);
            }
        }
    }, [viewBookingData])

    const formSchema = z
        .object({
            name: z.string().min(1, { message: "Name on card is required" }).trim(),

            cardNumber: z
                .string()
                .trim()
                .min(1, { message: "Card number is required" })
                .regex(/^\d{13,19}$/, { message: "Card number must be 13–19 digits" }),

            cardExpiry: z
                .string()
                .trim()
                .min(1, { message: "Card expiry is required" })
                .regex(/^(0[1-9]|1[0-2])\/\d{2}$/, {
                    message: "Invalid card expiry.",
                }),

            cardCvv: z
                .string()
                .trim()
                .min(3, { message: "Card CVV is required" })
                .regex(/^\d{3,4}$/, {
                    message: "CVV must be 3 or 4 digits",
                }),

            saveForFutureUsage: z.boolean().optional(),
        })
        .refine((data) => {
            const [month, year] = data.cardExpiry.split("/").map(Number);
            if (!month || !year) return false;

            const now = new Date();
            const inputDate = new Date(2000 + year, month - 1); // assume 20YY

            return inputDate >= new Date(now.getFullYear(), now.getMonth());
        }, {
            path: ["cardExpiry"],
            message: "Card expiry must be a future date",
        });


    const methods = useForm<any>({
        /**
         * Resolver integrates Zod schema validation into React Hook Form.
         * Ensures validation logic defined in `SignUpSchema` is applied.
         */
        resolver: zodResolver(formSchema),
        /**
         * Mode configuration for when validation should occur.
         * - `"onChange"`: Validates fields on every change.
         * - Ensures instant feedback for better UX.
         */
        mode: "onChange",
    });

    /**
       * Initializes the useForm hook for managing form state and validation.
       *
       * @typedef {formSchema} - The expected data structure for the sign-up form.
       */
    const {
        handleSubmit,
        formState: { errors },
        register,
        watch,
        control,
        getValues,
        setValue
    } = methods

    useEffect(() => {
        dispatch(bookingActions.resetBookingSummary());
        dispatch(bookingActions.resetViewPropertyAvailability());
    }, [])

    useEffect(() => {
        if (viewBookingData?.data?.propertyId) {
            dispatch(getViewPropertyAvailability({ propertyId: viewBookingData?.data?.propertyId, bookingId: bookingId, propertySpaceIds: propertySpaceIds }))
        }
        if (viewBookingData?.data && viewBookingData?.data?.bookingStatus === "confirmed") {
            router.push(`${Routes.FIND_A_HOME}`)
        }
    }, [viewBookingData?.data?.propertyId])

    useEffect(() => {
        if (bookingId) {
            dispatch(getViewBooking({ bookingId: bookingId, propertySpaceIds: propertySpaceIds }, (res) => {
                if (!res?.meta?.status) {
                    Toast('error', res?.meta?.message);
                    router.push(`${Routes.FIND_A_HOME_INFO(slug)}`);
                }
            }));
        }
    }, [bookingId])

    /**
     * Handles the form submission.
     * 
     * Takes the form data, constructs the booking payload with the necessary information such as property ID, check-in and check-out dates, 
     * the number of guests, and booking flags. Dispatches the paymentDetailsAddEdit action with the payload and navigates to the booking page upon successful
     * payment creation. If the booking is successfully confirmed, navigates to the booking confirmed page.
     */
    const onSubmit = () => {
        const formDate = getValues();
        const payload = {
            paymentDetailId: viewBookingData?.data?.paymentDetailsId,
            name: formDate.name,
            paymentDetailType: "card",
            cardType: "mastercard",
            cardNumber: formDate.cardNumber,
            cardExpiry: formDate.cardExpiry,
            cardCvv: formDate.cardCvv,
            saveForFutureUsage: formDate.saveForFutureUsage
        }
        let finalPayload = selectedPaymentData ? selectedPaymentData : payload;
        dispatch(paymentDetailsAddEdit(finalPayload, (res) => {
            if (res?.meta?.status) {
                const payload = {
                    paymentDetailsId: res?.data?.paymentDetailId,
                    bookingId: bookingId,
                    propertyId: viewBookingData?.data?.propertyId,
                    isGuestBooking: false,
                    checkInDate: viewBookingData?.data?.checkInDate,
                    checkOutDate: viewBookingData?.data?.checkOutDate,
                    numberOfGuest: viewBookingData?.data?.numberOfGuest,
                    skipPayment: true,
                    confirmBooking: true,
                    guestDetails: viewBookingData?.data?.guestDetails,
                    agreedToHouseRules: viewBookingData?.data?.agreedToHouseRules,
                    infoForHost: {
                        specialRequest: viewBookingData?.data?.infoForHost?.specialRequest
                    },
                    propertySpaceIds: propertySpaceIds
                }
                dispatch(createBooking(payload, () => {
                    router.push(`${Routes.BOOKING_CONFIRMED(slug, bookingId)}`);
                }))
            }
        }))
    };

    /**
     * Sets booking payload and fetches booking summary if property is selected.
     * @param payload - Booking data including guests and other details.
     */
    const getApiPayload = (payload) => {
        const { guests, ...rest } = payload;
        const currentPayload = {
            numberOfGuest: guests,
            bookingId: bookingId,
            ...rest,
        };

        if (viewBookingData?.data?.propertyId) {
            dispatch(getBookingSummary(currentPayload));
        }
    }

    return (
        <>
            <div className={`flex items-center justify-start lg:justify-between gap-3 mb-3 md:mb-5 lg:mb-6`}>
                <i className={`Icon IconRightArrow cursor-pointer rotate-180 !bg-grey344Color hover:!bg-primaryColor !w-[22px] !h-[22px] lg:!hidden`}
                    onClick={() => router.back()}></i>
                <h1 className={`h4 !mb-0 !font-fw500`}>{BOOKING.REVIEW_AND_PAYMENT}</h1>
                <div className={`hidden lg:block bg-white p-2.5 px-6 rounded-full text-center`}>
                    <BookingTimer
                        onTimeout={() => {
                            dispatch(commonActions.setLRFModalOpen(false))
                            dispatch(commonActions.setLRFFlow(null))
                            dispatch(commonActions.draftedModal(false))
                            dispatch(commonActions.isBookingFlow(false))
                        }}
                        onTimerRun={() => {
                            dispatch(commonActions.isBookingFlow(true))
                        }}
                        onLeavePageModalClose={() => {
                            dispatch(commonActions.draftedModal(false))
                        }}
                        onBrowserBackButtonEvent={(e) => {
                            if (isBookingFlow) {
                                scrollToTop();
                                e.preventDefault();
                                window.history.pushState(null, '', window.location.pathname);
                                dispatch(commonActions.afterDraftedNavigation(Routes.FIND_A_HOME));
                                dispatch(commonActions.draftedModal(true));
                            } else {
                                router.back();
                            }
                        }}
                        onLeaveSubmit={() => {
                            let payload: any = {
                                bookingId: bookingId,
                                discardBooking: true
                            }
                            dispatch(cancelBooking(payload, () => {
                                if (afterDraftedNavigation) {
                                    dispatch(commonActions.isBookingFlow(false));
                                    dispatch(commonActions.afterDraftedNavigation(null));
                                    setTimeout(() => {
                                        router.replace(afterDraftedNavigation);
                                    }, 100);
                                } else {
                                    dispatch(commonActions.isBookingFlow(false));
                                    dispatch(commonActions.afterDraftedNavigation(null));
                                    setTimeout(() => {
                                        router.replace(Routes.FIND_A_HOME)
                                    }, 100);
                                }
                            }))
                        }}
                        isBookingFlow={isBookingFlow}
                        showDraftedModal={showDraftedModal}
                        viewBookingData={viewBookingData?.data}
                        onBookAgain={() => {
                            router.push(`${Routes.FIND_A_HOME_INFO(slug)}`)
                        }}
                    />
                </div>
            </div>
            <FormProvider {...methods}>
                <form onSubmit={handleSubmit(onSubmit)}>
                    <div className={`flex flex-col lg:flex-row gap-[20px] xl:gap-[24px]`}>
                        {isClient && isMobile &&
                            <>
                                {/* Summary */}
                                <div className={`w-full lg:w-[40%] h-max lg:sticky lg:top-[85px] xxl:top-[110px] booking-summary`}>
                                    <BookingSummary
                                        onSubmit={onSubmit}
                                        userType={'guest'}
                                        viewPropertyAvailabilityData={viewPropertyAvailability?.data}
                                        viewBookingData={viewBookingData?.data}
                                        bookingSummaryData={bookingSummary?.data}
                                        isbookingSummaryLoading={false}
                                        isCreateBookingLoading={false}
                                        getApiPayload={getApiPayload}
                                        isLoggedIn={true}
                                        isEditShow={false}
                                    />
                                </div>
                            </>
                        }
                        <div className={`flex flex-col gap-[20px] xl:gap-[24px] w-full lg:w-[60%]`}>
                            <div className={`bg-white p-4 rounded-[12px] w-full`}>
                                <h2 className={`h6 !mb-4 !font-fw600`}>{BOOKING?.PAYMENT_DETAILS}</h2>
                                <RadioPayment BOOKING={BOOKING} selectedPaymentData={selectedPaymentData} setSelectedPaymentData={setSelectedPaymentData} />
                                {/* Mobile Button Paynow */}
                                {isClient && isMobile &&
                                    <div className={`flex flex-col gap-2.5 pt-4 border-t border-[#E4E7EC]`}>
                                        <button
                                            className={`SecondaryBtn w-full`}
                                            type='submit'
                                        >
                                            {BOOKING.CONFIRM_BOOKING}
                                        </button>
                                        <BookingTimer
                                            onTimeout={() => {
                                                dispatch(commonActions.setLRFModalOpen(false))
                                                dispatch(commonActions.setLRFFlow(null))
                                                dispatch(commonActions.draftedModal(false))
                                                dispatch(commonActions.isBookingFlow(false))
                                            }}
                                            onTimerRun={() => {
                                                dispatch(commonActions.isBookingFlow(true))
                                            }}
                                            onLeavePageModalClose={() => {
                                                dispatch(commonActions.draftedModal(false))
                                            }}
                                            onBrowserBackButtonEvent={(e) => {
                                                if (isBookingFlow) {
                                                    scrollToTop();
                                                    e.preventDefault();
                                                    window.history.pushState(null, '', window.location.pathname);
                                                    dispatch(commonActions.afterDraftedNavigation(Routes.FIND_A_HOME));
                                                    dispatch(commonActions.draftedModal(true));
                                                } else {
                                                    router.back();
                                                }
                                            }}
                                            onLeaveSubmit={() => {
                                                let payload: any = {
                                                    bookingId: bookingId,
                                                    discardBooking: true
                                                }
                                                dispatch(cancelBooking(payload, () => {
                                                    if (afterDraftedNavigation) {
                                                        dispatch(commonActions.isBookingFlow(false));
                                                        dispatch(commonActions.afterDraftedNavigation(null));
                                                        setTimeout(() => {
                                                            router.replace(afterDraftedNavigation);
                                                        }, 100);
                                                    } else {
                                                        dispatch(commonActions.isBookingFlow(false));
                                                        dispatch(commonActions.afterDraftedNavigation(null));
                                                        setTimeout(() => {
                                                            router.replace(Routes.FIND_A_HOME)
                                                        }, 100);
                                                    }
                                                }))
                                            }}
                                            isBookingFlow={isBookingFlow}
                                            showDraftedModal={showDraftedModal}
                                            viewBookingData={viewBookingData?.data}
                                            onBookAgain={() => {
                                                router.push(`${Routes.FIND_A_HOME_INFO(slug)}`)
                                            }}
                                        />
                                    </div>
                                }
                            </div>
                        </div>
                        {/* Summary */}
                        {isClient && !isMobile &&
                            <div className={`w-full lg:w-[40%] h-max lg:sticky lg:top-[85px] xxl:top-[110px] booking-summary`}>
                                <BookingSummary
                                    onSubmit={onSubmit}
                                    userType={'guest'}
                                    viewPropertyAvailabilityData={viewPropertyAvailability?.data}
                                    viewBookingData={viewBookingData?.data}
                                    bookingSummaryData={bookingSummary?.data}
                                    isbookingSummaryLoading={false}
                                    isCreateBookingLoading={false}
                                    getApiPayload={getApiPayload}
                                    isLoggedIn={true}
                                    isEditShow={false}
                                />
                            </div>
                        }
                    </div>
                </form >
            </FormProvider>
        </>
    )
}

export default Payment