import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { WorkflowConfiguration } from 'src/common/entities';
import { CommonDataService } from 'src/common/services/commonData.service';
import { AppLoggerService } from 'src/common/services/logger.service';
import { handleKnownErrors } from 'src/common/utils/handle-error.util';
import { ERROR_CODES } from 'src/common/constants/error-string-constants';
import { WorkflowLifecycleStatusEnum } from 'src/common/enum/workflow-lifecycle-status.enum';

@Injectable()
export class WorkflowConfigurationRepository {
  constructor(
    @InjectRepository(WorkflowConfiguration)
    private readonly repo: Repository<WorkflowConfiguration>,
    private readonly commonDataService: CommonDataService,
    private readonly logger: AppLoggerService,
  ) {}

  async findActiveByProgramTypeKey(programTypeKey: string): Promise<WorkflowConfiguration | null> {
    try {
      const data = await this.commonDataService.get(
        this.repo,
        undefined,
        {
          programTypeKey,
          lifecycleStatus: WorkflowLifecycleStatusEnum.ACTIVE,
        },
        1,
        0,
        { id: 'DESC' },
        undefined,
        ['stages', 'actions'],
      );
      return data[0] ?? null;
    } catch (error) {
      this.logger.error('Failed to load workflow configuration by program type key', error?.stack, { programTypeKey });
      handleKnownErrors(ERROR_CODES.WORKFLOW_CONFIGURATION_GET_FAILED, error);
    }
  }

  async findByWorkflowKey(workflowKey: string): Promise<WorkflowConfiguration | null> {
    try {
      const data = await this.commonDataService.get(
        this.repo,
        undefined,
        { workflowKey },
        1,
        0,
        { id: 'DESC' },
        undefined,
        ['stages', 'actions'],
      );
      return data[0] ?? null;
    } catch (error) {
      this.logger.error('Failed to load workflow configuration by workflowKey', error?.stack, { workflowKey });
      handleKnownErrors(ERROR_CODES.WORKFLOW_CONFIGURATION_GET_FAILED, error);
    }
  }

  async findById(id: number): Promise<WorkflowConfiguration | null> {
    try {
      const data = await this.commonDataService.get(
        this.repo,
        undefined,
        { id },
        1,
        0,
        { id: 'DESC' },
        undefined,
        ['stages', 'actions'],
      );
      return data[0] ?? null;
    } catch (error) {
      this.logger.error('Failed to load workflow configuration by id', error?.stack, { id });
      handleKnownErrors(ERROR_CODES.WORKFLOW_CONFIGURATION_GET_FAILED, error);
    }
  }
}
