import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import { AppService } from '../../../app.service';
import { EEnvVariable } from '../../../configuration/enums/env-variable.enum';
import {
  REDIS_KEYS,
  RedisService,
} from '../../../shared/services/redis/redis.service';
import { Attachment } from '../../attachment.entity';
import { RemoveAttachmentWorkflow } from '../../workflows/remove-attachment/remove-attachment.workflow';

@Injectable()
export class RemoveNotAllowedAttachmentsCron {
  public readonly maxTemporaryAttachments: number = +process.env[
    EEnvVariable.MAX_TEMPORARY_ATTACHMENTS
  ];

  private logger: Logger = new Logger('RemoveNotAllowedAttachmentsCron');

  constructor(
    private removeAttachmentWorkflow: RemoveAttachmentWorkflow,
    private redisService: RedisService,
    private appService: AppService
  ) {}

  @Cron('*/30 * * * * *')
  async handleCron() {
    if (
      process.env['NODE_ENV'] !== 'development' &&
      !this.appService.isMaster
    ) {
      return;
    }

    const licenseeIds: number[] = [];
    const licenseeIdList = this.redisService.getList(
      REDIS_KEYS.ATTACHMENT_LICENSEE_IDS_CHECKS
    );

    this.redisService.deleteKey(REDIS_KEYS.ATTACHMENT_LICENSEE_IDS_CHECKS);

    for (const v of await licenseeIdList) {
      if (!licenseeIds.includes(+v)) {
        licenseeIds.push(+v);
      }
    }

    if (licenseeIds.length === 0) {
      return;
    }

    this.logger.log(
      `[licenseeIds=${licenseeIds.join(
        ', '
      )}] were received for Attachment check`
    );
    for (const licenseeId of licenseeIds) {
      this.logger.log(
        `Checking for over-the-limit Attachments for [licenseeId=${licenseeId}]`
      );
      const temporaryAttachments = await Attachment.find({
        where: { licensee: licenseeId, message: null, isLocal: true },
        order: { createdOn: 'ASC' },
      });

      if (temporaryAttachments.length <= this.maxTemporaryAttachments) {
        return;
      }

      const deleteCount =
        temporaryAttachments.length - this.maxTemporaryAttachments;

      this.logger.log(
        `${deleteCount} over-the-limit Attachments were found for [licenseeId=${licenseeId}]`
      );

      let deletedCount = 0;
      try {
        for (let i = 0; i < deleteCount; i++) {
          await this.removeAttachmentWorkflow.remove(temporaryAttachments[i]);
          deletedCount++;
        }
        this.logger.log('All over-the-limit Attachments were deleted');
      } catch (e) {
        this.logger.error(
          `Not all over-the-limit Attachments were deleted (${deletedCount} deleted)`,
          e
        );
      }
    }
  }
}
