"use client";
/*
  @author: Hemal
  File: Booking.tsx
  Description: This file contains the Booking component, which displays the booking page for a property.
  It also handles navigation to the booking page for a property.
*/
import { RootState } from "@/redux/slices";
import { commonActions } from "@/redux/slices/Common/commonSlice";
import { AppDispatch } from "@/redux/store";
import getViewPropertyAvailability, {
  cancelBooking,
  createBooking,
  getBookingSummary,
  getViewBooking,
} from "@/redux/thunks/Booking/booking.thunk";
import { getMasterCountryList } from "@/redux/thunks/Master/master.thunk";
import CustomDropdown from "@/src/components/CustomDropdown/CustomDropdown";
// import CustomDropdown from '@/src/components/CustomDropdown/CustomDropdown'
import { Toast } from "@/src/components/Toast";
import { PropertyDetailContent } from "@/src/types/StaticContent/propertydetail.content.type";
import { formatDateYYYYMMDD, scrollToTop } from "@/src/utils/commonFunctions";
import { ARRIVAL_TIME_OPTIONS, REGEX } from "@/src/utils/commonVariables";
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 {
  AboutYouSection,
  BookingSummary,
  BookingTimer,
} from "blankbase-packages";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { Controller, FormProvider, useForm } from "react-hook-form";
import { useDispatch, useSelector } from "react-redux";
import * as z from "zod";

const Booking = ({
  bookingId,
  slug,
  BOOKING,
  profileData,
  PropertyDetailContent,
}: {
  PropertyDetailContent: PropertyDetailContent;
  bookingId: string;
  slug: string;
  BOOKING: any;
  profileData: any;
}) => {
  const dispatch = useDispatch<AppDispatch>();
  const router = useRouter();
  const { countryList } = useSelector(
    (state: RootState) => state.masterActions
  );
  const {
    viewBookingData,
    viewPropertyAvailability,
    bookingSummary,
    isbookingSummaryLoading,
  } = useSelector((state: RootState) => state.booking);

  const [propertySpaceIds, setPropertySpaceIds] = useState<string[]>([]);
  const [bookingSummaryPayload, setBookingSummaryPayload] = useState<any>(null);

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

  const isClient = useIsClient();
  const isMobile = useIsMobile();

  const formSchema = z.object({
    firstName: z.string().min(1, BOOKING.FORM.FIRST_NAME_REQUIRED),
    lastName: z.string().min(1, BOOKING.FORM.LAST_NAME_REQUIRED),
    email: z
      .string()
      .min(1, { message: BOOKING.FORM.EMAIL_REQUIRED }) // Required field
      .regex(REGEX.EMAIL, { message: BOOKING.FORM.EMAIL_INVALID }), // Must follow email pattern
    phoneNumber: z
      .string()
      .min(1, { message: BOOKING.FORM.PHONE_NUMBER_REQUIRED }),
    dateOfBirth: z.date({
      message: BOOKING.FORM.DATE_OF_BIRTH_REQUIRED,
    }),
    nationality: z.object(
      {
        countryId: z.string(),
        name: z.string(),
      },
      { message: BOOKING.FORM.NATIONALITY_REQUIRED }
    ),
    estimatedTimeOfArrival: z.object(
      {
        value: z.string(),
        label: z.string(),
      },
      { message: BOOKING.FORM.ARRIVAL_TIME_REQUIRED }
    ),
    agreedToHouseRules: z.boolean().refine((val) => val === true, {
      message: BOOKING.FORM.HOME_RULES_AGREEMENT_REQUIRED,
    }),
  });

  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",
    defaultValues: {
      firstName: profileData?.firstName ?? "",
      lastName: profileData?.lastName ?? "",
      email: profileData?.email ?? "",
      phoneNumber: profileData?.mobileNumber ?? "",
      estimatedTimeOfArrival: ARRIVAL_TIME_OPTIONS[0],
      nationality: profileData?.countryData ?? null,
    },
  });

  /**
   * 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;

  const { showDraftedModal, afterDraftedNavigation, isBookingFlow } =
    useSelector((state: RootState) => state.common);

  useEffect(() => {
    if (viewBookingData?.data?.propertyId) {
      dispatch(
        getViewPropertyAvailability({
          propertyId: viewBookingData?.data?.propertyId,
          bookingId: bookingId,
          propertySpaceIds: propertySpaceIds,
        })
      );
    }
  }, [viewBookingData?.data?.propertyId]);

  useEffect(() => {
    if (profileData) {
      setValue("firstName", profileData?.firstName ?? "");
      setValue("lastName", profileData?.lastName ?? "");
      setValue("email", profileData?.email ?? "");
      setValue("phoneNumber", profileData?.mobileNumber ?? "");
      setValue(
        "dateOfBirth",
        profileData?.dateOfBirth
          ? new Date(profileData?.dateOfBirth)
          : undefined
      );
      setValue("nationality", profileData?.countryData ?? null);
    }
  }, [profileData, countryList]);

  /**
   * Handles the booking confirmation process by constructing a booking payload and dispatching the createBooking thunk.
   * If the booking is successful, navigates to the payment page.
   */
  const handleConfirmBooking = () => {
    const formValues = getValues();

    const payload = {
      bookingId: bookingId,
      propertyId: viewBookingData?.data?.propertyId,
      isGuestBooking: false,
      checkInDate: bookingSummary?.data?.summary?.checkInDate,
      checkOutDate: bookingSummary?.data?.summary?.checkOutDate,
      numberOfGuest: bookingSummary?.data?.summary?.numberOfGuest,
      skipPayment: true,
      confirmBooking: false,
      guestDetails: {
        firstName: formValues.firstName,
        lastName: formValues.lastName,
        email: formValues.email,
        phoneNumber: formValues.phoneNumber,
        dateOfBirth: formatDateYYYYMMDD(formValues.dateOfBirth),
        nationality: formValues.nationality.name,
        estimatedTimeOfArrival: formValues.estimatedTimeOfArrival.value,
        countryId: formValues.nationality.countryId,
      },
      agreedToHouseRules: formValues.agreedToHouseRules,
      infoForHost: {
        specialRequest: formValues.message,
      },
      propertySpaceIds: propertySpaceIds,
    };
    dispatch(
      createBooking(payload, () => {
        router.push(`${Routes.PAYMENT(slug, bookingId)}`);
      })
    );
  };

  /**
   * Handles form submission by triggering the booking confirmation process.
   * @param data - The form data submitted by the user.
   */
  const onSubmit = () => {
    handleConfirmBooking();
  };

  /**
   * Handle click
   * Dispatches actions to:
   * - Set the current LRF flow
   * - Open the LRF modal
   * @param item - The selected item as a string
   */
  const handleClick = (item: string) => {
    dispatch(commonActions.setLRFFlow(item));
    dispatch(commonActions.setLRFModalOpen(true));
    dispatch(commonActions.setLRFData(getValues())); // Store the form data in the Redux store using getValues()
  };

  /**
   * Dispatches the action to get the master country list
   */
  useEffect(() => {
    if (bookingId) {
      dispatch(
        getViewBooking({ bookingId: bookingId }, (res) => {
          if (!res?.meta?.status) {
            Toast("error", res?.meta?.message);
            router.push(`${Routes.FIND_A_HOME_INFO(slug)}`);
          }
        })
      );
    }
  }, [bookingId]);

  useEffect(() => {
    dispatch(getMasterCountryList({ perPage: -1 }));
  }, []);

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

    if (viewBookingData?.data?.propertyId) {
      const newPayload = {
        numberOfGuest: guests,
        ...rest,
        propertySpaceIds: propertySpaceIds,
        bookingId: bookingId,
      };

      if (
        JSON.stringify(newPayload) !== JSON.stringify(bookingSummaryPayload)
      ) {
        setBookingSummaryPayload(newPayload);
        dispatch(getBookingSummary(newPayload));
      }
    }
  };

  useEffect(() => {
    if (propertySpaceIds) {
      if (viewBookingData?.data?.isColivingBooking) {
        getApiPayload(bookingSummaryPayload);
      }
    }
  }, [propertySpaceIds, bookingSummaryPayload]);

  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]`}>
            <div
              className={`flex flex-col gap-[20px] xl:gap-[24px] w-full lg:w-[60%]`}
            >
              {profileData ? (
                <>
                  <div className="bg-white rounded-[12px] p-[16px] lg:p-[20px] w-full">
                    <h2 className={`h6 !mb-2 !font-fw600`}>
                      {BOOKING?.WELCOME}, {profileData?.firstName}{" "}
                      {profileData?.lastName}
                    </h2>
                    <p className={`text-grey667Color`}>
                      {BOOKING?.WELCOME_DESCRIPTION}
                    </p>
                  </div>
                  {isClient && isMobile && (
                    <div className="booking-summary">
                      <BookingSummary
                        IsReview
                        onSubmit={onSubmit}
                        userType={"guest"}
                        viewPropertyAvailabilityData={
                          viewPropertyAvailability?.data
                        }
                        viewBookingData={viewBookingData?.data}
                        bookingSummaryData={bookingSummary?.data}
                        isbookingSummaryLoading={false}
                        isCreateBookingLoading={false}
                        getApiPayload={getApiPayload}
                        isLoggedIn={profileData ? true : false}
                      />
                    </div>
                  )}
                </>
              ) : (
                <>
                  <div
                    className={`lg:bg-white lg:rounded-[12px] lg:p-[20px] w-full grid grid-cols-2 gap-2.5 lg:gap-[20px]`}
                  >
                    <button
                      type="button"
                      className={`w-full py-3 px-4 SecondaryBorderedBtn !bg-transparent hover:!bg-secondaryColor`}
                      onClick={() => handleClick("login")}
                    >
                      {BOOKING?.LOGIN}
                    </button>
                    <button
                      type="button"
                      className={`w-full py-3 px-4 PrimaryBtn`}
                      onClick={() => handleClick("create")}
                    >
                      {BOOKING?.REGISTER}
                    </button>
                  </div>
                  {isClient && isMobile && (
                    <div className="booking-summary">
                      <BookingSummary
                        IsReview
                        onSubmit={onSubmit}
                        userType={"guest"}
                        viewPropertyAvailabilityData={
                          viewPropertyAvailability?.data
                        }
                        viewBookingData={viewBookingData?.data}
                        bookingSummaryData={bookingSummary?.data}
                        isbookingSummaryLoading={false}
                        isCreateBookingLoading={false}
                        getApiPayload={getApiPayload}
                        isLoggedIn={profileData ? true : false}
                      />
                    </div>
                  )}
                </>
              )}
              {/* About you wrap */}
              <div className="about-you-section">
                <AboutYouSection
                  register={register}
                  errors={errors}
                  setValue={setValue}
                  Controller={Controller}
                  control={control}
                  countryList={countryList?.data}
                  viewBookingData={viewBookingData?.data}
                />
              </div>
              {/* Mobile Button Paynow */}
              {isClient && isMobile && (
                <div
                  className={`flex flex-col gap-2.5 pt-4 border-t border-[#E4E7EC]`}
                >
                  <button
                    disabled={!profileData}
                    className={`SecondaryBtn w-full ${
                      !profileData ? "opacity-50 !cursor-not-allowed" : ""
                    }`}
                    type="submit"
                  >
                    {profileData
                      ? BOOKING?.ADD_PAYMENT_DETAILS
                      : BOOKING?.LOGIN_TO_CONTINUE}
                  </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, (res) => {
                          dispatch(commonActions.isBookingFlow(false));
                          dispatch(commonActions.afterDraftedNavigation(null));
                          if (afterDraftedNavigation) {
                            setTimeout(() => {
                              router.replace(afterDraftedNavigation);
                            }, 100);
                          }
                          if (
                            res?.meta?.status === 0 ||
                            !afterDraftedNavigation
                          ) {
                            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>
            {/* Summary */}
            {isClient && !isMobile && (
              <div
                className={`w-full lg:w-[40%] h-max lg:sticky lg:top-[85px] xxl:top-[110px] booking-summary`}
              >
                <BookingSummary
                  IsReview
                  onSubmit={onSubmit}
                  userType={"guest"}
                  viewPropertyAvailabilityData={viewPropertyAvailability?.data}
                  viewBookingData={viewBookingData?.data}
                  bookingSummaryData={bookingSummary?.data}
                  isbookingSummaryLoading={false}
                  isCreateBookingLoading={false}
                  getApiPayload={getApiPayload}
                  isLoggedIn={profileData ? true : false}
                />
              </div>
            )}
          </div>
        </form>
      </FormProvider>
    </>
  );
};

export default Booking;
