<?php

declare (strict_types = 1);

namespace MyApp\Model;

use MyApp\Entity\Compte;
use MyApp\Entity\Role;
use PDO;

class Compte_Model
{
    private PDO $db;

    public function __construct(PDO $db)
    {
        $this->db = $db;
    }

    // on récup toutes les enregistrements de la BDD
    public function getAllCompte(): array
    {
        $sql = "SELECT Compte.*, Role.* FROM Compte JOIN Role ON Role.Id_role = Compte.Id_role";
        $stmt = $this->db->query($sql); // contient l'ensemble des résultats
        $compte = [];
        // on organise sous forme d'un tableau les valeurs récupérées
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

            $role = null;
            if ($row['Id_role'] !== null) {
                $role = new Role($row['Id_role'], $row['Nom_role']);
            }
            $compte[] = new Compte($row['Id_compte'], $row['Nom'], $row['Prenom'], $row['Num_telephone'], $row['Mail'], $row['Mot_de_passe'], $role);
        }

        return $compte;
    }
    // méthode pour récuperer un enregistrement
    public function getOneCompte(int $id): ?Compte
    {
        $sql = "SELECT Compte.*, Role.* FROM Compte JOIN Role ON Role.Id_role = Compte.Id_role where Id_compte = :id";
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(":id", $id);
        $stmt->execute();
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$row) {
            return null;
        }
        $role = null;
        if ($row['Id_role'] !== null) {
            $role = new Role($row['Id_role'], $row['Nom_role']);
        }
        return new Compte($row['Id_compte'], $row['Nom'], $row['Prenom'], $row['Num_telephone'], $row['Mail'], $row['Mot_de_passe'], $role);
    }

    // récupéré des enregistrements en fonction d'une recherche
    public function getSearchCompte(?string $search): array
    {
        $sql = "SELECT Compte.*, Role.* FROM Compte JOIN Role ON Role.Id_role = Compte.Id_role where Nom = :nom OR Prenom = :prenom OR Num_telephone = :num_telephone OR Mail = :mail OR Mot_de_passe = :mot_de_passe OR Role.Id_role = :id_role";
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(":nom", $search);
        $stmt->bindValue(":prenom", $search);
        $stmt->bindValue(":num_telephone", $search);
        $stmt->bindValue(":mail", $search);
        $stmt->bindValue(":mot_de_passe", $search);
        $stmt->bindValue(":id_role", $search);
        $stmt->execute();
        $compte = [];
        // on organise sous forme d'un tableau les valeurs récupérées
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

            $role = null;
            if ($row['Id_role'] !== null) {
                $role = new Role($row['Id_role'], $row['Nom_role']);
            }
            $compte[] = new Compte($row['Id_compte'], $row['Nom'], $row['Prenom'], $row['Num_telephone'], $row['Mail'], $row['Mot_de_passe'], $role);
        }
        if ($search === '' || $search === null) {
            return $this->getAllCompte();
        } else {
            return $compte;
        }
    }

    // méthode pour ajout erun enregistrement à la table compte
    public function createCompte(Compte $compte): bool
    {
        $sql = "INSERT INTO Compte (Id_compte, Nom, Prenom, Num_telephone, Mail, Mot_de_passe, Id_role) VALUES (:Id_compte, :Nom, :Prenom, :Num_telephone, :Mail, :Mot_de_passe, :Id_role)";
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(':Id_compte', $compte->getId(), PDO::PARAM_STR);
        $stmt->bindValue(':Nom', $compte->getNom(), PDO::PARAM_STR);
        $stmt->bindValue(':Prenom', $compte->getPrenom(), PDO::PARAM_STR);
        $stmt->bindValue(':Num_telephone', $compte->getNum_telephone(), PDO::PARAM_STR);
        $stmt->bindValue(':Mail', $compte->getMail(), PDO::PARAM_STR);

        // Hacher le mot de passe avant de l'insérer dans la base de données
        $mot_de_passe_hache = password_hash($compte->getMot_de_passe(), PASSWORD_DEFAULT);
        $stmt->bindValue(':Mot_de_passe', $mot_de_passe_hache, PDO::PARAM_STR);

        $stmt->bindValue(':Id_role', $compte->getId_role()->getId_role(), PDO::PARAM_STR);
        return $stmt->execute();
    }

    // suppprimer un enregistrement d'un compte
    public function deleteCompte(int $id): bool
    {
        $sql = "DELETE Compte, Reservation FROM Compte
                LEFT JOIN Reservation ON Compte.Id_compte = Reservation.Id_compte
                WHERE Compte.Id_compte = :id";
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(':id', $id, PDO::PARAM_INT);
        return $stmt->execute();

    }

    public function updateCompte(Compte $compte): bool
    {
        $sql = "UPDATE Compte
        SET Id_compte = :Id_compte,
            Nom = :Nom,
            Prenom = :Prenom,
            Num_telephone = :Num_telephone,
            Mail = :Mail,
            Mot_de_passe = :Mot_de_passe,
            Id_role = :Id_role
        WHERE Id_compte = :Id_compte";

        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(':Id_compte', $compte->getId(), PDO::PARAM_STR);
        $stmt->bindValue(':Nom', $compte->getNom(), PDO::PARAM_STR);
        $stmt->bindValue(':Prenom', $compte->getPrenom(), PDO::PARAM_STR);
        $stmt->bindValue(':Num_telephone', $compte->getNum_telephone(), PDO::PARAM_STR);
        $stmt->bindValue(':Mail', $compte->getMail(), PDO::PARAM_STR);
        $stmt->bindValue(':Mot_de_passe', $compte->getMot_de_passe(), PDO::PARAM_STR);
        $stmt->bindValue(':Id_role', $compte->getId_role()->getId_role(), PDO::PARAM_STR);
        return $stmt->execute();
    }

    public function getCompteByMail(string $mail): ?Compte
    {
        $sql = "SELECT Compte.*, Role.* FROM Compte JOIN Role ON Role.Id_role = Compte.Id_role WHERE Mail = :mail";
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(':mail', $mail); // Utilisation de ':mail' au lieu de ':Mail'
        $stmt->execute();
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$row) {
            return null;
        }
        $role = null;
        if ($row['Id_role'] !== null) {
            $role = new Role($row['Id_role'], $row['Nom_role']);
        }
        return new Compte($row['Id_compte'], $row['Nom'], $row['Prenom'], $row['Num_telephone'], $row['Mail'], $row['Mot_de_passe'], $role);
    }

}
