import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, MaxLength } from 'class-validator';
import { CreateDto } from 'src/common/dto/create.dto';
import { PaginationDTO } from 'src/assessment-evaluation/dto/pagination.dto';
import { DeviceParts } from 'src/train/entities/device/device-parts.entity';
import { DevicePartHasOperation } from 'src/train/entities/device/device-part-has-operation.entity';
import { DevicePartOperation } from 'src/train/entities/device/device-part-operation.entity';

@Injectable()
export class DevicePartsService {
  constructor(
    @InjectRepository(DeviceParts)
    private deviceParts: Repository<DeviceParts>,
    @InjectRepository(DevicePartHasOperation)
    private devicePartHasOperation: Repository<DevicePartHasOperation>,
  ) {}
  /**
   * 创建部件
   * @param createClassifyDto
   * @returns
   */
  async create(createClassifyDto: CreatePartDto) {
    const part = await this.deviceParts.save(createClassifyDto, {
      transaction: false,
    });
    // 创建部件时可以同时保存所有部件操作
    if (createClassifyDto.operation?.length > 0) {
      const datas = createClassifyDto.operation.map((item) => ({
        creator: createClassifyDto.creator,
        updater: createClassifyDto.creator,
        part: +part.id,
        operation: +item.id,
      }));
      await this.devicePartHasOperation.insert(datas);
    }
    return true;
  }
  /**
   * 更新部件
   * @param id
   * @param updateClassifyDto
   * @returns
   */
  async update(id: number, updateClassifyDto: UpdatePartDto) {
    await this.deviceParts.update(id, updateClassifyDto);
    // 删除所有部件关联的操作后再次保存
    await this.devicePartHasOperation.delete({ part: +id });
    // 创建部件时可以同时保存所有部件操作
    if (updateClassifyDto.operation?.length > 0) {
      const datas = updateClassifyDto.operation.map((item) => ({
        part: +id,
        operation: +item.id,
      }));
      await this.devicePartHasOperation.insert(datas);
    }
    return true;
  }
  /**
   * 获取该设备下所有部件
   * @returns
   */
  async findAll(deviceId: number) {
    return this.deviceParts.query(
      `select dp.id,dp.device,dp.name,group_concat(dpo.name) as operations,dp.keycode ,dp.comment from device_parts dp 
      left join device_part_has_operation dpho on dpho.part  = dp.id
      left join device_part_operation dpo on dpo.id = dpho.operation 
      where dp.del_flag  = 0 and dp.device  = ?
      group by dp.id order by dp.id desc`,
      [deviceId],
    );
  }
  /**
   * 获取部件详情-用于编辑部件，同时返回所有
   * @returns
   */
  async findOne(id: number) {
    return this.deviceParts
      .createQueryBuilder('part')
      .where({ delFlag: 0, id })
      .leftJoinAndMapMany(
        '',
        DevicePartHasOperation,
        'haso',
        'haso.part = part.id',
      )
      .leftJoinAndMapMany(
        'part.operation',
        DevicePartOperation,
        'operation',
        'haso.operation = operation.id',
      )
      .andWhere('haso.del_flag=0 and operation.del_flag=0')
      .getOne();
  }
  // 无需分页
  // async paging(paging: PaginationDTO) {
  //   const res: any = await this.deviceParts
  //     .createQueryBuilder('part')
  //     .andWhere({
  //       delFlag: 0,
  //     })
  //     .skip((paging.currentPage - 1) * paging.pageSize)
  //     .take(paging.pageSize)
  //     .getManyAndCount();
  //   return {
  //     data: res[0],
  //     total: res[1],
  //   };
  // }

  /**
   *  删除部件
   * @param id
   * @returns
   */
  async remove(id: number) {
    await this.deviceParts.update(id, { delFlag: 1 });
    await this.devicePartHasOperation.delete({ part: id });
    // await this.deviceParts.update(item.id, { delFlag: 1 });
    return true;
  }
  async removeByDevice(deviceId: number) {
    const deviceHasPart = await this.deviceParts.find({
      where: { device: deviceId },
    });
    for (let ind = 0; ind < deviceHasPart.length; ind++) {
      const partx = deviceHasPart[ind];
      await this.devicePartHasOperation.delete({
        part: partx.id,
      });
      await this.deviceParts.delete({ id: partx.id });
    }
    return 0;
  }
  // /**
  //  *  批量删除部件
  //  * @param id
  //  * @returns
  //  */
  // async removeAll(ids: number[]) {
  //   await this.deviceParts.update(ids, { delFlag: 1 });
  //   // await this.deviceParts.update(item.id, { delFlag: 1 });
  //   return true;
  // }
}

export class CreatePartDto extends CreateDto {
  @ApiProperty({ description: '设备Id' })
  @IsNotEmpty({ message: '设备Id不能为空' })
  device: number;

  @ApiProperty({ description: '部件名称' })
  @IsNotEmpty({ message: '部件名称不能为空' })
  @MaxLength(30, { message: '部件名称不能超过30个字符' })
  name: string;

  @ApiProperty({ description: '部件键值' })
  @IsNotEmpty({ message: '部件键值不能为空' })
  @MaxLength(30, { message: '键值不能超过30个字符' })
  keycode: string;

  @ApiProperty({ description: '部件说明' })
  @IsNotEmpty({ message: '部件说明不能为空' })
  @MaxLength(200, { message: '部件说明不能超过200个字符' })
  comment: string;

  @ApiProperty({ description: '部件状态列表', default: [{ id: 1 }] })
  operation?: Array<{ id: number }>;
}

export class UpdatePartDto extends CreateDto {
  @ApiProperty({ description: '设备Id' })
  device: number;

  @ApiProperty({ description: '部件名称' })
  @MaxLength(30, { message: '部件名称不能超过30个字符' })
  name: string;

  @ApiProperty({ description: '部件键值' })
  @MaxLength(30, { message: '键值不能超过30个字符' })
  keycode: string;

  @ApiProperty({ description: '部件说明' })
  @MaxLength(200, { message: '部件说明不能超过200个字符' })
  comment: string;

  @ApiProperty({ description: '部件状态列表', default: [{ id: 1 }] })
  operation?: Array<{ id: number }>;
}
