<template>
	<div class="sas-calendar">
		<div class="calendar-container px-3">
			<v-progress-circular
				v-if="loading"
				:size="30"
				color="primary"
				indeterminate
				class="center-absolute"
			/>
			<v-row :class="loading ? 'opacity-25' : ''">
				<v-col v-for="(m, mindex) in months" :key="m" cols="12" md="">
					<div :class="{ single: single }" class="calendar-month">
						<v-row class="calendar-nav" no-gutters>
							<v-col
								class="d-flex justify-space-between align-center"
								cols="12"
							>
								<v-btn
									v-if="mindex === 0 && controls"
									:disabled="disableNavPast"
									class="calendar-nav-arrow prev year"
									size="small"
									variant="link"
									@click="prevYear"
								>
									<v-icon
										icon="mdi-chevron-double-left"
									></v-icon>
									<!-- <fa icon="angle-double-left"></fa> -->
								</v-btn>
								<div v-else class="calendar-nav-arrow">
									&nbsp;
								</div>

								<v-btn
									v-if="mindex === 0 && controls"
									:disabled="disableNavPast"
									class="calendar-nav-arrow prev month"
									size="small"
									variant="link"
									@click="prevMonth"
								>
									<v-icon icon="mdi-menu-left"></v-icon>
									<!-- <fa icon="caret-left"></fa> -->
								</v-btn>
								<div v-else class="calendar-nav-arrow">
									&nbsp;
								</div>

								<h4
									class="calendar-month-title flex-grow-1 text-h6 text-capitalize font-weight-bold m-2"
								>
									{{ getMonthYear(mindex) }}
								</h4>

								<v-btn
									v-if="m === months && controls"
									:disabled="disableNavFuture"
									class="calendar-nav-arrow next month"
									size="small"
									variant="link"
									@click="nextMonth"
								>
									<v-icon icon="mdi-menu-right"></v-icon>
									<!-- <fa icon="caret-right"></fa> -->
								</v-btn>
								<div v-else class="calendar-nav-arrow">
									&nbsp;
								</div>

								<v-btn
									v-if="m === months && controls"
									:disabled="disableNavFuture"
									class="calendar-nav-arrow next year"
									size="small"
									variant="link"
									@click="nextYear"
								>
									<v-icon
										icon="mdi-chevron-double-right"
									></v-icon>
									<!-- <fa icon="angle-double-right"></fa> -->
								</v-btn>
								<div v-else class="calendar-nav-arrow">
									&nbsp;
								</div>
							</v-col>
						</v-row>
						<div
							:class="{
								picker: !loading,
								isCheckouting,
								notDetailed: !detailed,
							}"
							class="calendar-month-body"
						>
							<div class="calendar-month-week-header text-center">
								<div
									v-for="(wh, whi) in 7"
									:key="whi"
									class="calendar-month-week-grid calendar-month-week-grid--label"
									width="14%"
								>
									{{ getWeekDayLabel(whi) }}
								</div>
							</div>
							<div class="calendar-month-days">
								<div
									v-for="(g, gi) in 37"
									:key="gi"
									class="calendar-month-week-grid"
								>
									<CalendarDay
										:after-today="
										isAfterToday(
											calcDayPositionGrid(mindex, g),
											mindex,
										)
									"
										:day="
										checkBlocked(
											calcDayPositionGrid(mindex, g),
											mindex,
											gi,
										)
									"
										:detailed="detailed"
										:g="g"
										:gi="gi"
										:is-infinity="infinity"
										:is-selected="
										checkDateSelected(
											calcDayPositionGrid(mindex, g),
											mindex,
										)
									"
										:isRange="
										checkDateRange(
											calcDayPositionGrid(mindex, g),
											mindex,
										)
									"
										:lastDayOfMonth="getLastDayOfMonth(mindex)"
										:mindex="mindex"
										:picker="!loading ? picker : false"
										:positionGrid="
										calcDayPositionGrid(mindex, g)
									"
										:today="
										isToday(
											calcDayPositionGrid(mindex, g),
											mindex,
										)
									"
										@click="selectDay"
										@hover="hoverDay"
									>
									</CalendarDay>
								</div>
							</div>
						</div>
					</div>
				</v-col>
			</v-row>
		</div>
	</div>
	<div v-if="picker">
		<v-alert
			:color="messageType"
			:model-value="showAlert"
			class="w-100"
			style="border-radius: 10px"
			closable
			@click:close="dismissedAlert"
		>
			<span v-html="message"></span>
		</v-alert>
		<v-btn
			:disabled="!innerValue.from"
			block
			class="mt-4"
			color="primary"
			variant="outlined"
			@click="clear"
		>
			clear dates
		</v-btn>
	</div>
</template>

<script>
export default {
	inheritAttrs: false,
	components: {
		CalendarDay: Vue.defineAsyncComponent(() =>
			loadModule(
				window.SAS_URL + "/src/components/calendar/CalendarDay.vue",
				options,
			),
		),
	},
	props: {
		controls: {
			type: Boolean,
			default: false,
		},
		externalControls: {
			type: Boolean,
			default: false,
		},
		dark: {
			type: Boolean,
			default: false,
		},
		detailed: {
			type: Boolean,
			default: false,
		},
		forceBlockedDates: {
			type: Array,
			default: () => [],
		},
		forceDates: {
			type: Array,
			default: () => [],
		},
		light: {
			type: Boolean,
			default: false,
		},
		infinity: {
			type: Boolean,
			default: false,
		},
		months: {
			type: Number,
			default: 2,
		},
		noBlocks: {
			type: Boolean,
			default: false,
		},
		noPeriodCheck: {
			type: Boolean,
			default: false,
		},
		noValidation: {
			type: Boolean,
			default: false,
		},
		picker: {
			type: Boolean,
			default: false,
		},
		property: {
			type: Object,
			default: () => ({}),
		},
		showSummary: {
			type: Boolean,
			default: false,
		},
		forceSeasons: {
			type: Array,
			default: () => [],
		},
		actionPicker: {
			type: String,
			default: 'from',
		},
		modelValue: {
			type: Object,
			default: () => ({}),
		},
		dateParams: {
			type: Object,
			default: () => ({}),
		},
		single: {
			type: Boolean,
			default: false,
		},
		noCheckPeriod: {
			type: Boolean,
			default: false,
		},
	},
	emits: [
		'select:to',
		'select:from',
		'next:year',
		'update:modelValue',
		'update:stateLoading',
		'prevNextMonth',
		'invalid',
		'action',
	],
	data() {
		return {
			// year: $moment().format('YYYY'),
			// month: $moment().format('MM'),
			disableNavPast: true,
			disableNavFuture: false,
			innerValue: {
				from: '',
				to: '',
			},
			currentAction: '',
			hoverTo: null,

			minimumStay: 1,
			validPeriod: {},
			stateSeasons: useCalendarStore().seasonsPropertyMonth ?? {},

			message: '',
			messageType: 'alert-error',
			dismissCountDown: 10,
			stateMonth: $moment().format('MM'),
			stateYear: $moment().format('YYYY'),
			stateLoading: false,
		}
	},
	computed: {
		// ...mapGetters({
		// 	stateMonth: 'calendar/month',
		// 	stateYear: 'calendar/year',
		// 	stateLoading: 'calendar/loading'
		// }),
		showAlert() {
			return !!this.message
		},
		month: {
			get() {
				return this.stateMonth
			},
			set(value) {
				return this.setMonth(value)
			},
		},
		year: {
			get() {
				return this.stateYear
			},
			set(value) {
				return this.setYear(value)
			},
		},
		loading: {
			get() {
				return this.stateLoading
			},
			set(value) {
				return this.setLoading(value)
			},
		},
		blockedDates() {
			if (this.noValidation) return []
			return this.currentProperty?.properties?.blocked_dates || []
		},
		bookings() {
			if (this.noValidation) return []
			return this.currentProperty.property_booking_reservations || []
		},
		currentProperty() {
			if (this.noValidation) return {}
			return this.property
		},
		maxDaysAllowed() {
			if (this.noValidation || this.noBlocks) return null
			return this.currentProperty?.properties?.maximum_rental_days_allowed
		},
		vendorBlocking() {
			if (this.noValidation) return []
			const blocked_dates = [
				...(this.currentProperty?.property_blocked_dates || []),
			]
			if (this.forceBlockedDates?.length) {
				blocked_dates.push(...this.forceBlockedDates)
			}
			return blocked_dates
		},
		isCheckinMorning() {
			return (
				parseInt(
					this.property.property_configurations?.hour_check_in,
				) <= 12
			)
		},
		isCheckoutMorning() {
			return (
				parseInt(
					this.property.property_configurations?.hour_check_out,
				) <= 12
			)
		},
		isCheckouting() {
			// return !!this.innerValue.from && !this.innerValue.to
			return this.currentAction === 'to'
		},
		propertyHasConnection() {
			return this.property.properties?.connections?.p
		},
		seasons() {
			if (this.noValidation) return []
			return (
				(this.stateSeasons[this.property?.properties?.id] ||
					this.currentProperty?.property_seasons ||
					this.forceSeasons) ??
				[]
			)
		},
	},
	watch: {
		month: {
			handler() {
				this.getSeasonMonth()
			},
			immediate: true,
			deep: true,
		},
		year: {
			handler() {
				this.getSeasonMonth()
			},
			immediate: true,
		},
		actionPicker: {
			handler(value) {
				this.currentAction = value
			},
		},
		currentAction: {
			handler(value) {
				this.$emit('action', value)
			},
		},
		currentProperty: {
			deep: true,
			immediate: true,
			handler(value) {
				if (value && Object.keys(value).length) {
					const checked = this.checkCurrentDates()
					if (!checked.valid) {
						this.$emit('invalid', checked)
					}
				}
			},
		},
		innerValue: {
			deep: true,
			handler(value) {
				this.$emit('update:modelValue', value)
			},
		},
		modelValue: {
			deep: true,
			immediate: true,
			handler(value) {
				this.innerValue = value
			},
		},
		dateParams: {
			deep: true,
			handler(value) {
				if (value.from !== undefined && value.to !== undefined) {
					this.innerValue.from = $moment(value.from).format(
						'YYYY-MM-DD',
					)
					this.innerValue.to = $moment(value.to).format(
						'YYYY-MM-DD',
					)
				}
			},
		},
	},
	beforeMount() {
		if (this.months === 12) this.setMonth(1)
	},
	mounted() {
		if (this.innerValue.from) {
			const currentDate = $moment(this.innerValue.from, 'YYYY-MM-DD')
			this.month = currentDate.format('MM')
			this.year = currentDate.format('YYYY')
		}

		this.testPastNav()
		this.testFutureNav()
		window.currentSeasonOfDate = this.currentSeasonOfDate;
	},
	methods: {
		// ...mapMutations({
		// 	setMonth: 'calendar/set_month',
		// 	setYear: 'calendar/set_year',
		// 	setLoading: 'calendar/set_loading',
		// }),
		getSeasonMonth() {
			const month = $moment(`${this.month}/${this.year}`, 'MM/YYYY')
			if (
				this.picker &&
				!this.noValidation &&
				!this.loading &&
				!Array.isArray(this.seasons) &&
				this.propertyHasConnection
			) {
				const promises = []
				if (!this.seasons[month.format('MM/YYYY')]) {
					promises.push(
						useCalendarStore().getSeasonsByPropertyByMonth({
							id: this.property?.properties?.id,
							start_date_from: month
								.startOf('month')
								.format('YYYY-MM-DD'),
							start_date_end: month
								.endOf('month')
								.format('YYYY-MM-DD'),
						}),
					)
				}
				const nextMonth = month.add(1, 'month')
				if (!this.seasons[nextMonth.format('MM/YYYY')]) {
					promises.push(
						useCalendarStore().getSeasonsByPropertyByMonth({
							id: this.property?.properties?.id,
							start_date_from: nextMonth
								.startOf('month')
								.format('YYYY-MM-DD'),
							start_date_end: nextMonth
								.endOf('month')
								.format('YYYY-MM-DD'),
						}),
					)
				}
				if (promises.length) {
					this.loading = true
					Promise.all(promises).finally(() => {
						this.loading = false
					})
				}
			}
		},
		currentSeasonOfDate(date_moment) {
			if (!this.property || !Object.keys(this.property).length) return {}
			let seasons = this.seasons ?? []
			if (!Array.isArray(seasons)) {
				seasons = this.seasons[date_moment.format('MM/YYYY')] ?? []
			}
			return (
				seasons.find((season) => {
					if (season.start_date && season.published) {
						return date_moment.isBetween(
							season.start_date,
							season.end_date,
							null,
							'[]',
						)
					}
				}) ?? {}
			)
		},
		getYear(qty) {
			return $moment(this.month + '/' + this.year, 'MM/YYYY')
				.add(qty, 'months')
				.format('YYYY')
		},
		getGridWeekDay(g) {
			return g % 7
		},
		getMinimumStayFromDate(date) {
			const default_min_stay = 1
			const seasonsDate = this.currentSeasonOfDate(date)
			if (seasonsDate && seasonsDate.minimum_stay)
				return seasonsDate.minimum_stay

			if (this.property?.property_pricings) {
				return this.property.property_pricings
					? this.property.property_pricings.minimum_stay
					: default_min_stay
			}
			return default_min_stay
		},
		getMinimumStay(date) {
			const seasonsDate = this.currentSeasonOfDate(date)

			if (seasonsDate && Object.keys(seasonsDate).length) {
				this.minimumStay =
					seasonsDate.minimum_stay ||
					this.property.property_pricings.minimum_stay ||
					1
			} else if (this.property?.property_pricings) {
				this.minimumStay =
					this.property.property_pricings.minimum_stay || 1
			}

			return 1
		},
		getPeriodMessage(period, hidePeriod = false) {
			let text = ''
			if (period.dateFrom) {
				text += `The closest valid booking period is ${period.dateFrom.format(
					'Do MMMM YYYY',
				)}`

				if (period.dateTo)
					text += ` to ${period.dateTo.format('Do MMMM YYYY')}`
			} else if (!hidePeriod) {
				text += 'There are no days available for booking'
			}

			return text
		},
		getValidPeriod(selectedDate) {
			if (!selectedDate) return {}

			let findDatePeriod = true
			const validPeriod = {}

			const max_date = $moment().add(this.maxDaysAllowed, 'months')
			const calendarDate = $moment(
				this.month + '/' + this.year,
				'MM/YYYY',
			)
			const currentDate = selectedDate.clone()
			let minimum_stay = 1

			do {
				const endOfMonth = currentDate.clone().endOf('month').date()

				const diff = parseInt(
					currentDate
						.clone(true)
						.startOf('month')
						.diff(calendarDate, 'months'),
				)
				const month = diff > -1 ? diff : 0

				for (
					let day = currentDate.date();
					day < endOfMonth + 1;
					day++
				) {
					const date = currentDate.clone()
					date.set({date: day})
					const dayValues = this.checkBlocked(day, month, date.day())
					// eslint-disable-next-line no-unused-vars
					const isRestrictedCheckin =
						dayValues.isRestricted &&
						!dayValues.isRestrictedCheckInDays

					if (dayValues.isRangeValid) continue

					if (
						dayValues.isBlockedFull ||
						dayValues.isRestrictedCheckin ||
						dayValues.isBookedFull
					)
						continue

					// const seasonsDate = this.currentSeasonOfDate(date)
					// if (seasonsDate && Object.keys(seasonsDate).length) {
					// 	minimum_stay = seasonsDate.minimum_stay || 1
					// } else minimum_stay = 1
					minimum_stay = this.getMinimumStayFromDate(date)

					const minDate = date.clone().add(minimum_stay, 'days')

					let dateToValid
					let isValidRange = true
					let findValidRange = true

					for (
						let dayRange = 1;
						findValidRange && isValidRange;
						dayRange++
					) {
						const dayRangeDate = date.clone().add(dayRange, 'days')
						const dayRangeValues = this.checkBlocked(
							dayRangeDate.date(),
							dayRangeDate.diff(calendarDate, 'months'),
							dayRangeDate.day(),
							{from: date.format('YYYY-MM-DD'), range: true},
						)
						// const isRestrictedRange =
						// 	dayRangeValues.isRestricted &&
						// 	!dayRangeValues.isRestrictedCheckOutDays

						isValidRange =
							!dayRangeValues.isBlockedFull &&
							!dayRangeValues.isBookedFull &&
							!dayRangeValues.isCheckoutUnavailable

						if (
							isValidRange &&
							dayRangeDate.isSameOrAfter(minDate) &&
							!dayRangeValues.isRestricted
						) {
							dateToValid = dayRangeDate
							findValidRange = false
						}
					}

					if (!isValidRange) continue

					validPeriod.dateFrom = date
					validPeriod.dateTo = dateToValid

					findDatePeriod = false
					break
				}

				if (findDatePeriod) {
					currentDate.add(1, 'month').startOf('month')
					const finalDate = currentDate
						.clone()
						.set({date: max_date.date()})
						.endOf('day')
					findDatePeriod = max_date.isAfter(finalDate)
				}
			} while (findDatePeriod)

			this.validPeriod = validPeriod
			return validPeriod
		},
		checkValidDayPeriod(isMorning, dayValues) {
			return !(
				(isMorning &&
					(dayValues.isBlockedAfternoon ||
						dayValues.isBlockedMorning)) ||
				(!isMorning && dayValues.isBlockedAfternoon) ||
				(isMorning &&
					(dayValues.isBookingMorning ||
						dayValues.isBookingAfternoon)) ||
				(!isMorning && dayValues.isBookingAfternoon)
			)
		},
		checkValidPeriod(dates) {
			const from = dates.from
			const to = dates.to
			const current = $moment(
				this.month + '/' + this.year,
				'MM/YYYY',
			)

			let validRange = true
			for (
				let date = from.clone();
				date.isSameOrBefore(to) && validRange;
				date.add(1, 'days')
			) {
				// const isRange =
				// 	date.isAfter(dates.from) && date.isBefore(dates.to)
				const dayValues = this.checkBlocked(
					date.date(),
					date.diff(current, 'months'),
					date.day(),
				)

				if (dayValues.isRangeValid) {
					validRange = true
					continue
				}

				// default validation
				validRange = !(
					dayValues.isBlockedFull ||
					dayValues.isBookedFull ||
					(dayValues.isRestricted &&
						!dayValues.isRestrictedCheckInOutDays)
				)

				if (!validRange) continue

				if (date.isSame(to)) {
					if (this.isCheckoutMorning) continue
					validRange = this.checkValidDayPeriod(
						this.isCheckoutMorning,
						dayValues,
					)
				} else if (date.isSame(from)) {
					validRange =
						this.checkValidDayPeriod(
							this.isCheckinMorning,
							dayValues,
						) && !dayValues.isCheckoutUnavailable
				} else {
					validRange = !(
						dayValues.isBlockedMorning ||
						dayValues.isBlockedAfternoon ||
						dayValues.isBookingMorning ||
						dayValues.isBookingAfternoon
					)
				}
			}

			return validRange
		},
		checkSummaryText(summary) {
			const default_summary = 'Unavailable'
			let exclude_words = ['airbnb', 'vrbo', 'booking.com']

			if (
				exclude_words.filter((el) => summary.toLowerCase().includes(el))
					.length
			)
				return default_summary

			return summary
		},
		checkBlocked(day, m, w, forceDates = {}) {
			let month = $moment(this.month + '/' + this.year, 'MM/YYYY')
				.add(m, 'months')
				.format('MM')
			const dateMoment = $moment(
				this.getYear(m) + '-' + month + '-' + day,
				'YYYY-MM-DD',
			)

			let date = dateMoment.format('YYYY-MM-DD')
			// if (date === '2024-12-16') debugger
			// console.log('DATE', date)
			// eslint-disable-next-line no-unused-vars
			const today = $moment().startOf('day')

			let isBlocked = false
			let isBlockedMorning = false
			let isBlockedAfternoon = false
			let isBlockedFull = false
			let isBlockedFullCtrl = false
			let isBlockedArrival = false
			let isRestricted = false
			let isRestrictedCheckInOutDays = false
			let isRestrictedCheckInDays = false
			let isRestrictedCheckOutDays = false
			let isBooked = false
			let isCheckin = false
			let isCheckout = false
			let isBookingMorning = false
			let isBookingAfternoon = false
			let isBookedFull = false
			let isBookedFullCtrl = false
			let isCleaningMorning = false
			let isCleaningAfternoon = false
			let isCleaning = false
			let isCheckoutUnavailable = false
			let isRangeValid = false
			let summary = ''
			let currentSeason = null
			let options = {}

			if (
				this.isAfterToday &&
				!this.isAfterToday(day, m) &&
				!forceDates.range
			) {
				return {
					isBlocked,
					isBlockedMorning,
					isBlockedAfternoon,
					isBlockedFull,
					isBlockedArrival,
					isRestricted,
					isRestrictedCheckInOutDays,
					isRestrictedCheckInDays,
					isRestrictedCheckOutDays,
					isBooked,
					isCheckin,
					isCheckout,
					isBookingMorning,
					isBookingAfternoon,
					isBookedFull,
					isCleaningMorning,
					isCleaningAfternoon,
					isCleaning,
					isCheckoutUnavailable,
					isRangeValid,
					summary,
				}
			}

			//CHECK INSIDE EACH SEASON TO GET THE CURRENT
			// currentSeason = this.seasons?.filter((season) => {
			// 	if (season.start_date) {
			// 		return $moment(date).isBetween(
			// 			season.start_date,
			// 			season.end_date,
			// 			null,
			// 			'[]',
			// 		)
			// 	}
			// })[0]
			currentSeason = this.currentSeasonOfDate(dateMoment)

			if (this.maxDaysAllowed) {
				const max = $moment()
					.add(this.maxDaysAllowed, 'months')
					.format('YYYY-MM-DD')
				if (
					$moment(date, 'YYYY-MM-DD').isSameOrAfter(
						$moment(max, 'YYYY-MM-DD'),
					)
				) {
					isBlocked = true
					isBlockedFull = true
					if (this.picker) summary = 'Blocked Date'
					else
						summary = `Blocked Date - Max allowed date is ${
							this.maxDaysAllowed
						} month${this.maxDaysAllowed > 1 ? 's' : ''} in advance`
				}
			}

			if (this.blockedDates) {
				let blockedRangeDates = this.blockedDates.filter(function (bd) {
					return typeof bd === 'object' && bd !== null
				})
				let blockedSingleDates = this.blockedDates.filter(
					function (bd) {
						return typeof bd === 'string'
					},
				)

				blockedRangeDates.forEach((range) => {
					const start_date = $moment(range.start_date)
					const end_date = $moment(range.end_date)
					if (
						$moment(date).isBetween(
							start_date,
							end_date,
							null,
							'[]',
						) ||
						$moment(date)
							.startOf('day')
							.isSame(start_date.startOf('day')) ||
						$moment(date)
							.startOf('day')
							.isSame(end_date.startOf('day'))
					) {
						isBlocked = true
						isRestricted = false

						if (this.detailed) {
							summary = range.summary
								? this.checkSummaryText(
									range.summary.split(' - ')[0].trim(),
								)
								: ''
						} else {
							summary = 'Blocked'
						}

						if ($moment(date).isSame(range.start_date)) {
							isBlockedAfternoon = true
						}

						if ($moment(date).isSame(range.end_date)) {
							isBlockedMorning = true
						}

						if (
							(!$moment(date)
									.startOf('day')
									.isSame(start_date.startOf('day')) &&
								!$moment(date)
									.startOf('day')
									.isSame(end_date.startOf('day'))) ||
							($moment(date)
									.startOf('day')
									.isSame(start_date.startOf('day')) &&
								$moment(date)
									.startOf('day')
									.isSame(end_date.startOf('day')))
						) {
							isBlockedFullCtrl = true
						}
					}
				})

				blockedSingleDates.forEach((single) => {
					if (date === single) {
						isBlocked = true

						if (this.detailed) {
							summary = single.summary
								? this.checkSummaryText(
									single.summary.split(' - ')[0].trim(),
								)
								: ''
						} else {
							summary = 'Blocked'
						}

						if ($moment(date).isSame(single.start_date)) {
							isBlockedAfternoon = true
						}

						if ($moment(date).isSame(single.end_date)) {
							isBlockedMorning = true
						}

						if (
							(!$moment(date).isSame(single.start_date) &&
								!$moment(date).isSame(single.end_date)) ||
							($moment(date).isSame(single.start_date) &&
								$moment(date).isSame(single.end_date))
						) {
							isBlockedFullCtrl = true
						}
					}
				})
			}

			if (this.bookings.length > 0) {
				this.bookings
					.filter((b) => b.type == 'booked')
					.map((b) => {
						if (
							$moment(date)
								.startOf('day')
								.isBetween(
									b.booking_checkin_date,
									b.booking_checkout_date,
									'day',
									'[]',
								)
						) {
							isBlocked = false
							isRestricted = false
							isBooked = true
							summary = 'Property Booked'

							if (
								$moment(date).isSame(
									b.booking_checkin_date,
									'day',
								)
							) {
								isCheckin = true
								summary += ' - Check-in'
								isBookingAfternoon = true
							}

							if (
								$moment(date).isSame(
									b.booking_checkout_date,
									'day',
								)
							) {
								isCheckout = true
								summary += ' - Check-out'
								isBookingMorning = true
							}

							if (
								!$moment(date).isSame(
									b.booking_checkout_date,
									'day',
								) &&
								!$moment(date).isSame(
									b.booking_checkin_date,
									'day',
								)
							) {
								isBookedFullCtrl = true
							}
						}
					})

				this.bookings
					.filter((b) => b.type == 'cleaning')
					.map((b) => {
						const start_date = $moment(b.booking_checkin_date)
						const end_date = $moment(b.booking_checkout_date)
						if (
							$moment(date)
								.startOf('day')
								.isBetween(start_date, end_date, 'day', '{]') ||
							$moment(date)
								.startOf('day')
								.isSame(start_date.startOf('day')) ||
							$moment(date)
								.startOf('day')
								.isSame(end_date.startOf('day'))
						) {
							isBlocked = false
							isRestricted = false
							isCleaning = true

							if (this.detailed) {
								if (
									isBooked &&
									isCheckout &&
									isBookingMorning
								) {
									isCleaningAfternoon = true
								}

								if (isBooked && isCleaning) {
									summary += ' - Checkout / Cleaning day'
								} else {
									summary = 'Cleaning Day'
								}
							} else {
								isBooked = true
								summary = 'Property Booked'

								if (
									$moment(date).isSame(start_date, 'day')
								) {
									isCheckin = true
									isBookingAfternoon = true
								}

								if (
									$moment(date).isSame(end_date, 'day')
								) {
									isCheckout = true
									summary += ' - Check-out'
									isBookingMorning = true
								}
							}

							if (
								!$moment(date).isSame(
									b.booking_checkout_date,
									'day',
								) &&
								!$moment(date).isSame(
									b.booking_checkin_date,
									'day',
								)
							) {
								isBookedFullCtrl = true
							}
						}
					})
			}
			if (isBookedFullCtrl) {
				isBookedFull = true
			}

			if (this.property?.properties?.blocked_dates_system) {
				this.property?.properties?.blocked_dates_system?.forEach(
					(range) => {
						// if (date === '2024-08-17') {
						// 	console.log('BLOCKED DATE', range.from, range.to, range, $moment(date).isBetween(
						// 		range.from,
						// 		range.to,
						// 		null,
						// 		'[]'
						// 	))
						// }
						const start_date = $moment(range.from)
						const end_date = $moment(range.to)
						if (
							$moment(date)
								.startOf('day')
								.isBetween(
									start_date.startOf('day'),
									end_date.startOf('day'),
									null,
									'[]',
								) ||
							$moment(date)
								.startOf('day')
								.isSame(start_date.startOf('day')) ||
							$moment(date)
								.startOf('day')
								.isSame(end_date.startOf('day'))
						) {
							isBlocked = true
							isRestricted = false
							summary = 'Blocked'

							if (this.showSummary) {
								if (range.summary) summary = range.summary
								else if (range.block_type)
									summary += ` ${range.block_type}`
							}

							if (
								$moment(date)
									.startOf('day')
									.isSame(start_date.startOf('day'))
							) {
								isBlockedAfternoon = true
							}

							if (
								$moment(date)
									.startOf('day')
									.isSame(end_date.startOf('day'))
							) {
								isBlockedMorning = true
							}

							if (
								!$moment(date)
									.startOf('day')
									.isSame(start_date.startOf('day')) &&
								!$moment(date)
									.startOf('day')
									.isSame(end_date.startOf('day'))
							) {
								isBlockedFullCtrl = true
							}
						}
					},
				)
			}

			this.vendorBlocking.forEach((range) => {
				if (
					$moment(date).isBetween(
						range.from,
						range.to,
						null,
						'[]',
					)
				) {
					isBlocked = true
					isRestricted = false
					summary = 'Blocked'

					if (this.showSummary) {
						if (range.summary) summary = range.summary
						else if (range.block_type)
							summary += ` ${range.block_type}`
					}

					if ($moment(date).isSame(range.from)) {
						isBlockedAfternoon = true
					}

					if ($moment(date).isSame(range.to)) {
						isBlockedMorning = true
					}

					if (
						!$moment(date).isSame(range.from) &&
						!$moment(date).isSame(range.to)
					) {
						isBlockedFullCtrl = true
					}
				}
			})
			if (isBlockedFullCtrl || (isBlockedMorning && isBlockedAfternoon)) {
				isBlockedFull = true
			}

			const hasForceDates = Object.keys(forceDates).length
			if (
				!isBlocked &&
				!isRestricted &&
				!hasForceDates &&
				this.innerValue.from
			) {
				isRestricted = [1, 3].includes(currentSeason?.changeover)
				isRestrictedCheckInOutDays = isRestricted
				isRestrictedCheckOutDays = isRestricted
				if (isRestricted) {
					summary = `Restricted Check-out Day`
				}
			} else if (!isBlocked && !isRestricted && !hasForceDates) {
				isRestricted = [2, 3].includes(currentSeason?.changeover)
				isRestrictedCheckInOutDays = isRestricted
				isRestrictedCheckInDays = isRestricted
				if (isRestricted) {
					summary = `Restricted Check-in Day`
				}
			}

			if (this.property?.property_configurations?.time_before_arrival) {
				const timeBeforeArrival = dateMoment
					.clone()
					.subtract(
						this.property?.property_configurations
							?.time_before_arrival,
						'hours',
					)
				if ($moment().isSameOrAfter(timeBeforeArrival)) {
					isBlockedArrival = true
					isBlocked = true
					isBlockedFull = true
					summary = `Preparation time before arrival is ${this.property?.property_configurations?.time_before_arrival} hours`
				}
				// console.log('TIME BEFORE ARRIVAL', today.isSameOrAfter(timeBeforeArrival), timeBeforeArrival)
			}

			if (!isBlockedFull && !isRestricted && !isBookedFull) {
				if (
					currentSeason?.check_in_days?.length > 0 &&
					currentSeason?.checkin_active_flag &&
					!currentSeason?.check_in_days.includes(
						parseInt(this.getGridWeekDay(w)),
					) &&
					!this.isCheckouting
				) {
					isRestricted = true
					isRestrictedCheckInOutDays = true
					isRestrictedCheckInDays = true
					if (this.detailed) {
						summary = `Season ${currentSeason.name} - Restricted Check-in Day`
					} else if (this.showSummary) {
						summary = `Restricted Check-in Day`
					}
				} else if (
					currentSeason?.check_out_days?.length > 0 &&
					currentSeason?.checkout_active_flag &&
					!currentSeason?.check_out_days.includes(
						parseInt(this.getGridWeekDay(w)),
					) &&
					this.isCheckouting
				) {
					isRestricted = true
					isRestrictedCheckInOutDays = true
					isRestrictedCheckOutDays = true
					if (this.detailed) {
						summary = `Season ${currentSeason.name} - Restricted Check-out Day`
					} else if (this.showSummary)
						summary = `Restricted Check-out Day`
				} else if (
					!this.isCheckouting &&
					!isRestrictedCheckInOutDays &&
					this.property?.property_pricings?.checkin_active_flag &&
					!this.property?.property_pricings?.check_in_days?.includes(
						parseInt(this.getGridWeekDay(w)),
					)
				) {
					isRestricted = true
					isRestrictedCheckInOutDays = true
					isRestrictedCheckInDays = true
					summary = `Restricted Check-in Day`
				} else if (
					this.isCheckouting &&
					!isRestrictedCheckInOutDays &&
					this.property?.property_pricings?.checkout_active_flag &&
					!this.property?.property_pricings?.check_out_days?.includes(
						parseInt(this.getGridWeekDay(w)),
					)
				) {
					isRestricted = true
					isRestrictedCheckInOutDays = true
					isRestrictedCheckOutDays = true
					summary = `Restricted Check-out Day`
				}
			}

			if (
				!this.property?.property_pricings?.checkout_active_flag &&
				!isRestrictedCheckInOutDays &&
				!isBooked &&
				!isBlockedAfternoon &&
				!isRestrictedCheckInOutDays &&
				!this.isCheckouting
			) {
				isRestricted = false
				summary = ''
			}

			if (this.picker && !forceDates.range) {
				const dateFromString = forceDates.from || this.innerValue.from
				const dateFrom = $moment(dateFromString)
				if (dateFromString && dateMoment.isAfter(dateFrom)) {
					let minimum_stay = this.getMinimumStayFromDate(
						$moment(date),
					)

					if (this.propertyHasConnection && this.innerValue.from) {
						const fromSeason = this.currentSeasonOfDate(dateFrom)
						minimum_stay = fromSeason.minimum_stay ?? minimum_stay
					}

					const minDate = $moment(
						$moment(dateFromString, 'YYYY-MM-DD')
							.add(minimum_stay, 'days')
							.toDate(),
					)

					//const fullBooked = isBooked && !isBookingMorning && !isBookingAfternoon
					const fullBooked = isBookedFull
					if (dateMoment.isBefore(minDate) && !fullBooked) {
						isCheckoutUnavailable = true
						summary = `${minimum_stay} night${
							minimum_stay > 1 ? 's' : ''
						} minimum stay`
					}
				} else if (dateFromString === date && !this.innerValue.to) {
					summary = 'Select date to checkout'
				}
			}

			if (this.forceDates.length) {
				const forcedValue = this.forceDates.find(
					(el) => el.date === date,
				)

				if (forcedValue) {
					const isCheckin = !this.isCheckouting
					if (isCheckin && date !== this.innerValue.from) {
						isRestricted = !forcedValue.checkin
					} else if (date !== this.innerValue.from) {
						isRestricted = !forcedValue.checkout
					}

					isRangeValid = !forcedValue.checkin && !forcedValue.checkout
				}
			}

			return {
				isBlocked,
				isBlockedMorning,
				isBlockedAfternoon,
				isBlockedFull,
				isBlockedArrival,
				isRestricted,
				isRestrictedCheckInOutDays,
				isRestrictedCheckInDays,
				isRestrictedCheckOutDays,
				isBooked,
				isCheckin,
				isCheckout,
				isBookingMorning,
				isBookingAfternoon,
				isBookedFull,
				isCleaningMorning,
				isCleaningAfternoon,
				isCleaning,
				isCheckoutUnavailable,
				isRangeValid,
				summary,
				options,
			}
		},
		setMonth(value) {
			this.stateMonth = value
		},
		setYear(value) {
			this.stateYear = value
		},
		setLoading(value) {
			this.$emit('update:stateLoading', value)
		},
		setActionPicker(value) {
			this.currentAction = value
		},
		setMessage(value, type) {
			this.message = value
			this.messageType = type
		},
		checkCurrentDates() {
			if (!this.innerValue.from || !this.innerValue.to) {
				return {valid: true}
			}

			const dates = {
				from: $moment(this.value.from),
				to: $moment(this.value.to),
			}
			const valid = this.checkValidPeriod(dates)

			if (!valid) {
				this.getMinimumStay(dates.from)
				const validPeriod = this.getValidPeriod(dates.from)
				const message = `Date is not available for booking. ${this.getPeriodMessage(
					validPeriod,
				)}`

				return {
					valid,
					validPeriod,
					message,
				}
			}

			return {valid: true}
		},
		dismissedAlert() {
			this.message = ''
			this.dismissCountDown = 10
		},
		formatedMessage(message = '', period = {}, hidePeriod = false) {
			const title = message
			const text = this.getPeriodMessage(period, hidePeriod)

			const newMessage = `<h6 class="alert-heading ${
				text ? 'mb-3' : ''
			}">${title}</h6><p>${text}</p>`

			return newMessage
		},
		checkDateSelected(day, month) {
			const date = $moment(`${this.month}/${this.year}`, 'MM/YYYY')
				.add(month, 'months')
				.add(day - 1, 'days')
				.startOf('day')

			const dateFrom = this.innerValue.from
				? $moment(this.innerValue.from, 'YYYY-MM-DD').startOf(
					'day',
				)
				: null

			const dateTo = this.innerValue.to
				? $moment(this.innerValue.to, 'YYYY-MM-DD').startOf('day')
				: null

			return date.isSame(dateFrom) || date.isSame(dateTo)
		},
		checkDateRange(day, month) {
			const date = $moment(`${this.month}/${this.year}`, 'MM/YYYY')
				.add(month, 'months')
				.add(day - 1, 'days')
				.startOf('day')

			const dateFrom = this.innerValue.from
				? $moment(this.innerValue.from, 'YYYY-MM-DD').startOf(
					'day',
				)
				: null

			let dateTo = this.innerValue.to
				? $moment(this.innerValue.to, 'YYYY-MM-DD').startOf('day')
				: null
			if (this.isCheckouting && this.hoverTo) {
				dateTo = this.hoverTo
			}

			return date.isAfter(dateFrom) && date.isBefore(dateTo)
		},
		selectDay(props) {
			if (!props.day || !props.picker) return false

			this.message = ''

			const date = $moment(`${this.month}/${this.year}`, 'MM/YYYY')
				.add(props.mindex, 'months')
				.startOf('day')
				.set({date: props.positionGrid})

			if (
				this.innerValue.from !== undefined &&
				this.innerValue.to !== undefined
			) {
				this.innerValue.from = date.format('YYYY-MM-DD')
				this.innerValue.to = undefined
				this.currentAction = 'to'

				return
			}

			const dateFrom = this.innerValue.from
				? $moment(this.innerValue.from, 'YYYY-MM-DD')
				: null

			const isCheckin =
				!this.innerValue.from || this.currentAction === 'from'

			if (
				!isCheckin &&
				(date.isBefore(dateFrom) || date.isSame(dateFrom))
			) {
				this.message = this.formatedMessage(
					'Checkout date must be after checkin date',
					{},
					true,
				)
				return
			}

			if (this.noBlocks) {
				if (isCheckin) this.changeDateFrom(date, props.day)
				else this.changeDateTo(date, props.day)
				return
			}

			const setMessage = (
				message = '',
				period = {},
				hidePeriod = false,
			) => {
				const title = message
				let text = ''
				if (period?.dateFrom) {
					text += ` The closest valid booking period is ${period.dateFrom.format(
						'Do MMMM YYYY',
					)}`

					if (period?.dateTo)
						text += ` to ${period.dateTo.format('Do MMMM YYYY')}`
				} else if (!hidePeriod) {
					text += ' There are no days available for booking'
				}

				const newMessage = `<h6 class="alert-heading ${
					text ? 'mb-3' : ''
				}">${title}</h6><p>${text}</p>`

				return newMessage
			}

			if (props.day.isBookedFull) {
				this.message = setMessage(
					'Date already booked',
					this.noPeriodCheck
						? ''
						: this.getValidPeriod(
							isCheckin ? date : dateFrom,
							isCheckin,
						),
					this.noPeriodCheck,
				)
				return
			}

			if (props.day.isBlockedFull) {
				this.message = setMessage(
					'Date is blocked',
					this.noPeriodCheck
						? ''
						: this.getValidPeriod(
							isCheckin ? date : dateFrom,
							isCheckin,
						),
					this.noPeriodCheck,
				)
				return
			}

			if (props.day.isRestricted) {
				this.message = setMessage(
					'Date not available for booking',
					this.noPeriodCheck
						? ''
						: this.getValidPeriod(
							isCheckin ? date : dateFrom,
							isCheckin,
						),
					this.noPeriodCheck,
				)
				return
			}

			if (props.day.isCheckoutUnavailable) {
				this.message = setMessage(
					`${this.minimumStay} night${
						this.minimumStay > 1 ? 's' : ''
					} minimum stay`,
					{},
					true,
				)
				return
			}

			if (isCheckin && props.day.isBooked && props.day.isCheckin) {
				this.message = setMessage(
					'Date already have a checkin',
					this.noPeriodCheck
						? ''
						: this.getValidPeriod(
							isCheckin ? date : dateFrom,
							isCheckin,
						),
					this.noPeriodCheck,
				)
				return
			} else if (
				!isCheckin &&
				props.day.isBooked &&
				props.day.isCheckout
			) {
				this.message = setMessage(
					'Date already have a checkout',
					{},
					true,
				)
				return
			}

			if (isCheckin && this.innerValue.to) {
				const isValidDayPeriodCheckin = this.checkValidDayPeriod(
					this.isCheckinMorning,
					props.day,
				)
				if (!isValidDayPeriodCheckin) {
					this.message = setMessage(
						'Date not available for booking',
						this.noPeriodCheck
							? ''
							: this.getValidPeriod(
								isCheckin ? date : dateFrom,
								isCheckin,
							),
						this.noPeriodCheck,
					)
					return
				}
				const valid = this.checkValidPeriod({
					from: date,
					to: $moment(this.innerValue.to, 'YYYY-MM-DD'),
				})

				if (!valid) {
					this.innerValue.to = ''
					this.message = setMessage(
						'Invalid date',
						this.noPeriodCheck
							? ''
							: this.getValidPeriod(
								isCheckin ? date : dateFrom,
								isCheckin,
							),
						this.noPeriodCheck,
					)
				}
				this.changeDateFrom(date, props.day)
			} else if (isCheckin) {
				const isValidDayPeriod = this.checkValidDayPeriod(
					this.isCheckinMorning,
					props.day,
				)
				if (!isValidDayPeriod) {
					this.message = setMessage(
						'Date not available for booking',
						this.noPeriodCheck
							? ''
							: this.getValidPeriod(
								isCheckin ? date : dateFrom,
								isCheckin,
							),
						this.noPeriodCheck,
					)
					return
				}
				this.changeDateFrom(date, props.day)
			} else {
				const valid = this.checkValidPeriod({
					from: dateFrom,
					to: date,
				})
				if (valid || this.propertyHasConnection) {
					this.changeDateTo(date, props.day)
				} else {
					this.message = setMessage(
						'Invalid date',
						this.noPeriodCheck
							? ''
							: this.getValidPeriod(
								isCheckin ? date : dateFrom,
								isCheckin,
							),
						this.noPeriodCheck,
					)
				}
			}
		},
		changeDateFrom(date, dayProps) {
			const dateTo = this.innerValue.to
				? $moment(this.innerValue.to, 'YYYY-MM-DD')
				: null

			if (dateTo && dateTo.isBefore(date)) this.innerValue.to = ''

			if (
				this.currentProperty &&
				Object.keys(this.currentProperty).length
			)
				this.getMinimumStay(date)

			this.currentAction = 'to'
			this.innerValue.from = date.format('YYYY-MM-DD')
			this.$emit('select:from', {
				controller: {
					setMessage: this.setMessage,
					setActionPicker: this.setActionPicker,
				},
				date: this.innerValue.from,
				dayProps,
			})
		},
		changeDateTo(date, dayProps) {
			if (
				!this.noBlocks &&
				this.currentProperty &&
				Object.keys(this.currentProperty).length
			) {
				const reservateDates =
					this.currentProperty.property_booking_reservations.map(
						(el) => ({
							...el,
							checkin: $moment(
								el.booking_calendar_hour_check_in,
							).startOf('day'),
							checkout: $moment(
								el.booking_calendar_hour_check_out,
							).startOf('day'),
						}),
					)

				const dateFrom = $moment(
					this.innerValue.from,
					'YYYY-MM-DD',
				).startOf('day')
				const isRangeInvalid = reservateDates?.filter(
					(el) =>
						el.checkin.isBetween(dateFrom, date) ||
						el.checkout.isBetween(dateFrom, date),
				).length
				if (isRangeInvalid) {
					this.message =
						'Date is not available for checkout. There are some dates reserved'

					return
				}

				if (
					this.currentProperty.property_configurations &&
					Number(
						this.currentProperty.property_configurations
							.block_cleaning,
					)
				) {
					const dateCleaning = date
						.clone()
						.add(
							Number(
								this.currentProperty.property_configurations
									.block_cleaning,
							),
							'days',
						)
						.startOf('day')

					if (
						reservateDates?.filter((el) =>
							dateCleaning.isBetween(el.checkin, el.checkout),
						).length
					) {
						this.messageType = 'alert-error'
						this.message = `Property needs ${
							this.currentProperty.property_configurations
								.block_cleaning
						} day${
							Number(
								this.currentProperty.property_configurations
									.block_cleaning,
							) > 1
								? 's'
								: ''
						} reserved for cleaning`

						return
					}
				}

				const seasonsDate = this.currentSeasonOfDate(date)
				if (seasonsDate && Object.keys(seasonsDate).length) {
					if (seasonsDate.block_cleaning_days) {
						const dateCleaningSeason = date
							.clone()
							.add(seasonsDate.block_cleaning_days, 'days')
							.startOf('day')

						if (
							reservateDates?.filter(
								(el) =>
									el.checkin.isSame(dateCleaningSeason) ||
									el.checkout.isSame(dateCleaningSeason),
							).length
						) {
							this.messageType = 'alert-error'
							this.message = `Property needs ${
								seasonsDate.block_cleaning_days
							} day${
								seasonsDate.block_cleaning_days > 1 ? 's' : ''
							} reserved for cleaning`

							return
						}
					}
				}
			}
			this.innerValue.to = date.format('YYYY-MM-DD')
			this.$emit('select:to', {
				controller: {
					setMessage: this.setMessage,
					setActionPicker: this.setActionPicker,
				},
				date: this.innerValue.to,
				dayProps,
			})
		},
		async downloadCalendar() {
			const text = `${window.location}/${this.currentProperty.id}/ical`
			try {
				await navigator.clipboard.writeText(text)
				alert('Link copied to clipboard')
			} catch (err) {
				alert('Error in copying link: ', err)
			}
		},
		hoverDay(dayData) {
			if (
				this.isCheckouting &&
				dayData.isHover &&
				this.innerValue.from &&
				!this.innerValue.to
			) {
				const date = $moment(
					`${this.month}/${this.year}`,
					'MM/YYYY',
				)
					.add(dayData.mindex, 'months')
					.startOf('day')
				date.set({date: dayData.positionGrid})

				if (
					date.isBefore(
						$moment(this.innerValue.from, 'YYYY-MM-DD'),
					)
				)
					return false

				this.hoverTo = date
			} else this.hoverTo = null
		},
		nextYear() {
			this.year = $moment(this.year, 'YYYY')
				.add(1, 'year')
				.format('YYYY')
			this.testPastNav()
			this.testFutureNav()
			this.$emit('prevNextMonth', this.month, this.year)
			this.$emit('next:year', this.year)
		},
		prevYear() {
			const current_date = $moment(
				`${this.year}-${this.month}`,
				'YYYY-MM',
			)

			const diff_year = current_date.diff(this.today(), 'years')
			let new_date
			if (this.infinity || diff_year > 0) {
				new_date = current_date.clone().subtract(1, 'years')
			} else {
				new_date = $moment(this.today())
			}

			this.month = new_date.format('MM')
			this.year = new_date.format('YYYY')

			this.testPastNav()
			this.testFutureNav()
			this.$emit('prevNextMonth', this.month, this.year)
		},
		nextMonth() {
			const month = this.month
			this.month = $moment(month + '/' + this.year, 'MM/YYYY')
				.add(1, 'month')
				.format('MM')
			this.year = $moment(month + '/' + this.year, 'MM/YYYY')
				.add(1, 'month')
				.format('YYYY')
			this.testPastNav()
			this.testFutureNav()
			this.$emit('prevNextMonth', this.month, this.year)
		},
		prevMonth() {
			const month = this.month
			this.month = $moment(month + '/' + this.year, 'MM/YYYY')
				.subtract(1, 'month')
				.format('MM')
			this.year = $moment(month + '/' + this.year, 'MM/YYYY')
				.subtract(1, 'month')
				.format('YYYY')
			this.testPastNav()
			this.testFutureNav()
			this.$emit('prevNextMonth', this.month, this.year)
		},
		today() {
			return $moment().format('YYYY-MM-DD')
		},
		isAfterToday(day, m) {
			const today = $moment().startOf('day')
			const date = $moment(`${this.month}/${this.year}`, 'MM/YYYY')
				.add(m, 'months')
				.add(day - 1, 'days')
			return !today.isSame(date, 'day') && today.isBefore(date)
		},
		isToday(day, m) {
			const month = $moment(this.month + '/' + this.year, 'MM/YYYY')
				.add(m, 'months')
				.format('MM')

			if (
				parseInt($moment().format('YYYY')) === parseInt(this.year)
			) {
				if (parseInt($moment().format('MM')) === parseInt(month)) {
					if (
						parseInt($moment().format('DD')) === parseInt(day)
					) {
						return true
					}
				}
			}
			return false
		},
		currentYear() {
			return $moment().format('YYYY')
		},
		currentMonth() {
			return $moment().format('MM')
		},
		getThisDate() {
			return $moment(this.month + '/' + this.year, 'MM/YYYY').format(
				'YYYY-MM',
			)
		},
		getMonthYear(qty) {
			return $moment(this.month + '/' + this.year, 'MM/YYYY')
				.add(qty, 'months')
				.format('MMMM YYYY')
		},
		getLastDayOfMonth(m) {
			return $moment(this.month, 'M')
				.add(m, 'months')
				.endOf('month')
				.format('DD')
		},
		getWeekDayLabel(weekday) {
			return $moment(weekday, 'e').format('ddd')
		},
		getWeekDayStartMonth(m) {
			const addedMonth = $moment(
				this.month + '/' + this.year,
				'MM/YYYY',
			)
				.add(m, 'months')
				.format('MM')
			const addedYear = $moment(
				this.month + '/' + this.year,
				'MM/YYYY',
			)
				.add(m, 'months')
				.format('YYYY')
			return $moment(
				'01/' + addedMonth + '/' + addedYear,
				'DD/MM/YYYY',
			).format('e')
		},
		calcDayPositionGrid(m, g) {
			return parseInt(g) - parseInt(this.getWeekDayStartMonth(m))
		},
		testPastNav() {
			this.disableNavPast =
				!this.infinity &&
				!$moment(`${this.year}-${this.month}`, 'YYYY-MM').isAfter(
					this.today(),
				)
			// if (parseInt(this.currentYear()) - parseInt(this.year) >= 0) {
			// 	if (parseInt(this.currentMonth()) - parseInt(this.month) >= 0) {
			// 		this.disableNavPast = true
			// 	}
			// }
		},
		testFutureNav() {
			if (this.infinity || !this.maxDaysAllowed) {
				this.disableNavFuture = false
				return false
			}
			const current_year = parseInt(
				$moment(this.year + '-' + this.month, 'YYYY-MM')
					.add(this.months - 1, 'months')
					.format('YYYY'),
			)
			const max_year = parseInt(
				$moment()
					.add(this.maxDaysAllowed, 'months')
					.format('YYYY'),
			)

			this.disableNavFuture = false
			if (current_year >= max_year) {
				const current_month = parseInt(
					$moment(this.year + '-' + this.month, 'YYYY-MM')
						.add(this.months - 1, 'months')
						.format('MM'),
				)
				const max_month = parseInt(
					$moment()
						.add(this.maxDaysAllowed, 'months')
						.format('MM'),
				)
				// const max_this_month = parseInt(
				// 	$moment()
				// 		.add(this.maxDaysAllowed, 'months')
				// 		.subtract(1, 'month')
				// 		.format('MM')
				// )

				if (
					current_month >= max_month ||
					current_year >= max_year + 1
				) {
					this.year = max_year
					this.month = max_month - 1
					this.disableNavFuture = true
				}
			}
		},
		clear() {
			this.innerValue.from = undefined
			this.innerValue.to = undefined
		},
	},
}

</script>

<style scoped>
.single {
	max-width: 350px;
}

.center-absolute {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}

.opacity-25 {
	opacity: 0.25;
}
</style>
