import AppResponse from '@/response/app-response';
import {
  BadRequestException,
  HttpStatus,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Request } from 'express';
import {
  FilterOperator,
  FilterSuffix,
  paginate,
  PaginateQuery,
} from 'nestjs-paginate';
import { Column } from 'nestjs-paginate/lib/helper';
import { In, Repository } from 'typeorm';
import { v1 as uuidV1 } from 'uuid';
import Admin from '../entities/admin.entity';
import { GenerateKey } from '../entities/generate-key.entity';
import Permission from '../entities/permission.entity';

@Injectable()
export class GenerateKeysService {
  constructor(
    @InjectRepository(GenerateKey)
    readonly generateKeyRepo: Repository<GenerateKey>,
    @InjectRepository(Permission)
    readonly permissionRepo: Repository<Permission>,
  ) {}

  async index(query: PaginateQuery) {
    const filterableColumns: {
      [key in Column<Admin> | (string & {})]?:
        | (FilterOperator | FilterSuffix)[]
        | true;
    } = {
      id: true,
      client_key: [FilterOperator.ILIKE],
    };

    query.filter = AppResponse.processFilters(query.filter, filterableColumns);

    const data = await paginate(query, this.generateKeyRepo, {
      sortableColumns: ['id', 'client_key'],
      searchableColumns: ['id', 'client_key'],
      defaultLimit: 15,
      filterableColumns,
      defaultSortBy: [['id', 'DESC']],
      maxLimit: 100,
    });

    return AppResponse.toPagination<GenerateKey>(data, true, GenerateKey);
  }

  async delete(id: Admin['id']) {
    const admin = await this.generateKeyRepo.findOne({ where: { id } });

    if (!admin)
      throw new NotFoundException(
        AppResponse.toResponse(false, {
          message: 'Key is not found',
          status_code: HttpStatus.NOT_FOUND,
        }),
      );

    await this.generateKeyRepo.delete({ id: admin.id });

    return AppResponse.toResponse(true, { message: 'Delete success !' });
  }

  async deletes(ids: Admin['id'][]) {
    const result = await this.generateKeyRepo.delete({
      id: In(ids),
    });

    if (!result.affected) {
      throw new BadRequestException(
        AppResponse.toResponse(false, {
          message: 'No items have been deleted yet.',
          status_code: HttpStatus.BAD_REQUEST,
        }),
      );
    }

    return AppResponse.toResponse(true, { message: 'Delete success !' });
  }

  async create(request: Request) {
    const admin = request['admin'];

    const clientKey = uuidV1();

    const result = await this.generateKeyRepo.save({
      admin: { id: admin.id },
      client_key: `client-${clientKey}-${admin.id}`,
    });

    if (!result)
      throw new BadRequestException(
        AppResponse.toResponse(null, { message: `Can't create key` }),
      );

    return AppResponse.toResponse(result);
  }

}
