import { Inject, Injectable } from '@nestjs/common';
import { UserProvider, UsersSession } from 'src/core/sessions';
import { BLANK_USER } from 'src/core/strings/constants/base.constants';
import { EditDataSchedulingDefaultDto } from '../../../infrastructure/dto/data-scheduling.dto';
import { DataSchedulingDefaultEntity } from '../../entities/data-scheduling.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSchedulingDefaultModel } from '../../../data/models/data-scheduling-default.model';
import { Repository } from 'typeorm';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import { SelectQueryBuilder } from 'typeorm';
import { DataSchedulingModel } from '../../../data/models/data-scheduling.model';
import { EventBus } from '@nestjs/cqrs';
import { DataSchedulingChangeStatusEvent } from '../../entities/event/data-scheduling-change-status.event';

@Injectable()
export class DataSchedulingManager {
  @Inject()
  protected userProvider: UserProvider;

  constructor(
    private eventBus: EventBus,

    @InjectRepository(DataSchedulingDefaultModel)
    private repository: Repository<DataSchedulingDefaultModel>,

    @InjectRepository(DataSchedulingModel)
    private repoSchedule: Repository<DataSchedulingModel>,
  ) {}

  private getUser(): UsersSession {
    try {
      return this.userProvider?.user ?? BLANK_USER;
    } catch (error) {
      return BLANK_USER;
    }
  }

  get tableName(): string {
    return TABLE_NAME.DATA_SCHEDULING_DEFAULT;
  }

  private queryBuilder(): SelectQueryBuilder<DataSchedulingDefaultModel> {
    return this.repository.createQueryBuilder(this.tableName);
  }

  async update(
    body: EditDataSchedulingDefaultDto,
  ): Promise<DataSchedulingDefaultEntity> {
    if (body.default_value > 100) {
      throw new Error('Value tidak boleh lebih dari 100.');
    }

    const userData = this.getUser();
    const dateNow = new Date().getTime();
    const existData = await this.queryBuilder().getOne();

    const payload: DataSchedulingDefaultEntity = {
      id: existData?.id,
      default_value: body.default_value,
      creator_id: userData.id as any,
      creator_name: userData.name,
      editor_id: userData.id as any,
      editor_name: userData.name,
      created_at: dateNow,
      updated_at: dateNow,
    };

    await this.publishEventUpdates();
    return this.repository.save(payload);
  }

  async getData() {
    return this.queryBuilder().getOne();
  }

  async publishEventUpdates() {
    await this.eventBus.publish(
      new DataSchedulingChangeStatusEvent({ data: null } as any),
    );
  }

  async setupActiveScheduling() {
    await this.publishEventUpdates();
    return { message: 'Success setup transaction schedule.' };
  }
}
