<?php

require_once __DIR__ . '/../core/AbstractPdo.php';

class StudentService extends AbstractPdo
{
    protected $table = 'student';
    protected $primaryKey = 'id';

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Authenticate admin user with encrypted password
     */
    public function login($email, $password)
    {
        // Check if admin exists with this email
        $sql = "SELECT * FROM {$this->table} WHERE email = :email OR cin = :email";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['email' => $email]);
        $student = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$student) {
            return [
                'success' => false,
                'message' => 'Cin ou mot de passe incorrect'
            ];
        }

        // Check if account is blocked
        if ($student['blocked'] == 1) {
            return [
                'success' => false,
                'message' => 'Votre compte est bloqué. Veuillez contacter l\'administrateur.'
            ];
        }

        // Verify password using password_verify()
        if (!password_verify($password, $student['password'])) {
            // Increment failed login attempts
            $this->incrementFailedAttempts($student['id']);

            // Check if should be blocked (3 failed attempts)
            $sql = "SELECT cnx_fail_number FROM {$this->table} WHERE id = :id";
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute(['id' => $student['id']]);
            $failCount = $stmt->fetch(PDO::FETCH_ASSOC)['cnx_fail_number'];

            if ($failCount >= 3) {
                $this->blockStudent($student['id']);
                return [
                    'success' => false,
                    'message' => 'Trop de tentatives échouées. Votre compte a été bloqué.'
                ];
            }

            return [
                'success' => false,
                'message' => 'Email ou mot de passe incorrect. Tentative ' . $failCount . '/3'
            ];
        }

        // Login successful - reset failed attempts
        $this->resetFailedAttempts($student['id']);

        // Return admin data (without password)
        unset($student['password']);

        return [
            'success' => true,
            'data' => $student,
            'message' => 'Login successful'
        ];
        return $student;
    }


    /**
     * Update admin password with encryption
     */
    public function updatePassword($studentId, $newPassword)
    {
        $hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);

        $sql = "UPDATE student SET password = :password WHERE id = :id";
        $stmt = $this->pdo->prepare($sql);
        $result = $stmt->execute([
            'password' => $hashedPassword,
            'id' => $studentId
        ]);

        if ($result) {
            return ['success' => true, 'message' => 'Mot de passe mis à jour avec succès'];
        }
        return ['success' => false, 'message' => 'Erreur lors de la mise à jour'];
    }

    /**
     * Reset admin password (admin initiated)
     */
    public function resetPassword($email, $newPassword)
    {
        // Verify email exists
        $sql = "SELECT id FROM {$this->table} WHERE email = :email";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['email' => $email]);
        $student = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$student) {
            return ['success' => false, 'message' => 'Email non trouvé'];
        }

        return $this->updatePassword($student['id'], $newPassword);
    }

    /**
     * Check password strength
     */
    public function validatePasswordStrength($password)
    {
        $errors = [];

        if (strlen($password) < 8) {
            $errors[] = 'Le mot de passe doit contenir au moins 8 caractères';
        }
        if (!preg_match('/[A-Z]/', $password)) {
            $errors[] = 'Le mot de passe doit contenir au moins une majuscule';
        }
        if (!preg_match('/[a-z]/', $password)) {
            $errors[] = 'Le mot de passe doit contenir au moins une minuscule';
        }
        if (!preg_match('/[0-9]/', $password)) {
            $errors[] = 'Le mot de passe doit contenir au moins un chiffre';
        }
        if (!preg_match('/[!@#$%^&*(),.?":{}|<>]/', $password)) {
            $errors[] = 'Le mot de passe doit contenir au moins un caractère spécial';
        }

        return [
            'valid' => empty($errors),
            'errors' => $errors
        ];
    }


    /**
     * Increment failed login attempts
     */
    private function incrementFailedAttempts($studentId)
    {
        $sql = "UPDATE {$this->table} SET cnx_fail_number = cnx_fail_number + 1 WHERE id = :id";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['id' => $studentId]);
    }

    /**
     * Reset failed login attempts
     */
    private function resetFailedAttempts($studentId)
    {
        $sql = "UPDATE {$this->table} SET cnx_fail_number = 0 WHERE id = :id";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['id' => $studentId]);
    }

    /**
     * Block admin account
     */
    private function blockStudent($studentId)
    {
        $sql = "UPDATE {$this->table} SET blocked = 1 WHERE id = :id";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['id' => $studentId]);
    }

    /**
     * Unblock admin account
     */
    public function unblockStudent($studentId)
    {
        $sql = "UPDATE {$this->table} SET blocked = 0, cnx_fail_number = 0 WHERE id = :id";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['id' => $studentId]);
        return ['success' => true, 'message' => 'Compte débloqué avec succès'];
    }

    /**
     * Get admin by ID
     */
    public function getStudentById($id)
    {
        $sql = "SELECT id, email, nom, prenom, cin, phone FROM {$this->table} WHERE id = :id";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['id' => $id]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    }


    /**
     * Get students with search criteria
     */
    public function search($searchData, $page = 1, $perPage = 10)
    {
        $filters = [];
        $searchFields = ['nom', 'prenom', 'email', 'cin', 'phone'];

        foreach ($searchFields as $field) {
            if (!empty($searchData[$field])) {
                $filters[$field] = [
                    'value' => $searchData[$field],
                    'like' => true
                ];
            }
        }

        $offset = ($page - 1) * $perPage;
        $students = $this->findMultiple($filters, 'id DESC', $perPage, $offset);
        $total = $this->count($filters);

        return [
            'data' => $students,
            'total' => $total,
            'page' => $page,
            'perPage' => $perPage,
            'totalPages' => ceil($total / $perPage)
        ];
    }

    /**
     * Get student by ID
     */
    public function getStudent($id)
    {
        return $this->findOne($id);
    }

    /**
     * Create a new student
     */
  public function createStudent($data)
{

    if(
        empty($data['password'])
    ){

        $data['password'] = password_hash(
            "12345678",
            PASSWORD_DEFAULT
        );


    }else{


        $data['password'] =
        password_hash(
            $data['password'],
            PASSWORD_DEFAULT
        );

    }


    return $this->insert($data);

}

    /**
     * Update a student
     */
   public function updateStudent($id, $data)
{

    // ===============================
    // CHANGEMENT PASSWORD
    // ===============================

    if(
        !empty($data['new_password'])
    ){

        $sql = "SELECT password 
                FROM student 
                WHERE id = :id";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute([
            'id'=>$id
        ]);

        $student = $stmt->fetch(PDO::FETCH_ASSOC);


        if(!$student){

            return [
                'success'=>false,
                'message'=>'Etudiant introuvable'
            ];

        }



        // Vérifier ancien mot de passe

        if(
            !password_verify(
                $data['current_password'],
                $student['password']
            )
        ){

            return [
                'success'=>false,
                'message'=>'Mot de passe actuel incorrect'
            ];

        }




        // Vérifier confirmation

        if(
            $data['new_password']
            !==
            $data['confirm_password']
        ){

            return [
                'success'=>false,
                'message'=>'La confirmation du mot de passe est incorrecte'
            ];

        }




        // Vérifier sécurité password

        $check =
        $this->validatePasswordStrength(
            $data['new_password']
        );


        if(!$check['valid']){

            return [
                'success'=>false,
                'message'=>implode(
                    "\n",
                    $check['errors']
                )
            ];

        }




        $hashed =
        password_hash(
            $data['new_password'],
            PASSWORD_DEFAULT
        );



        $sql =
        "UPDATE student 
         SET password=:password 
         WHERE id=:id";


        $stmt=$this->pdo->prepare($sql);


        $stmt->execute([

            'password'=>$hashed,

            'id'=>$id

        ]);

    }





    // ===============================
    // INFORMATIONS
    // ===============================


    unset($data['current_password']);
    unset($data['new_password']);
    unset($data['confirm_password']);



    if(!empty($data)){


        $this->update(
            $id,
            $data
        );

    }



    return [
        'success'=>true,
        'message'=>'Etudiant modifié avec succès'
    ];

}
    /**
     * Delete a student
     */
    public function deleteStudent($id)
    {
        return $this->delete($id);
    }

    /**
     * Check student inscriptions and determine redirect URL
     */
    public function checkStudentInscriptions($studentId)
    {
        try {
            // Get count of inscriptions for this student
            $sql = "SELECT COUNT(*) as total FROM inscriptions WHERE student_id = ? AND active = 1";
            $stmt = $this->db->prepare($sql);
            $stmt->execute([$studentId]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            $count = $result['total'] ?? 0;

            // Get student info
            $studentSql = "SELECT id, cin, email, nom, prenom FROM students WHERE id = ?";
            $studentStmt = $this->db->prepare($studentSql);
            $studentStmt->execute([$studentId]);
            $student = $studentStmt->fetch(PDO::FETCH_ASSOC);

            // Determine redirect URL based on count
            $redirectUrl = '';
            if ($count == 0) {
                // No inscriptions - go to create page
                $redirectUrl = '/est-concours/app/view/student/inscription/create/index.php';
            } elseif ($count == 1) {
                // One inscription - go to create page with existing data
                // Get the inscription ID
                $insSql = "SELECT id FROM inscriptions WHERE student_id = ? AND active = 1 LIMIT 1";
                $insStmt = $this->db->prepare($insSql);
                $insStmt->execute([$studentId]);
                $inscription = $insStmt->fetch(PDO::FETCH_ASSOC);
                $redirectUrl = '/est-concours/app/view/student/inscription/create/index.php?id=' . ($inscription['id'] ?? '');
            } else {
                // Multiple inscriptions - go to list page
                $redirectUrl = '/est-concours/app/view/student/inscription/list/index.php';
            }

            return [
                'inscription_count' => $count,
                'redirect_url' => $redirectUrl,
                'student' => $student
            ];
        } catch (Exception $e) {
            error_log('Error checking student inscriptions: ' . $e->getMessage());
            return [
                'inscription_count' => 0,
                'redirect_url' => '/est-concours/app/view/student/inscription/create/index.php',
                'student' => null
            ];
        }
    }


    /**
     * Mot de passe oublié :
     * - Cherche l'étudiant par CIN
     * - Génère un nouveau mot de passe aléatoire
     * - Le crypte et met à jour la base de données
     * - Envoie le nouveau mot de passe par email
     */
    public function forgotPassword($cin)
    {
        // 1. Chercher l'étudiant par CIN
        $sql = "SELECT id, email, nom, prenom FROM {$this->table} WHERE cin = :cin";
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['cin' => $cin]);
        $student = $stmt->fetch(PDO::FETCH_ASSOC);

        // 2. CIN non trouvé → retourner une erreur
        if (!$student) {
            return [
                'success' => false,
                'message' => 'Aucun compte trouvé avec cet Email.'
            ];
        }

        // 3. Générer un nouveau mot de passe aléatoire (8 caractères)
        $newPassword = $this->generatePassword();

        // 4. Crypter le mot de passe avec password_hash()
        $hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);

        // 5. Mettre à jour le mot de passe dans la base de données
        $sqlUpdate = "UPDATE {$this->table} SET password = :password WHERE id = :id";
        $stmtUpdate = $this->pdo->prepare($sqlUpdate);
        $stmtUpdate->execute([
            'password' => $hashedPassword,
            'id' => $student['id']
        ]);

        // 6. Envoyer l'email avec le nouveau mot de passe
        $emailEnvoye = $this->sendPasswordEmail(
            $student['email'],
            $student['prenom'] . ' ' . $student['nom'],
            $newPassword
        );

        // 7. Retourner la réponse avec le nouveau mot de passe (affiché aussi à l'écran)
        if ($emailEnvoye) {
            return [
                'success' => true,
                'message' => 'Un email a été envoyé à ' . $student['email'] . ' avec votre nouveau mot de passe.',
                'new_password' => $newPassword
            ];
        } else {
            // Email échoué (normal en local) → on affiche le mot de passe à l'écran
            return [
                'success' => true,
                'message' => 'Mot de passe réinitialisé avec succès. (Email non envoyé en local, notez le mot de passe ci-dessous)',
                'new_password' => $newPassword
            ];
        }
    }

    /**
     * Génère un mot de passe aléatoire de 8 caractères
     * Contient : lettres majuscules, minuscules et chiffres
     */
    private function generatePassword($length = 8)
    {
        $chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789';
        $password = '';
        $max = strlen($chars) - 1;
        for ($i = 0; $i < $length; $i++) {
            $password .= $chars[random_int(0, $max)];
        }
        return $password;
    }

    /**
     * Envoie un email avec le nouveau mot de passe
     * Utilise la fonction mail() native de PHP
     * (Fonctionne en production avec un serveur mail configuré)
     */

    private function sendPasswordEmail($email, $fullName, $newPassword)
    {
        $subject = 'Réinitialisation de votre mot de passe - EST Concours';

        $message = "Bonjour $fullName,\r\n\r\n"
            . "Votre mot de passe a été réinitialisé avec succès.\r\n\r\n"
            . "Votre nouveau mot de passe : $newPassword\r\n\r\n"
            . "Connectez-vous sur : http://localhost/est-concours/app/cnx/student/login/\r\n\r\n"
            . "Nous vous conseillons de changer ce mot de passe après votre connexion.\r\n\r\n"
            . "Cordialement,\r\n"
            . "L'équipe EST Concours";

        $headers = "From: noreply@est-concours.ma\r\n";
        $headers .= "Reply-To: noreply@est-concours.ma\r\n";
        $headers .= "Content-Type: text/plain; charset=UTF-8\r\n";

        return mail($email, $subject, $message, $headers);
    }
    public function updateStudentWithPassword($id, $data) {
        $currentStudent = $this->findOne($id);

        // إذا كان المستخدم بغى يغير الباسورد
        if (!empty($data['new_password'])) {
            // تأكد واش الباسورد القديم صحيح
            if (empty($data['current_password']) || !password_verify($data['current_password'], $currentStudent['password'])) {
                return ['success' => false, 'message' => 'Mot de passe actuel incorrect ou vide'];
            }
            // تأكد من تطابق الجديد
            if ($data['new_password'] !== $data['confirm_password']) {
                return ['success' => false, 'message' => 'Les nouveaux mots de passe ne correspondent pas'];
            }
            // تشفير الباسورد الجديد
            $data['password'] = password_hash($data['new_password'], PASSWORD_DEFAULT);
        }

        // حذف الحقول اللي ما كايناش فالداتابيز باش ما يوقعش خطأ فالـ SQL
        unset($data['current_password'], $data['new_password'], $data['confirm_password']);

        // تحديث البيانات
        $result = $this->update($id, $data);
        return ['success' => (bool)$result, 'message' => $result ? 'Mise à jour réussie' : 'Erreur lors de la mise à jour'];
    }

}

?>
