import {
  BadRequestException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { CreateGroupDto } from './dto/create-group.dto';
import { UpdateGroupDto } from './dto/update-group.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Group } from './entities/group.entity';
import { DataSource, EntityManager, Repository } from 'typeorm';
import { GroupsRepository } from './groups.repository';
import isValidUuidV4 from 'src/common/uuid validator/uuid-validate';
import { lan } from 'src/lan';
import { isEmpty } from 'src/common/helper';
import * as path from 'path';
import * as fs from 'fs';
import { AppUserRepository } from 'src/app_users/app_users.repository';
import { ProvincesRepository } from 'src/provinces/provinces.repository';
import { AppUsersService } from 'src/app_users/app_users.service';

@Injectable()
export class GroupsService {
  constructor(
    @InjectRepository(Group)
    private readonly groupEntity: Repository<Group>,
    private readonly groupsRepository: GroupsRepository,
    private readonly appUserRepository: AppUserRepository,
    private readonly provinceRepository: ProvincesRepository,
    private readonly appUserService: AppUsersService,
    private readonly connection: DataSource,
  ) {}

  async create(createGroupDto: CreateGroupDto) {
    if (createGroupDto.owner_id) {
      const data = await this.appUserRepository.findUserId(
        createGroupDto.owner_id,
      );

      if (isEmpty(data)) {
        throw new BadRequestException(lan('login.user_not_found'));
      }
    }

    if (createGroupDto.province_id) {
      const data = await this.provinceRepository.findById(
        createGroupDto.province_id,
      );

      if (isEmpty(data)) {
        throw new BadRequestException(lan('province_not_found'));
      }
    }

    const group: Group = new Group();
    Object.assign(group, createGroupDto);

    const returnData = await this.groupEntity.save(group);

    return returnData;
  }

  async findAllGroups(
    take: number,
    skip: number,
    search: string,
    headers: any,
  ) {
    return await this.groupsRepository.findAll(take, skip, search, headers);
  }

  async findGroup(id: string) {
    if (!isValidUuidV4(id)) {
      throw new BadRequestException(lan('common.invalid_uuid_format'));
    }

    const group = await this.groupsRepository.findOne(id, true);

    if (isEmpty(group)) {
      throw new NotFoundException(lan('common.data_not_found'));
    }

    return group;
  }

  async findAllGroupUser(
    id: string,
    take: number,
    skip: number,
    search: string,
  ) {
    return await this.groupsRepository.findGroupUser(id, take, skip, search);
  }

  async updateGroup(id: string, updateGroupDto: UpdateGroupDto) {
    if (!isValidUuidV4(id)) {
      throw new BadRequestException(lan('common.invalid_uuid_format'));
    }

    const group = await this.groupsRepository.findOneById(id);

    if (isEmpty(group)) {
      throw new NotFoundException(lan('common.data_not_found'));
    }

    Object.assign(group, updateGroupDto);

    return await this.groupEntity.update(id, group);
  }

  async removeGroup(id: string) {
    if (!isValidUuidV4(id)) {
      throw new BadRequestException(lan('common.invalid_uuid_format'));
    }

    const group = await this.groupsRepository.findOne(id, false);

    if (isEmpty(group)) {
      throw new NotFoundException(lan('common.data_not_found'));
    }

    if (group.icon) {
      const filePath = path.join(`public/${group.icon}`);

      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
      }
    }

    return this.groupEntity.softDelete(id);
  }
}
