import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { WorkflowConfigurationVariable } 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';

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

  async findByWorkflowId(workflowConfigurationId: number): Promise<WorkflowConfigurationVariable[]> {
    try {
      return await this.repo
        .createQueryBuilder('wcv')
        .leftJoinAndSelect('wcv.variableMaster', 'vm')
        .where('wcv.workflowConfigId = :workflowConfigurationId', { workflowConfigurationId })
        .andWhere('wcv.deletedAt IS NULL')
        .orderBy('wcv.variableOrder', 'ASC')
        .getMany();
    } catch (error) {
      this.logger.error('Failed to load workflow configuration variables', error?.stack, { workflowConfigurationId });
      handleKnownErrors(ERROR_CODES.WORKFLOW_VARIABLE_GET_FAILED, error);
    }
  }

  async findByWorkflowIdWithDetails(workflowConfigurationId: number): Promise<WorkflowConfigurationVariable[]> {
    try {
      return await this.repo
        .createQueryBuilder('wcv')
        .leftJoinAndSelect('wcv.variableMaster', 'vm')
        .where('wcv.workflowConfigId = :workflowConfigurationId', { workflowConfigurationId })
        .andWhere('wcv.deletedAt IS NULL')
        .andWhere('vm.isActive = :isActive', { isActive: true })
        .andWhere('vm.deletedAt IS NULL')
        .orderBy('vm.executionOrder', 'ASC')
        .addOrderBy('wcv.variableOrder', 'ASC')
        .getMany();
    } catch (error) {
      this.logger.error('Failed to load workflow configuration variables with details', error?.stack, {
        workflowConfigurationId,
      });
      handleKnownErrors(ERROR_CODES.WORKFLOW_VARIABLE_GET_FAILED, error);
    }
  }

  async create(data: Partial<WorkflowConfigurationVariable>): Promise<WorkflowConfigurationVariable> {
    try {
      const variable = this.repo.create(data);
      return await this.repo.save(variable);
    } catch (error) {
      this.logger.error('Failed to create workflow configuration variable', error?.stack, { data });
      handleKnownErrors(ERROR_CODES.WORKFLOW_VARIABLE_CREATE_FAILED, error);
    }
  }

  async bulkCreate(data: Partial<WorkflowConfigurationVariable>[]): Promise<WorkflowConfigurationVariable[]> {
    try {
      const variables = this.repo.create(data);
      return await this.repo.save(variables);
    } catch (error) {
      this.logger.error('Failed to bulk create workflow configuration variables', error?.stack, { data });
      handleKnownErrors(ERROR_CODES.WORKFLOW_VARIABLE_CREATE_FAILED, error);
    }
  }

  async deleteByWorkflowId(workflowConfigurationId: number): Promise<void> {
    try {
      await this.repo.softDelete({ workflowConfigId: workflowConfigurationId });
    } catch (error) {
      this.logger.error('Failed to delete workflow configuration variables', error?.stack, { workflowConfigurationId });
      handleKnownErrors(ERROR_CODES.WORKFLOW_VARIABLE_DELETE_FAILED, error);
    }
  }
}
