import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { ImportRun } from './entities/import-run.entity';
import { ImportStep } from './entities/import-step.entity';
import { ImportRow } from './entities/import-row.entity';
import { ImportRunService } from './imports.run.service';
import { ImportPreviewService } from './imports.preview.service';
import { ImportCommitService } from './imports.commit.service';

export type {
  ImportSheetMeta,
  ImportStepDetail,
  ImportRunDetail,
  ImportRunSettings,
  StepPreviewResult,
} from './imports.types';

@Injectable()
export class ImportsService {
  private runService?: ImportRunService;
  private previewService?: ImportPreviewService;
  private commitService?: ImportCommitService;

  constructor(
    @InjectRepository(ImportRun)
    private readonly runs: Repository<ImportRun>,
    @InjectRepository(ImportStep)
    private readonly steps: Repository<ImportStep>,
    @InjectRepository(ImportRow)
    private readonly rows: Repository<ImportRow>,
    private readonly dataSource: DataSource,
  ) {}

  private get runsSvc(): ImportRunService {
    if (!this.runService) {
      this.runService = new ImportRunService(this.runs, this.steps);
    }
    return this.runService;
  }

  private get previews(): ImportPreviewService {
    if (!this.previewService) {
      this.previewService = new ImportPreviewService(
        this.runs,
        this.steps,
        this.rows,
        this.dataSource,
      );
    }
    return this.previewService;
  }

  private get commits(): ImportCommitService {
    if (!this.commitService) {
      this.commitService = new ImportCommitService(
        this.runs,
        this.steps,
        this.rows,
        this.dataSource,
      );
    }
    return this.commitService;
  }

  async createRun(...args: Parameters<ImportRunService['createRun']>) {
    return this.runsSvc.createRun(...args);
  }

  async getRun(...args: Parameters<ImportRunService['getRun']>) {
    return this.runsSvc.getRun(...args);
  }

  async previewStep(...args: Parameters<ImportPreviewService['previewStep']>) {
    return this.previews.previewStep(...args);
  }

  async commitStep(...args: Parameters<ImportCommitService['commitStep']>) {
    return this.commits.commitStep(...args);
  }

  async errorReport(...args: Parameters<ImportCommitService['errorReport']>) {
    return this.commits.errorReport(...args);
  }
}
