import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { PrismaService } from '@core/database/prisma/prisma.service';
import { SyncService } from './sync.service';

const TASK_CODE = 'ENTRA_ID_SYNC';

@Injectable()
export class ScheduledSyncService {
  private readonly logger = new Logger(ScheduledSyncService.name);

  constructor(
    private readonly syncService: SyncService,
    private readonly prisma: PrismaService,
  ) {}

  /**
   * 定时任务：每小时执行同步
   */
  @Cron('0 * * * *', {
    name: 'entra-id-sync',
    timeZone: 'Asia/Shanghai',
  })
  async handleScheduledSync() {
    await this.executeSync('SCHEDULED');
  }

  /**
   * 手动触发同步
   */
  async triggerManualSync() {
    return this.executeSync('MANUAL');
  }

  /**
   * 统一执行入口：注册任务、创建执行记录、执行同步、更新结果
   */
  private async executeSync(triggerType: 'SCHEDULED' | 'MANUAL') {
    // 查找或自动注册任务
    let task = await this.prisma.automationTask.findFirst({ where: { code: TASK_CODE } });
    if (!task) {
      this.logger.log(`任务 ${TASK_CODE} 未注册，自动创建`);
      task = await this.prisma.automationTask.create({
        data: {
          code: TASK_CODE,
          name: 'Entra ID 用户同步',
          type: 'LDAP_SYNC',
          scheduleType: 'CRON',
          status: 'ACTIVE',
        },
      });
    }

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

    try {
      const result = await this.syncService.syncFromEntra();

      // 构建日志文本
      const logs = [
        `总用户数: ${result.totalUsers}`,
        `新增: ${result.createdUsers}`,
        `更新: ${result.updatedUsers}`,
        `跳过: ${result.skippedUsers}`,
        `冲突: ${result.conflictUsers}`,
        `保护(已离职): ${result.protectedTerminatedUsers}`,
        ...(result.errors.length > 0 ? [`错误(${result.errors.length}):\n${result.errors.join('\n')}`] : []),
      ].join('\n');

      // 更新执行记录
      await this.prisma.automationExecution.update({
        where: { id: execution.id },
        data: {
          status: result.success ? 'SUCCESS' : 'FAILED',
          completedAt: new Date(),
          duration: result.duration,
          result: result as any,
          error: result.errors.length > 0 ? result.errors.join('\n') : null,
          logs,
        },
      });

      // 更新任务统计
      await this.prisma.automationTask.update({
        where: { id: task.id },
        data: {
          lastRunAt: new Date(),
          lastStatus: result.success ? 'SUCCESS' : 'FAILED',
          totalRuns: { increment: 1 },
          ...(result.success
            ? { successRuns: { increment: 1 } }
            : { failedRuns: { increment: 1 } }),
        },
      });

      this.logger.log(
        `[${triggerType}] Entra ID 同步完成 - ` +
        `总数: ${result.totalUsers}, 新增: ${result.createdUsers}, ` +
        `更新: ${result.updatedUsers}, 跳过: ${result.skippedUsers}, ` +
        `耗时: ${result.duration}ms`,
      );

      return result;
    } catch (error: any) {
      this.logger.error(`[${triggerType}] Entra ID 同步失败: ${error.message}`, error.stack);

      await this.prisma.automationExecution.update({
        where: { id: execution.id },
        data: {
          status: 'FAILED',
          completedAt: new Date(),
          duration: Date.now() - execution.startedAt.getTime(),
          error: error.message,
        },
      });

      await this.prisma.automationTask.update({
        where: { id: task.id },
        data: {
          lastRunAt: new Date(),
          lastStatus: 'FAILED',
          totalRuns: { increment: 1 },
          failedRuns: { increment: 1 },
        },
      });

      throw error;
    }
  }
}
