import { BadRequestException, Injectable } from "@nestjs/common";

type ScheduleResolution = {
  date: string;
  source: "user" | "auto";
};

@Injectable()
export class SimScheduleService {
  private static readonly DATE_REGEX = /^\d{8}$/;

  ensureYyyyMmDd(value: string | undefined, fieldName = "date"): string {
    if (!value) {
      throw new BadRequestException(`${fieldName} is required in YYYYMMDD format`);
    }
    if (!SimScheduleService.DATE_REGEX.test(value)) {
      throw new BadRequestException(`${fieldName} must be in YYYYMMDD format`);
    }
    return value;
  }

  validateOptionalYyyyMmDd(value: string | undefined, fieldName = "date"): string | undefined {
    if (value == null) {
      return undefined;
    }
    if (!SimScheduleService.DATE_REGEX.test(value)) {
      throw new BadRequestException(`${fieldName} must be in YYYYMMDD format`);
    }
    return value;
  }

  resolveScheduledDate(value?: string, fieldName = "scheduledAt"): ScheduleResolution {
    if (value) {
      return {
        date: this.ensureYyyyMmDd(value, fieldName),
        source: "user",
      };
    }
    return {
      date: this.firstDayOfNextMonthYyyyMmDd(),
      source: "auto",
    };
  }

  firstDayOfNextMonth(): Date {
    const nextMonth = new Date();
    nextMonth.setHours(0, 0, 0, 0);
    nextMonth.setMonth(nextMonth.getMonth() + 1);
    nextMonth.setDate(1);
    return nextMonth;
  }

  firstDayOfNextMonthYyyyMmDd(): string {
    return this.formatYyyyMmDd(this.firstDayOfNextMonth());
  }

  firstDayOfNextMonthIsoDate(): string {
    return this.formatIsoDate(this.firstDayOfNextMonth());
  }

  formatYyyyMmDd(date: Date): string {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${year}${month}${day}`;
  }

  formatIsoDate(date: Date): string {
    return date.toISOString().split("T")[0];
  }
}

