import { isDate, isEmpty } from 'lodash' import { ZonedDateTime } from '@js-joda/core' import { format } from 'date-fns' import '@js-joda/timezone' import { BaseModel } from './base.model' export const AvailabilityTimeStatusValues = ['scheduled', 'blocked', 'available'] as const export type AvailabilityTimeStatus = typeof AvailabilityTimeStatusValues[number] export class AvailabilityTime extends BaseModel { id: string appointment_id: string availability_id: string reason: string status: AvailabilityTimeStatus time: string user_id?: string timezone?: string get isAvailable(): boolean { return this.status === 'available' } get isScheduled(): boolean { return this.status === 'scheduled' } get hoursWithoutOffset(): string { return this.time?.slice(0, 5) } get offset(): string { let time = this.time?.slice(8) if (isEmpty(time)) return null if (time.length === 3) time = `${time}:00` return time } getUTCDate(date: Date): Date { const dateStr = isDate(date) ? format(date, 'yyyy-MM-dd') : date return new Date(`${dateStr}T${this.hoursWithoutOffset}${this.getOffsetOfByDateAndTimezone(date)}`) } setOffsetInTime(date: Date): void { this.time = `${this.hoursWithoutOffset}${this.getOffsetOfByDateAndTimezone(date)}` } setScheduled(appointmentId?: string): void { this.status = 'scheduled' if (appointmentId) this.appointment_id = appointmentId } free(): void { this.appointment_id = null this.status = 'available' } block(): void { this.appointment_id = null this.status = 'blocked' } private getOffsetOfByDateAndTimezone(date: Date): string { const dateStr = isDate(date) ? format(date, 'yyyy-MM-dd') : date const time = `${this.hoursWithoutOffset}${!this.offset ? 'Z' : this.offset}` return ZonedDateTime.parse(`${dateStr}T${time}[${this.timezone}]`) .offset() .toString() } }