import {
  ConflictException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { RoleType, Users } from 'src/entities/users.entity';
import { CreateGestionnaireDto } from '../dto/create_gestionnaire.dto';
import { UpdateGestionnaireDto } from '../dto/update_gestionnaire.dto';
import * as bcrypt from 'bcrypt';

@Injectable()
export class GestionnairesService {
  constructor(
    @InjectRepository(Users)
    private readonly gestionnaireRepository: Repository<Users>,
  ) { }

  // Création d’un gestionnaire
  async create(dto: CreateGestionnaireDto): Promise<Users> {
    const exist = await this.gestionnaireRepository.findOneBy({ email: dto.email });
    if (exist) throw new ConflictException('Email déjà utilisé');

    const salt = await bcrypt.genSalt();
    const hashedPassword = await bcrypt.hash(dto.password, salt);

    const entity = this.gestionnaireRepository.create({
      email: dto.email,
      password: hashedPassword,
      prenom: dto.prenom,
      nom: dto.nom,
      genre: dto.genre,
      statut: dto.statut,
      telephone: dto.telephone,
      adresse: dto.adresse,
      photo_url: dto.photo_url,
      consentement_photo: dto.consentement_photo ?? false,
      date_consentement_photo: dto.date_consentement_photo
        ? new Date(dto.date_consentement_photo)
        : undefined,
      changement_mdp_obligatoire: dto.changement_mdp_obligatoire ?? false,
      role: RoleType.GESTIONNAIRE,
    });
    return this.gestionnaireRepository.save(entity);
  }

  // Liste des gestionnaires
  async findAll(): Promise<Users[]> {
    return this.gestionnaireRepository.find({ where: { role: RoleType.GESTIONNAIRE } });
  }

  // Récupérer un gestionnaire par ID
  async findOne(id: string): Promise<Users> {
    const gestionnaire = await this.gestionnaireRepository.findOne({
      where: { id, role: RoleType.GESTIONNAIRE },
    });
    if (!gestionnaire) throw new NotFoundException('Gestionnaire introuvable');
    return gestionnaire;
  }

  // Mise à jour d’un gestionnaire
  async update(id: string, dto: UpdateGestionnaireDto): Promise<Users> {
    const gestionnaire = await this.findOne(id);

    if (dto.password) {
      const salt = await bcrypt.genSalt();
      gestionnaire.password = await bcrypt.hash(dto.password, salt);
    }

    if (dto.date_consentement_photo !== undefined) {
      gestionnaire.date_consentement_photo = dto.date_consentement_photo
        ? new Date(dto.date_consentement_photo)
        : undefined;
    }

    const { password, date_consentement_photo, ...rest } = dto;
    Object.entries(rest).forEach(([key, value]) => {
      if (value !== undefined) {
        (gestionnaire as any)[key] = value;
      }
    });

    return this.gestionnaireRepository.save(gestionnaire);
  }

}
