import { Injectable, Logger } from '@nestjs/common';
import { DataSource } from 'typeorm';
import { SortCriteria } from './entity/sort_criteria.entity';
import {
  TaskListSortableAttribute,
  SortDirection,
} from '../../common/types/sort';
import { updateEntity } from '../../common/repository';
import { Context } from '../../common/log';

@Injectable()
export class SortCriteriaRepositoryService {
  constructor(private dataSource: DataSource) {}
  private readonly logger = new Logger(SortCriteriaRepositoryService.name);
  /**
   * Updates sort criteria
   * @param userId
   * @param parameter
   * @param direction
   * @returns sort criteria
   */
  async updateSortCriteria(
    context: Context,
    userId: number,
    parameter: TaskListSortableAttribute,
    direction: SortDirection,
  ): Promise<void> {
    this.logger.log(
      ` ${this.updateSortCriteria.name}; parameter:${parameter}, direction:${direction}`,
    );
    return await this.dataSource.transaction(async (entityManager) => {
      const repo = entityManager.getRepository(SortCriteria);
      const targetSortCriteria = await repo.findOne({
        where: {
          user_id: userId,
        },
        comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
      });
      // 運用上はあり得ないが、プログラム上発生しうるのでエラーとして処理
      if (!targetSortCriteria) {
        throw new Error('sort criteria not found.');
      }

      targetSortCriteria.parameter = parameter;
      targetSortCriteria.direction = direction;

      await updateEntity(
        repo,
        { id: targetSortCriteria.id },
        targetSortCriteria,
        false,
        context,
      );
    });
  }
  /**
   * Gets sort criteria
   * @param userId
   * @returns sort criteria
   */
  async getSortCriteria(
    context: Context,
    userId: number,
  ): Promise<SortCriteria> {
    this.logger.log(` ${this.updateSortCriteria.name}; userId:${userId}`);

    const repo = this.dataSource.getRepository(SortCriteria);
    const sortCriteria = await repo.findOne({
      where: {
        user_id: userId,
      },
      comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
    });
    // 運用上はあり得ないが、プログラム上発生しうるのでエラーとして処理
    if (!sortCriteria) {
      throw new Error('sort criteria not found.');
    }

    return sortCriteria;
  }
}
