import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';
import { AutomationTaskType, AutomationTaskStatus, AutomationExecutionStatus } from '@prisma/client';

export interface CreateTaskDto {
  name: string;
  code: string;
  description?: string;
  type: AutomationTaskType;
  scheduleType: string;
  scheduleConfig: any;
  config?: any;
  timeout?: number;
  retryCount?: number;
}

export interface UpdateTaskDto {
  name?: string;
  description?: string;
  status?: AutomationTaskStatus;
  scheduleType?: string;
  scheduleConfig?: any;
  config?: any;
  timeout?: number;
  retryCount?: number;
}

export interface ExecuteTaskDto {
  triggeredBy?: string;
}

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

  /**
   * 获取所有任务列表
   */
  async findAll(filters?: {
    type?: AutomationTaskType;
    status?: AutomationTaskStatus;
  }) {
    const where: any = {};

    if (filters?.type) {
      where.type = filters.type;
    }

    if (filters?.status) {
      where.status = filters.status;
    }

    const tasks = await this.prisma.automationTask.findMany({
      where,
      include: {
        _count: {
          select: {
            executions: true,
          },
        },
      },
      orderBy: {
        createdAt: 'desc',
      },
    });

    return tasks;
  }

  /**
   * 获取任务详情
   */
  async findOne(id: string) {
    const task = await this.prisma.automationTask.findUnique({
      where: { id },
      include: {
        createdBy: {
          select: {
            id: true,
            username: true,
            displayName: true,
          },
        },
        _count: {
          select: {
            executions: true,
          },
        },
      },
    });

    if (!task) {
      throw new NotFoundException('Task not found');
    }

    return task;
  }

  /**
   * 创建任务
   */
  async create(createTaskDto: CreateTaskDto, userId?: string) {
    const task = await this.prisma.automationTask.create({
      data: {
        ...createTaskDto,
        createdById: userId,
      },
    });

    return task;
  }

  /**
   * 更新任务
   */
  async update(id: string, updateTaskDto: UpdateTaskDto) {
    const task = await this.prisma.automationTask.findUnique({
      where: { id },
    });

    if (!task) {
      throw new NotFoundException('Task not found');
    }

    const updated = await this.prisma.automationTask.update({
      where: { id },
      data: updateTaskDto,
    });

    return updated;
  }

  /**
   * 删除任务
   */
  async remove(id: string) {
    const task = await this.prisma.automationTask.findUnique({
      where: { id },
    });

    if (!task) {
      throw new NotFoundException('Task not found');
    }

    await this.prisma.automationTask.delete({
      where: { id },
    });

    return { message: 'Task deleted successfully' };
  }

  /**
   * 启用/暂停/禁用任务
   */
  async updateStatus(id: string, status: AutomationTaskStatus) {
    return this.update(id, { status });
  }

  /**
   * 手动执行任务
   */
  async execute(id: string, executeDto: ExecuteTaskDto) {
    const task = await this.findOne(id);

    // 创建执行记录
    const execution = await this.prisma.automationExecution.create({
      data: {
        taskId: id,
        status: AutomationExecutionStatus.PENDING,
        triggerType: 'manual',
        triggeredBy: executeDto.triggeredBy,
      },
    });

    // 这里应该调用实际的执行逻辑
    // 当前只是创建一个执行记录作为占位
    // TODO: 实现实际的任务执行逻辑

    return {
      message: 'Task execution started',
      executionId: execution.id,
      task,
    };
  }

  /**
   * 获取任务的执行历史
   */
  async getExecutions(
    taskId: string,
    options?: {
      page?: number;
      pageSize?: number;
      status?: AutomationExecutionStatus;
    },
  ) {
    const page = options?.page || 1;
    const pageSize = options?.pageSize || 20;
    const skip = (page - 1) * pageSize;

    const where: any = { taskId };

    if (options?.status) {
      where.status = options.status;
    }

    const [executions, total] = await Promise.all([
      this.prisma.automationExecution.findMany({
        where,
        skip,
        take: pageSize,
        orderBy: {
          startedAt: 'desc',
        },
      }),
      this.prisma.automationExecution.count({ where }),
    ]);

    return {
      data: executions,
      pagination: {
        page,
        pageSize,
        total,
        totalPages: Math.ceil(total / pageSize),
      },
    };
  }

  /**
   * 获取执行详情
   */
  async getExecutionDetail(executionId: string) {
    const execution = await this.prisma.automationExecution.findUnique({
      where: { id: executionId },
      include: {
        task: {
          select: {
            id: true,
            name: true,
            code: true,
            type: true,
          },
        },
      },
    });

    if (!execution) {
      throw new NotFoundException('Execution not found');
    }

    return execution;
  }

  /**
   * 获取任务统计信息
   */
  async getStatistics() {
    const [totalTasks, activeTasks, totalExecutions, recentFailures] =
      await Promise.all([
        this.prisma.automationTask.count(),
        this.prisma.automationTask.count({
          where: { status: AutomationTaskStatus.ACTIVE },
        }),
        this.prisma.automationExecution.count(),
        this.prisma.automationExecution.count({
          where: {
            status: AutomationExecutionStatus.FAILED,
            startedAt: {
              gte: new Date(Date.now() - 24 * 60 * 60 * 1000), // 最近24小时
            },
          },
        }),
      ]);

    // 获取各类型任务统计
    const tasksByType = await this.prisma.automationTask.groupBy({
      by: ['type'],
      _count: true,
    });

    // 获取最近执行的任务
    const recentExecutions = await this.prisma.automationExecution.findMany({
      take: 10,
      orderBy: {
        startedAt: 'desc',
      },
      include: {
        task: {
          select: {
            name: true,
            type: true,
          },
        },
      },
    });

    return {
      totalTasks,
      activeTasks,
      totalExecutions,
      recentFailures,
      tasksByType,
      recentExecutions,
    };
  }
}

