import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { RoleDto } from '../dto/role.dto';
import { Feature } from '../entities/feature.entity';
import { Role } from '../entities/role.entity';

@Injectable()
export class RoleService {
  constructor(
    @InjectRepository(Role)
    private roleRepository: Repository<Role>,
  ) {}

  async create(roleDto: RoleDto) {
    return await this.roleRepository.manager.transaction(
      async (entityManager) => {
        const { features, ...role } = roleDto;
        const { id: roleId } = await entityManager.save(Role, role);

        for (const v of features) {
          v.roleId = roleId;
          v.updater = v.creator = role.creator;
        }

        await entityManager.insert(Feature, features);
      },
    );
  }

  async findAll() {
    return this.roleRepository
      .createQueryBuilder('role')
      .innerJoinAndMapMany(
        'role.features',
        Feature,
        'feature',
        [
          'feature.role_id=role.id',
          'feature.del_flag=0',
          'role.del_flag=0',
        ].join(' and '),
      )
      .select([
        'role.id',
        'role.name',
        'role.desc',
        'role.base',
        'role.creator',
        'feature.name',
      ])
      .getMany();
  }

  async update(id: number, roleDto: RoleDto) {
    return await this.roleRepository.manager.transaction(
      async (entityManager) => {
        await entityManager.delete(Feature, { roleId: id });

        const { features, ...role } = roleDto;
        await entityManager.update(Role, { id }, role);

        for (const v of features) {
          v.roleId = id;
          v.updater = v.creator = role.creator;
        }

        await entityManager.insert(Feature, features);
      },
    );
  }

  async remove(id: number) {
    return await this.roleRepository.manager.transaction(
      async (entityManager) => {
        await entityManager.delete(Feature, { roleId: id });
        await entityManager.update(Role, { id }, { delFlag: 1 });
      },
    );
  }
}
