export default function useFacilityBookings() {
  const { standardFormatDate } = useUtils();

  class MFacilityBooking implements TFacilityBooking {
    _id?: string;
    facility: string;
    site: string;
    timeSlots: string[];
    user: string;
    date: string;
    pax: number;
    status?: any;
    facilityName?: string;
    memberId?: string;
    fullName?: string;
    userGivenName?: string;
    userSurname?: string;
    userBlockName?: string;
    userLevelName?: string;
    userUnitName?: string;
    company?: string;
    email?: string;
    phoneNumber?: string;
    createdAt?: any;
    bookedFrom?: string;
    cancelledAt?: any;
    rejectedAt?: any;
    slotName?: string;
    bookingAmount?: number;
    depositAmount?: number;
    bookingPayment?: any;
    bookingCurrency?: any;
    beforeCheckList?: any[];
    beforeHandOver?: any;
    afterCheckList?: any[];
    afterTakeOver?: any;
    review?: any;
    remarks?: string;
    topUpPayment?: number | string;
    bookingFeeRefundPercentage?: number | string;
    refundTransaction?: Record<string, any>;
    refundTransactionCancelled?: Record<string, any>;
    refundTransactionRejected?: Record<string, any>;
    bookingTaxPercentage?: Record<string, any>;
    createdByType?: string;
    bookingPolicy?: string;

    constructor(
      {
        _id = "",
        facility = "",
        site = "",
        timeSlots = [],
        user = "",
        date = "",
        pax = 0,
        status = "",
        memberId = "",
        facilityName = "",
        fullName = "",
        userGivenName = "",
        userSurname = "",
        userBlockName = "",
        userLevelName = "",
        userUnitName = "",
        company = "",
        email = "",
        phoneNumber = "",
        createdAt = new Date(),
        bookedFrom = "",
        cancelledAt = null,
        rejectedAt = null,
        slotName = "",
        bookingAmount = 0,
        depositAmount = 0,
        bookingPayment = { pmethod: "" },
        bookingCurrency = { symbol: "", code: "", taxType: "" },
        beforeCheckList = [],
        beforeHandOver = {
          defectObservation: "",
          handOverBy: "",
          submittedAt: "",
          securitySignature: "",
          residentSignature: "",
        },
        afterCheckList = [],
        afterTakeOver = {
          defectObservation: "",
          handOverBy: "",
          submittedAt: "",
          securitySignature: "",
          residentSignature: "",
        },
        review = {},
        remarks = "",
        topUpPayment = 0,
        bookingFeeRefundPercentage = 0,
        refundTransaction = {},
        refundTransactionCancelled = {},
        refundTransactionRejected = {},
        bookingTaxPercentage = {},
        createdByType = "",
        bookingPolicy = "",
      } = {} as TFacilityBooking
    ) {
      this._id = _id;
      this.facility = facility;
      this.site = site;
      this.timeSlots = timeSlots;
      this.user = user;
      this.date = date;
      this.pax = pax;
      this.status = status;
      this.memberId = memberId;
      this.facilityName = facilityName;
      this.fullName = fullName;
      this.userGivenName = userGivenName;
      this.userSurname = userSurname;
      this.userBlockName = userBlockName;
      this.userLevelName = userLevelName;
      this.userUnitName = userUnitName;
      this.company = company;
      this.email = email;
      this.phoneNumber = phoneNumber;
      this.createdAt = createdAt;
      this.bookedFrom = bookedFrom;
      this.cancelledAt = cancelledAt;
      this.rejectedAt = rejectedAt;
      this.slotName = slotName;
      this.bookingAmount = bookingAmount;
      this.depositAmount = depositAmount;
      this.bookingPayment = bookingPayment;
      this.bookingCurrency = bookingCurrency;
      this.beforeCheckList = beforeCheckList;
      this.beforeHandOver = beforeHandOver;
      this.afterCheckList = afterCheckList;
      this.afterTakeOver = afterTakeOver;
      this.review = review;
      this.remarks = remarks;
      this.topUpPayment = topUpPayment;
      this.bookingFeeRefundPercentage = bookingFeeRefundPercentage;
      this.refundTransaction = refundTransaction;
      this.refundTransactionCancelled = refundTransactionCancelled;
      this.refundTransactionRejected = refundTransactionRejected;
      this.bookingTaxPercentage = bookingTaxPercentage;
      this.createdByType = createdByType;
      this.bookingPolicy = bookingPolicy;
    }
  }

  const facilityBooking = useState(
    "facilityBooking",
    () => new MFacilityBooking()
  );
  const facilityBookings = useState(
    "facilityBookings",
    (): TFacilityBooking[] => []
  );
  const tab = useState("facilityBookingTab", () => "Approved");
  const page = useState("facilityBookingPage", () => 1);
  const pages = useState("facilityBookingPages", () => 0);
  const itemsPerPage = useState("itemsPerPage", () => 10);
  const search = useState("facilityBookingSearch", (): any => null);
  const bookingPageRange = useState(
    "facilityBookingPageRange",
    () => "-- - -- of --"
  );
  const isLoading = useState("isLoading", () => false);

  const filters = useState("filters", () => ({
    from: standardFormatDate(new Date()),
    to: standardFormatDate(new Date()),
  }));

  async function setFacilityBookings(
    { status, search, site, dataType, limit, date, facility } = {} as {
      status?: string;
      search?: string;
      site?: string;
      dataType?: any;
      limit?: number;
      date?: { start: any; end: any } | null;
      facility?: string | null;
    }
  ) {
    try {
      isLoading.value = true;
      const _facilityBookings = getFacilityBookingsByPageSearch({
        page: page.value,
        status,
        search,
        limit,
        site,
        dataType,
        date,
        facility,
      }) as any;

      facilityBookings.value = _facilityBookings.items as TFacilityBooking[];
      bookingPageRange.value = _facilityBookings.pageRange;
      pages.value = _facilityBookings.pages;
      isLoading.value = false;
    } catch (error) {
      facilityBookings.value = [];
      bookingPageRange.value = "-- - -- of --";
      pages.value = 0;
      isLoading.value = false;
    }
  }

  async function getFacilityBookingsByPageSearch({
    _id,
    page = 1,
    status,
    search,
    limit = 10,
    site,
    dataType,
    date,
    facility,
  }: {
    _id?: string;
    page?: number;
    status?: string;
    search?: string;
    limit?: number;
    site?: string;
    dataType?: string | null;
    date?: { start: any; end: any } | null;
    facility?: string | null;
  }) {
    return useNuxtApp().$api("/api/facilities-booking/search/v1", {
      method: "POST",
      body: {
        _id,
        page,
        status,
        search,
        limit,
        site,
        dataType,
        date,
        facility,
      },
    });
  }

  function setFacilityBooking(data?: TFacilityBooking) {
    facilityBooking.value = data || new MFacilityBooking();
  }

  async function updateStatus({
    _ids = [],
    remarks = "",
    status = "",
    site = "",
    userType,
    updatedBy,
  }: {
    _ids?: string[];
    remarks?: string;
    status?: string;
    site?: string;
    userType?: string;
    updatedBy?: string;
  }) {
    return useNuxtApp().$api("/api/facilities-booking/update-booking/v1", {
      method: "POST",
      body: { _ids, remarks, status, site, userType, updatedBy },
    });
  }

  async function getSimilarBookingSlot({
    page = 1,
    limit = 10,
    _ids = [],
    site,
    updatedBy,
    userType,
  }: {
    page?: number;
    limit?: number;
    _ids: string[];
    site: string;
    updatedBy?: string;
    userType?: string;
  }) {
    return useNuxtApp().$api("/api/facilities-booking/similar-booking/v1", {
      method: "POST",
      body: {
        page,
        limit,
        _ids,
        site,
        updatedBy,
        userType,
      },
    });
  }

  async function generateBookingHistoryPdfOrCsv({
    dataType,
    date = null,
    site = "",
    limit,
  }: {
    limit?: number;
    site?: string;
    dataType?: string | null;
    date?: { start: any; end: any } | null;
  }) {
    return useNuxtApp().$api("/api/facilities-pdf/csv-pdf/v1", {
      method: "POST",
      body: { dataType, date, site, limit },
    });
  }

  async function getBookingVacantSlot({
    facility,
    date,
    site,
    email,
    memberId,
  }: {
    facility?: string;
    site: string;
    date: any;
    email?: string | null;
    memberId?: string | null;
  }) {
    return useNuxtApp().$api(`/api/facilities-booking/vacant-slot/v1`, {
      method: "POST",
      body: {
        facility,
        date,
        site,
        email,
        memberId,
      },
    });
  }

  async function getFacilityBookingsByIdPublic({
    _id,
    site,
    isSoa,
  }: {
    _id?: string;
    site?: string;
    isSoa?: boolean;
  }) {
    return useNuxtApp().$api(`/api/facilities-booking/by-id-public/v1`, {
      method: "POST",
      body: {
        _id,
        site,
        isSoa,
      },
    });
  }
  async function cancelFacilityBookingPublic({
    _ids = [],
    remarks = "",
    facility = "",
    site = "",
    status = "",
  }: {
    _ids?: string[];
    remarks?: string;
    facility?: string;
    site?: string;
    status?: string;
  }) {
    return await useNuxtApp().$api(
      `/api/facilities-booking/update-booking-public/v1`,
      {
        method: "POST",
        body: { _ids, remarks, facility, site, status },
      }
    );
  }

  const canNextBookingPage = computed(() => pages.value > page.value);
  const canPrevBookingPage = computed(() => page.value <= 1);

  function nextBookingPage(
    { status, search, site, dataType, date, facility } = {} as {
      status?: string;
      search?: string;
      site?: string;
      dataType?: string | null;
      date?: { start: any; end: any };
      facility?: string;
    }
  ) {
    page.value++;
    setFacilityBookings({
      status,
      search,
      site,
      dataType,
      date,
      facility,
    });
  }

  function prevBookingPage(
    { status, search, site, dataType, date, facility } = {} as {
      status?: string;
      search?: string;
      site?: string;
      dataType?: string | null;
      date?: { start: any; end: any };
      facility?: string;
    }
  ) {
    page.value--;
    setFacilityBookings({
      status,
      search,
      site,
      dataType,
      date,
      facility,
    });
  }

  return {
    tab,
    page,
    pages,
    itemsPerPage,
    search,
    bookingPageRange,
    isLoading,
    filters,
    facilityBookings,
    facilityBooking,
    setFacilityBooking,
    setFacilityBookings,
    getFacilityBookingsByPageSearch,
    nextBookingPage,
    prevBookingPage,
    canNextBookingPage,
    canPrevBookingPage,
    updateStatus,
    getSimilarBookingSlot,
    generateBookingHistoryPdfOrCsv,
    getBookingVacantSlot,
    getFacilityBookingsByIdPublic,
    cancelFacilityBookingPublic,
  };
}
