import { Injectable, NotFoundException, BadRequestException } from "@nestjs/common";
import { PrismaService } from "../prisma/prisma.service";

// Cron expression validation regex (simplified)
// Matches 5 space-separated fields: * or 0-59
// Note: This is a simplified regex. For production, use a cron library like cron-parser
// eslint-disable-next-line security/detect-unsafe-regex
const CRON_REGEX = /^(\*|[0-5]?[0-9])(\s+(\*|[0-5]?[0-9])){4}$/;

export interface CreateCronDto {
  workspaceId: string;
  expression: string;
  command: string;
}

export interface UpdateCronDto {
  expression?: string;
  command?: string;
  enabled?: boolean;
}

@Injectable()
export class CronService {
  constructor(private readonly prisma: PrismaService) {}

  async create(dto: CreateCronDto) {
    if (!this.isValidCronExpression(dto.expression)) {
      throw new BadRequestException("Invalid cron expression");
    }

    return this.prisma.cronSchedule.create({
      data: {
        workspaceId: dto.workspaceId,
        expression: dto.expression,
        command: dto.command,
        enabled: true,
      },
    });
  }

  async findAll(workspaceId: string) {
    return this.prisma.cronSchedule.findMany({
      where: { workspaceId },
      orderBy: { createdAt: "desc" },
    });
  }

  async findOne(id: string, workspaceId?: string) {
    const schedule = await this.prisma.cronSchedule.findUnique({
      where: { id },
    });

    if (!schedule) {
      return null;
    }

    if (workspaceId && schedule.workspaceId !== workspaceId) {
      return null;
    }

    return schedule;
  }

  async update(id: string, workspaceId: string, dto: UpdateCronDto) {
    const schedule = await this.findOne(id, workspaceId);

    if (!schedule) {
      throw new NotFoundException("Cron schedule not found");
    }

    if (dto.expression && !this.isValidCronExpression(dto.expression)) {
      throw new BadRequestException("Invalid cron expression");
    }

    return this.prisma.cronSchedule.update({
      where: { id },
      data: {
        ...(dto.expression && { expression: dto.expression }),
        ...(dto.command && { command: dto.command }),
        ...(dto.enabled !== undefined && { enabled: dto.enabled }),
      },
    });
  }

  async remove(id: string, workspaceId: string) {
    const schedule = await this.prisma.cronSchedule.findUnique({
      where: { id },
    });

    if (!schedule) {
      throw new NotFoundException("Cron schedule not found");
    }

    if (schedule.workspaceId !== workspaceId) {
      throw new BadRequestException("Not authorized to delete this schedule");
    }

    return this.prisma.cronSchedule.delete({
      where: { id },
    });
  }

  private isValidCronExpression(expression: string): boolean {
    return CRON_REGEX.test(expression);
  }
}
