import { Logger } from '@nestjs/common';
import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';
import * as fs from 'node:fs';
import { QueueName } from '../queue-names';
import type { ColdImportJob } from '../job-payloads';
import { ColdImportService } from '../../modules/sync/cold-import/cold-import.service';

/**
 * cold-import worker — 网页上传压缩包触发的整包导入。
 *
 * 流程:
 *   1. 调 ColdImportService.importDirectory(job.dir) — 与 CLI `pnpm cold-import` 同一入口;
 *      内部自建 syncLog(审计/最近事件)、cohort 分批、幂等落库。返回 ImportRunResult。
 *   2. finally 清理临时解压目录(含 PII 的上传数据文件不残留);失败时保留供排查。
 *
 * concurrency=1:整包导入是重任务,且 importDirectory 有 partial UNIQUE(host_id)
 *   WHERE status='running' 并发锁 —— 串行天然避免撞锁。attempts=1 不自动重试。
 *
 * 返回值即 job.returnvalue,前端按 jobId 轮询时读其中 totals 展示结果。
 */
@Processor(QueueName.COLD_IMPORT, { concurrency: 1 })
export class ColdImportProcessor extends WorkerHost {
  private readonly logger = new Logger(ColdImportProcessor.name);

  constructor(private readonly coldImport: ColdImportService) {
    super();
  }

  async process(job: Job<ColdImportJob>) {
    const { hostName, dir, cleanupDir, dryRun, triggeredBy } = job.data;
    this.logger.log(
      `cold-import START job=${job.id} host=${hostName} dir=${dir} dryRun=${!!dryRun} triggeredBy=${triggeredBy}`,
    );

    try {
      const result = await this.coldImport.importDirectory(dir, { dryRun: !!dryRun });
      this.logger.log(
        `cold-import DONE job=${job.id} host=${hostName} status=${result.status} ` +
          `patients=${result.totals.patientsUpserted} txn=${result.totals.transactionsWritten} ` +
          `dup=${result.totals.duplicates} failed=${result.totals.failed} ` +
          `factsCreated=${result.totals.factsCreated} factsSuperseded=${result.totals.factsSuperseded}`,
      );
      return result;
    } finally {
      // 成功/失败都清理整个迷你 data 根(cleanupDir,含 <host>/ 数据 + _shared/ 副本)。
      // 始终清理(PII 优先),失败原因已在 syncLog.errorMessage + job.failedReason 里。
      const target = cleanupDir ?? dir; // 兼容旧 job(无 cleanupDir)
      try {
        await fs.promises.rm(target, { recursive: true, force: true });
        this.logger.debug(`cold-import 清理临时目录 job=${job.id} dir=${target}`);
      } catch (err) {
        this.logger.warn(
          `cold-import 清理临时目录失败 job=${job.id} dir=${target}: ${err instanceof Error ? err.message : err}`,
        );
      }
    }
  }
}
