import { UniqueID } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; import { MailboxError, type MailboxUseInput, MailboxUseInputSchema } from "../mailbox-values"; import { CalendarDate } from "./calendar-date"; export class MailboxUseValues { private constructor( public readonly mailboxId: UniqueID, public readonly personId: UniqueID, public readonly startDate: CalendarDate, public readonly endDate: Maybe ) { Object.freeze(this); } static create(input: MailboxUseInput): Result { const parsed = MailboxUseInputSchema.safeParse(input); if (!parsed.success || (input.endDate !== null && input.endDate < input.startDate)) { return Result.fail(new MailboxError("INVALID_PERIOD")); } const mailbox = UniqueID.create(input.mailboxId); const person = UniqueID.create(input.personId); const start = CalendarDate.create(input.startDate); const end = input.endDate ? CalendarDate.create(input.endDate) : undefined; if (!(mailbox.isSuccess && person.isSuccess && start.isSuccess) || (end && !end.isSuccess)) { return Result.fail(new MailboxError("INVALID_REQUEST")); } return Result.ok( new MailboxUseValues( mailbox.data, person.data, start.data, end?.isSuccess ? Maybe.some(end.data) : Maybe.none() ) ); } toPrimitive(): MailboxUseInput { return { mailboxId: this.mailboxId.toPrimitive(), personId: this.personId.toPrimitive(), startDate: this.startDate.toPrimitive(), endDate: this.endDate.getOrUndefined()?.toPrimitive() ?? null, }; } sameTarget(other: MailboxUseValues) { return ( this.mailboxId.equals(other.mailboxId) && this.personId.equals(other.personId) && this.startDate.equals(other.startDate) ); } equals(other: MailboxUseValues) { return this.sameTarget(other) && this.toPrimitive().endDate === other.toPrimitive().endDate; } current(today: string) { const data = this.toPrimitive(); return data.startDate <= today && (data.endDate === null || today < data.endDate); } overlaps(other: MailboxUseValues) { const a = this.toPrimitive(); const b = other.toPrimitive(); return ( a.startDate !== a.endDate && b.startDate !== b.endDate && this.mailboxId.equals(other.mailboxId) && this.personId.equals(other.personId) && (b.endDate === null || a.startDate < b.endDate) && (a.endDate === null || b.startDate < a.endDate) ); } }