export default function usetFacility() {
  const { getCapitalized, standardFormatDate } = useUtils();

  class MFacility implements TFacility {
    _id?: string;
    name: string;
    site: string;
    featuredImage: { _id: string; name: string } | null | any;
    gallery: { _id: string; name: string; url: string }[];
    monday: {
      isEnabled: boolean;
      startTime: string;
      endTime: string;
      breakTimes: { startTime: string; endTime: string }[];
      peakTimes: { startTime: string; endTime: string }[];
      timeSlotsManual: { startTime: string; endTime: string }[] | null;
    };
    tuesday: {
      isEnabled: boolean;
      startTime: string;
      endTime: string;
      breakTimes: { startTime: string; endTime: string }[];
      peakTimes: { startTime: string; endTime: string }[];
      timeSlotsManual: { startTime: string; endTime: string }[] | null;
    };
    wednesday: {
      isEnabled: boolean;
      startTime: string;
      endTime: string;
      breakTimes: { startTime: string; endTime: string }[];
      peakTimes: { startTime: string; endTime: string }[];
      timeSlotsManual: { startTime: string; endTime: string }[] | null;
    };
    thursday: {
      isEnabled: boolean;
      startTime: string;
      endTime: string;
      breakTimes: { startTime: string; endTime: string }[];
      peakTimes: { startTime: string; endTime: string }[];
      timeSlotsManual: { startTime: string; endTime: string }[] | null;
    };
    friday: {
      isEnabled: boolean;
      startTime: string;
      endTime: string;
      breakTimes: { startTime: string; endTime: string }[];
      peakTimes: { startTime: string; endTime: string }[];
      timeSlotsManual: { startTime: string; endTime: string }[] | null;
    };
    saturday: {
      isEnabled: boolean;
      startTime: string;
      endTime: string;
      breakTimes: { startTime: string; endTime: string }[];
      peakTimes: { startTime: string; endTime: string }[];
      timeSlotsManual: { startTime: string; endTime: string }[] | null;
    };
    sunday: {
      isEnabled: boolean;
      startTime: string;
      endTime: string;
      breakTimes: { startTime: string; endTime: string }[];
      peakTimes: { startTime: string; endTime: string }[];
      timeSlotsManual: { startTime: string; endTime: string }[] | null;
    };
    description: string;
    about: string;
    maintenanceDatesWithTimes: Record<string, any>[];
    maintenanceWeekly: string[];
    maintenanceMonthly: string[];
    createdAt?: Date;
    updatedAt?: Date;
    status?: string;
    rulesAndPolicies?: string;
    icon?: string;
    hourInterval?: number;
    isBookingFeeEnabled: boolean;
    isGuestEnabled: boolean;
    bookingAmount: number | null;
    peakBookingFeeAmount?: number | null;
    bookingFeeGuestAmount?: number | null;
    peakBookingFeeGuestAmount?: number | null;
    bookingFeeRefundPercentage?: number | null;
    bookingCurrency: string;
    isDepositEnabled: boolean;
    depositAmount: number | null;
    depositCurrency: string;
    refundFrom: number;
    refundTo: number;
    isCancellationAutoRefundEnabled: boolean;
    isBookingPolicyEnabled: boolean;
    bookingPolicy: string;
    securityCheckList: {
      description: string;
      count: number;
      permanentRemarks: string;
    }[] = [];
    isBookingUnitLimitEnabled: boolean;
    bookingUnitLimit: number | null;
    isMaxNumberGuestLimitEnabled: boolean;
    maxNumberGuestLimit: number | null;
    isCancelAllowedLimitEnabled: boolean;
    daysAllowedCancel: number | null;

    constructor(
      {
        _id = "",
        name = "",
        featuredImage = null,
        site = "",
        gallery = [],
        monday = {
          isEnabled: false,
          startTime: "",
          endTime: "",
          breakTimes: [],
          peakTimes: [],
          timeSlotsManual: null,
        },
        tuesday = {
          isEnabled: false,
          startTime: "",
          endTime: "",
          breakTimes: [],
          peakTimes: [],
          timeSlotsManual: null,
        },
        wednesday = {
          isEnabled: false,
          startTime: "",
          endTime: "",
          breakTimes: [],
          peakTimes: [],
          timeSlotsManual: null,
        },
        thursday = {
          isEnabled: false,
          startTime: "",
          endTime: "",
          breakTimes: [],
          peakTimes: [],
          timeSlotsManual: null,
        },
        friday = {
          isEnabled: false,
          startTime: "",
          endTime: "",
          breakTimes: [],
          peakTimes: [],
          timeSlotsManual: null,
        },
        saturday = {
          isEnabled: false,
          startTime: "",
          endTime: "",
          breakTimes: [],
          peakTimes: [],
          timeSlotsManual: null,
        },
        sunday = {
          isEnabled: false,
          startTime: "",
          endTime: "",
          breakTimes: [],
          peakTimes: [],
          timeSlotsManual: null,
        },
        description = "",
        about = "",
        maintenanceDatesWithTimes = [],
        maintenanceWeekly = [],
        maintenanceMonthly = [],
        status = "",
        rulesAndPolicies = "",
        icon = "",
        hourInterval = 1,
        isBookingFeeEnabled = false,
        isGuestEnabled = false,
        bookingAmount = 0,
        peakBookingFeeAmount = 0,
        bookingFeeGuestAmount = 0,
        peakBookingFeeGuestAmount = 0,
        bookingFeeRefundPercentage = 0,
        bookingCurrency = "SGD",
        isDepositEnabled = false,
        depositAmount = 0,
        depositCurrency = "SGD",
        refundFrom = 0,
        refundTo = 0,
        isCancellationAutoRefundEnabled = false,
        isBookingPolicyEnabled = false,
        bookingPolicy = "",
        securityCheckList = [],
        isBookingUnitLimitEnabled = false,
        bookingUnitLimit = null,
        isMaxNumberGuestLimitEnabled = false,
        maxNumberGuestLimit = null,
        isCancelAllowedLimitEnabled = false,
        daysAllowedCancel = null,
      } = {} as TFacility
    ) {
      this._id = _id;
      this.name = name;
      this.site = site;
      this.featuredImage = featuredImage;
      this.gallery = gallery;
      this.monday = monday;
      this.monday.breakTimes = monday?.breakTimes ?? [];
      this.monday.peakTimes = monday?.peakTimes ?? [];
      this.monday.timeSlotsManual = monday?.timeSlotsManual ?? [];
      this.tuesday = tuesday;
      this.tuesday.breakTimes = tuesday?.breakTimes ?? [];
      this.tuesday.peakTimes = tuesday?.peakTimes ?? [];
      this.wednesday = wednesday;
      this.wednesday.breakTimes = wednesday?.breakTimes ?? [];
      this.wednesday.peakTimes = wednesday?.peakTimes ?? [];
      this.wednesday.timeSlotsManual = wednesday?.timeSlotsManual ?? null;
      this.thursday = thursday;
      this.thursday.breakTimes = thursday?.breakTimes ?? [];
      this.thursday.peakTimes = thursday?.peakTimes ?? [];
      this.thursday.timeSlotsManual = thursday?.timeSlotsManual ?? null;
      this.friday = friday;
      this.friday.breakTimes = friday?.breakTimes ?? [];
      this.friday.peakTimes = friday?.peakTimes ?? [];
      this.friday.timeSlotsManual = friday?.timeSlotsManual ?? null;
      this.saturday = saturday;
      this.saturday.breakTimes = saturday?.breakTimes ?? [];
      this.saturday.peakTimes = saturday?.peakTimes ?? [];
      this.saturday.timeSlotsManual = saturday?.timeSlotsManual ?? null;
      this.sunday = sunday;
      this.sunday.breakTimes = sunday?.breakTimes ?? [];
      this.sunday.peakTimes = sunday?.peakTimes ?? [];
      this.sunday.timeSlotsManual = sunday?.timeSlotsManual ?? null;
      this.description = description;
      this.about = about;
      this.maintenanceDatesWithTimes = maintenanceDatesWithTimes ?? [];
      this.maintenanceWeekly = maintenanceWeekly;
      this.maintenanceMonthly = maintenanceMonthly;
      this.status = status;
      this.rulesAndPolicies = rulesAndPolicies;
      this.icon = icon;
      this.hourInterval = hourInterval;
      this.isBookingFeeEnabled = isBookingFeeEnabled;
      this.isGuestEnabled = isGuestEnabled;
      this.bookingAmount = bookingAmount;
      this.peakBookingFeeAmount = peakBookingFeeAmount;
      this.bookingFeeGuestAmount = bookingFeeGuestAmount;
      this.peakBookingFeeGuestAmount = peakBookingFeeGuestAmount;
      this.bookingFeeRefundPercentage = bookingFeeRefundPercentage;
      this.bookingCurrency = bookingCurrency;
      this.isDepositEnabled = isDepositEnabled;
      this.depositAmount = depositAmount;
      this.depositCurrency = depositCurrency;
      this.refundFrom = refundFrom;
      this.refundTo = refundTo;
      this.isCancellationAutoRefundEnabled = isCancellationAutoRefundEnabled;
      this.bookingPolicy = bookingPolicy;
      this.securityCheckList = securityCheckList ?? [];
      this.isBookingUnitLimitEnabled = isBookingUnitLimitEnabled || false;
      this.bookingUnitLimit = bookingUnitLimit ?? null;
      this.isMaxNumberGuestLimitEnabled = isMaxNumberGuestLimitEnabled || false;
      this.maxNumberGuestLimit = maxNumberGuestLimit ?? null;
      this.isCancelAllowedLimitEnabled = isCancelAllowedLimitEnabled || false;
      this.daysAllowedCancel = daysAllowedCancel ?? null;
      this.isBookingPolicyEnabled = isBookingPolicyEnabled || false;
    }
  }

  const facility = useState("facility", () => new MFacility());
  const facilities = useState("facilities", (): TFacility[] => []);
  const page = useState("facilityPage", () => 1);
  const pages = useState("facilityPages", () => 0);
  const itemsPerPage = useState("itemsPerPage", () => 10);
  const search = useState("facilitySearch", () => "");
  const selectedFilter = useState("facilitySelectedFilter", () => "all");
  const pageRange = useState("facilityPageRange", () => "-- - -- of --");
  const isLoadingFacilities = useState("isLoadingFacilities", () => false);
  const isFacilityBookingsLoaded = useState(
    "isFacilityBookingsLoaded",
    () => false
  );

  const canNextPage = computed(() => pages.value > page.value);
  const canPrevPage = computed(() => page.value <= 1);

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

  const affectedBookingsTab = useState("affectedBookingsTab", () => "approved");

  const bookingFeeTaxPercentage = useState(
    "bookingFeeTaxPercentage",
    () => null
  );
  const bookingCurrencySymbol = useState("bookingCurrencySymbol", () => "");
  const bookingCurrencyType = useState("bookingCurrencyType", () => "");

  async function setFacilities(
    { sites, limit, userType } = {} as {
      sites?: string[];
      limit?: number;
      userType?: string;
    }
  ) {
    try {
      isLoadingFacilities.value = true;
      const _facilities = getFacilitiesByPageSearch({
        page: page.value,
        search: search.value,
        sites,
        limit,
        userType,
      }) as any;

      facilities.value = _facilities.items as TFacility[];
      pageRange.value = _facilities.pageRange;
      pages.value = _facilities.pages;
      isLoadingFacilities.value = false;
    } catch (error) {
      facilities.value = [];
      pageRange.value = "-- - -- of --";
      pages.value = 0;
      isLoadingFacilities.value = false;
    }
  }

  async function getFacilitiesByPageSearch({
    page = 1,
    search = "",
    limit = 10,
    sites = [],
    _id = "",
    userType,
  }: {
    _id?: string;
    page?: number;
    search?: string;
    sites?: string[];
    limit?: number;
    userType?: string;
  }) {
    return useNuxtApp().$api("/api/facilities/search/v1", {
      method: "POST",
      body: {
        page,
        search,
        limit,
        sites,
        _id,
        userType,
      },
    });
  }

  async function updateMaintenance({
    _id = "invalid",
    site = "invalid",
    maintenanceDatesWithTimes = [],
    maintenanceWeekly = [],
    maintenanceMonthly = [],
    userType,
    updatedBy,
  }: {
    _id: string;
    site: string;
    maintenanceDatesWithTimes: Record<string, any>[] | null;
    maintenanceWeekly?: String[] | null;
    maintenanceMonthly?: String[] | null;
    userType?: string;
    updatedBy?: string;
  }) {
    return useNuxtApp().$api("/api/facilities/maintenance/v1", {
      method: "POST",
      body: {
        _id,
        site,
        maintenanceDatesWithTimes,
        maintenanceWeekly,
        maintenanceMonthly,
        userType,
        updatedBy,
      },
    });
  }

  async function getAffectedBookings({
    page = 1,
    limit = 10,
    facility = "",
    site = "",
    maintenanceDatesWithTimes = [],
    maintenanceWeekly = [],
    maintenanceMonthly = [],
    status = "",
    userType,
    updatedBy,
  }: {
    page?: number;
    limit?: number;
    facility: string;
    site: string;
    maintenanceDatesWithTimes: Record<string, any>[] | null;
    maintenanceWeekly?: String[];
    maintenanceMonthly?: String[];
    status?: string;
    userType?: string;
    updatedBy?: string;
  }) {
    return useNuxtApp().$api(
      "/api/facilities-booking/maintenance-affected/v1",
      {
        method: "POST",
        body: {
          page,
          limit,
          facility,
          site,
          maintenanceDatesWithTimes,
          maintenanceWeekly,
          maintenanceMonthly,
          status,
          userType,
          updatedBy,
        },
      }
    );
  }

  async function addFacility(form: TFacility) {
    return useNuxtApp().$api("/api/facilities/v1", {
      method: "POST",
      body: form,
    });
  }

  async function deleteFacility({
    _id,
    site,
    updatedBy,
  }: {
    _id?: string;
    site?: string;
    updatedBy?: string;
  }) {
    return useNuxtApp().$api(`/api/facilities/v1?_id=${_id}&site=${site}`, {
      method: "PATCH",
      query: {
        updatedBy,
      },
    });
  }

  function setFacility(data?: TFacility) {
    facility.value = new MFacility(data);
  }

  async function onExportPdf(url: string) {
    const res = await useNuxtApp().$api<Blob | MediaSource>(
      `/api/facilities/v1/pdf`,
      {
        method: "GET",
        query: {
          url: url,
          title: `FACILITY BOOKINGS - ${selectedFilter.value} - FROM ${filters.value.from} TO ${filters.value.to}`,
          orientation: "P", // (L|Landscape|P|Portrait)
        },
      }
    );
    const downloadUrl = window.URL.createObjectURL(res);
    const a = document.createElement("a");
    a.href = downloadUrl;
    a.download = `FACILITY BOOKINGS - ${getCapitalized(
      selectedFilter.value
    )} - FROM ${filters.value.from} TO ${filters.value.to}.pdf`; // Specify the file name
    document.body.appendChild(a);
    a.click(); // Trigger the download
    window.URL.revokeObjectURL(downloadUrl); // Clean up
  }

  async function editFacilityById(facility: any) {
    // delete facility.updatedBy;
    facility.bookingCurrency = "SGD";
    facility.depositCurrency = "SGD";

    const payload = JSON.parse(JSON.stringify(facility));

    return useNuxtApp().$api(`/api/facilities/v1`, {
      method: "PUT",
      body: payload,
    });
  }

  async function saveFacilitySettings(data: any) {
    return useNuxtApp().$api("/api/facilities-settings/v1", {
      method: "POST",
      body: JSON.stringify(data),
    });
  }

  async function getFacilitiesSetting({
    site,
    fieldsType,
  }: {
    site: string;
    fieldsType?: string | null;
  }) {
    return useNuxtApp().$api("/api/facilities-settings/v1", {
      method: "PATCH",
      body: {
        site,
        fieldsType,
      },
    });
  }

  function nextPage(
    { sites } = {} as {
      sites?: string[];
    }
  ) {
    page.value++;
    setFacilities({
      sites,
    });
  }

  function prevPage(
    { sites } = {} as {
      sites?: string[];
    }
  ) {
    page.value--;
    setFacilities({
      sites,
    });
  }

  async function getAffectedBookedSlot({
    page = 1,
    limit = 1,
    facility,
    timeSlots,
    date,
    site,
    status,
  }: {
    page: number;
    limit: number;
    facility: string;
    user: string;
    site: string;
    timeSlots?: any;
    date?: any;
    pax: number;
    status?: string;
  }) {
    return useNuxtApp().$api("/api/facilities-booking/search/v1", {
      method: "POST",
      body: {
        page,
        limit,
        facility,
        timeSlots,
        date,
        site,
        status,
      },
    });
  }

  async function cancelFacilityBooking({
    _ids,
    facility,
    site,
    remarks,
  }: {
    _ids?: string[];
    facility: string;
    site: string;
    remarks: string;
  }) {
    return useNuxtApp().$api("/api/facilities-booking/cancel-booking/v1", {
      method: "POST",
      body: { _ids, facility, site, remarks },
    });
  }

  async function getFacilitiesIDPublic({ _id = "" }: { _id?: string }) {
    return useNuxtApp().$api("/api/facilities/get-by-id/v1", {
      method: "POST",
      body: {
        _id,
      },
    });
  }

  async function createBooking({
    facility,
    timeSlots,
    user,
    date,
    pax,
    site,
    invites,
    bookingPayment,
    bookingAmount,
    depositAmount,
    company,
    fullName,
    email,
    phoneNumber,
    bookingPolicy,
    memberId,
    notes,
  }: {
    facility: string;
    timeSlots: { _id: string; slot: string }[];
    user: string;
    site: string;
    date: any;
    pax: number;
    invites: any;
    bookingPayment?: any;
    bookingAmount?: number;
    depositAmount?: number;
    company?: string;
    fullName?: string;
    email?: string;
    phoneNumber?: string;
    bookingPolicy?: string;
    memberId?: string;
    notes?: string;
  }) {
    const data: any = {
      facility,
      timeSlots,
      user,
      date,
      pax,
      site,
      company,
      fullName,
      email,
      phoneNumber,
      invites,
      bookingPolicy,
      memberId,
      notes,
    };
    if (bookingPayment) data.bookingPayment = bookingPayment;
    if (bookingAmount) data.bookingAmount = bookingAmount;
    if (depositAmount) data.depositAmount = depositAmount;
    return useNuxtApp().$api(`/api/facilities-booking/v1`, {
      method: "POST",
      body: JSON.stringify(data),
    });
  }

  return {
    page,
    pages,
    itemsPerPage,
    search,
    selectedFilter,
    pageRange,
    isLoadingFacilities,
    isFacilityBookingsLoaded,
    filters,
    facilities,
    facility,
    addFacility,
    setFacility,
    onExportPdf,
    setFacilities,
    getFacilitiesByPageSearch,
    updateMaintenance,
    getAffectedBookings,
    editFacilityById,
    saveFacilitySettings,
    getFacilitiesSetting,
    nextPage,
    prevPage,
    canNextPage,
    canPrevPage,
    getAffectedBookedSlot,
    affectedBookingsTab,
    cancelFacilityBooking,
    deleteFacility,
    bookingFeeTaxPercentage,
    bookingCurrencySymbol,
    bookingCurrencyType,
    getFacilitiesIDPublic,
    createBooking,
  };
}
