<?php

require_once BASE_PATH . '/app/models/User.php';
require_once BASE_PATH . '/app/models/SystemSetting.php';
require_once BASE_PATH . '/app/models/RememberToken.php';
require_once BASE_PATH . '/app/helpers/SessionAuth.php';

class AuthController
{
    private User $userModel;
    private SystemSetting $systemSettingModel;

    public function __construct()
    {
        $this->userModel = new User();
        $this->systemSettingModel = new SystemSetting();
    }

    // ========================================================
    // LOGIN PAGE
    // ========================================================

   public function login(): void
{
    if (isset($_SESSION['user'])) {
        $this->redirectAfterLogin();
    }

    $errors = [];
    $old = [];


    /*
    |--------------------------------------------------------------------------
    | LẤY FLASH MESSAGE NGAY TẠI TRANG LOGIN
    |--------------------------------------------------------------------------
    */

    $successMessage =
        $_SESSION['flash_success']
        ?? null;

    $errorMessage =
        $_SESSION['flash_error']
        ?? null;


    /*
    * Sau khi lấy phải xóa ngay.
    * Không để message chạy sang trang Quên mật khẩu.
    */
    unset(
        $_SESSION['flash_success'],
        $_SESSION['flash_error']
    );


    require BASE_PATH
        . '/app/views/auth/login.php';
}

    // ========================================================
    // LOGIN SUBMIT
    // ========================================================

    public function loginSubmit(): void
    {
        $this->requirePost();
        $this->validateCsrf();

        $identifier = trim(
            $_POST['identifier'] ?? ''
        );

        $password =
            $_POST['password'] ?? '';

        $old = [
            'identifier' => $identifier
        ];

        $errors = [];

        if ($identifier === '') {
            $errors[] =
                'Vui lòng nhập email hoặc số điện thoại.';
        }

        if ($password === '') {
            $errors[] =
                'Vui lòng nhập mật khẩu.';
        }

        if (!empty($errors)) {

            require BASE_PATH
                . '/app/views/auth/login.php';

            return;
        }

        // Chuẩn hóa nếu người dùng nhập số điện thoại
        if (
            preg_match(
                '/^[+0-9\s.\-]+$/',
                $identifier
            )
        ) {
            $identifier =
                $this->normalizePhone(
                    $identifier
                );
        }

        $user =
            $this->userModel
                ->findByIdentifier(
                    $identifier
                );

        if (
            !$user
            || !password_verify(
                $password,
                $user['password_hash']
            )
        ) {

            $errors[] =
                'Thông tin đăng nhập không chính xác.';

            require BASE_PATH
                . '/app/views/auth/login.php';

            return;
        }

        if ($user['status'] !== 'active') {

            $errors[] =
                'Tài khoản hiện đang bị khóa.';

            require BASE_PATH
                . '/app/views/auth/login.php';

            return;
        }

        // Nâng thuật toán hash khi cần
        if (
            password_needs_rehash(
                $user['password_hash'],
                PASSWORD_DEFAULT
            )
        ) {

            $newHash =
                password_hash(
                    $password,
                    PASSWORD_DEFAULT
                );

            $this->userModel
                ->updatePasswordHash(
                    (int) $user['id'],
                    $newHash
                );
        }

        sign_in_user($user);

        $this->userModel
            ->updateLastLogin(
                (int) $user['id']
            );

        if (isset($_POST['remember'])) {
            (new RememberToken())->issue((int) $user['id']);
        }

        $this->redirectAfterLogin();
    }

    // ========================================================
    // REGISTER PAGE
    // ========================================================

    public function register(): void
    {
        if (isset($_SESSION['user'])) {
            $this->redirectAfterLogin();
        }

        $errors = [];
        $old = [];
        $registrationClosed = !$this->systemSettingModel->getBoolean(
            'registration_enabled',
            true
        );

        if ($registrationClosed) {
            $errors[] = 'Đăng ký tài khoản đang tạm đóng.';
        }

        require BASE_PATH
            . '/app/views/auth/register.php';
    }

    // ========================================================
    // REGISTER SUBMIT
    // ========================================================

    public function registerSubmit(): void
    {
        $this->requirePost();
        $this->validateCsrf();

        if (!$this->systemSettingModel->getBoolean(
            'registration_enabled',
            true
        )) {
            http_response_code(403);
            $errors = ['Đăng ký tài khoản đang tạm đóng.'];
            $old = [];
            $registrationClosed = true;

            require BASE_PATH
                . '/app/views/auth/register.php';

            return;
        }

        $fullName =
            trim(
                $_POST['full_name'] ?? ''
            );

        $phone =
            $this->normalizePhone(
                $_POST['phone'] ?? ''
            );

        $email =
            strtolower(
                trim(
                    $_POST['email'] ?? ''
                )
            );

        $password =
            $_POST['password'] ?? '';

        $passwordConfirmation =
            $_POST['password_confirmation']
            ?? '';

        $old = [
            'full_name' => $fullName,
            'phone' => $phone,
            'email' => $email
        ];

        $errors = [];

        // ====================================================
        // VALIDATE NAME
        // ====================================================

        if (mb_strlen($fullName) < 2) {
            $errors[] =
                'Họ tên phải có ít nhất 2 ký tự.';
        }

        if (mb_strlen($fullName) > 120) {
            $errors[] =
                'Họ tên quá dài.';
        }

        // ====================================================
        // PHONE
        // ====================================================

        if (
            !preg_match(
                '/^0[0-9]{9}$/',
                $phone
            )
        ) {

            $errors[] =
                'Số điện thoại phải gồm 10 số và bắt đầu bằng 0.';

        } elseif (
            $this->userModel
                ->phoneExists($phone)
        ) {

            $errors[] =
                'Số điện thoại đã được sử dụng.';
        }

        // ====================================================
// EMAIL REQUIRED
// ====================================================

if ($email === '') {

    $errors[] =
        'Vui lòng nhập email.';

} elseif (
    !filter_var(
        $email,
        FILTER_VALIDATE_EMAIL
    )
) {

    $errors[] =
        'Email không hợp lệ.';

} elseif (
    $this->userModel
        ->emailExists($email)
) {

    $errors[] =
        'Email đã được sử dụng.';
}

        // ====================================================
        // PASSWORD
        // ====================================================

        if (strlen($password) < 8) {
            $errors[] =
                'Mật khẩu phải có ít nhất 8 ký tự.';
        }

        if ($password !== $passwordConfirmation) {
            $errors[] =
                'Xác nhận mật khẩu không khớp.';
        }

        if (!empty($errors)) {

            require BASE_PATH
                . '/app/views/auth/register.php';

            return;
        }

        try {

            $userId =
                $this->userModel
                    ->createCustomer([
                        'full_name' =>
                            $fullName,

                        'phone' =>
                            $phone,

                        'email' => $email,

                        'password_hash' =>
                            password_hash(
                                $password,
                                PASSWORD_DEFAULT
                            )
                    ]);

        } catch (PDOException $e) {

            $errors[] =
                'Không thể tạo tài khoản. Email hoặc số điện thoại có thể đã tồn tại.';

            require BASE_PATH
                . '/app/views/auth/register.php';

            return;
        }

        $user =
            $this->userModel
                ->findById($userId);

        if (!$user) {
            throw new RuntimeException(
                'Không thể tải tài khoản vừa tạo.'
            );
        }

        // Đăng nhập ngay sau khi đăng ký
        sign_in_user($user);

        $this->userModel
            ->updateLastLogin($userId);

        $_SESSION['flash_success'] =
            'Tạo tài khoản thành công.';

        $this->redirectAfterLogin();
    }

    // ========================================================
    // LOGOUT
    // ========================================================

    public function logout(): void
    {
        $this->requirePost();
        $this->validateCsrf();

        (new RememberToken())->revokeRawCookie();

        unset(
            $_SESSION['user'],
            $_SESSION['redirect_after_login']
        );

        session_regenerate_id(true);

        $_SESSION['flash_success'] =
            'Bạn đã đăng xuất.';

        header(
            'Location: '
            . BASE_URL
            . '/'
        );

        exit;
    }

    // ========================================================
    // PHONE NORMALIZE
    // ========================================================

    private function normalizePhone(
        string $phone
    ): string {

        $phone =
            preg_replace(
                '/[\s.\-]/',
                '',
                trim($phone)
            );

        if (
            str_starts_with(
                $phone,
                '+84'
            )
        ) {

            $phone =
                '0'
                . substr(
                    $phone,
                    3
                );
        }

        return $phone;
    }

    // ========================================================
    // REDIRECT
    // ========================================================

    private function redirectAfterLogin(): never
    {
        $redirect =
            $_SESSION[
                'redirect_after_login'
            ]
            ?? null;

        unset(
            $_SESSION[
                'redirect_after_login'
            ]
        );

        // Chỉ cho redirect trong website của mình
        if (
            is_string($redirect)
            && str_starts_with(
                $redirect,
                BASE_URL
            )
        ) {

            header(
                'Location: '
                . $redirect
            );

            exit;
        }

        header(
            'Location: '
            . BASE_URL
            . (
                ($_SESSION['user']['role'] ?? null) === 'admin'
                    ? '/?url=admin'
                    : '/'
            )
        );

        exit;
    }

    // ========================================================
    // SECURITY
    // ========================================================

    private function requirePost(): void
    {
        if (
            $_SERVER[
                'REQUEST_METHOD'
            ] !== 'POST'
        ) {

            http_response_code(405);

            exit(
                'Method Not Allowed'
            );
        }
    }

    private function validateCsrf(): void
    {
        $token =
            $_POST['_token']
            ?? '';

        $sessionToken =
            $_SESSION['csrf_token']
            ?? '';

        if (
            $token === ''
            || $sessionToken === ''
            || !hash_equals(
                $sessionToken,
                $token
            )
        ) {

            http_response_code(403);

            exit(
                'Yêu cầu không hợp lệ.'
            );
        }
    }
}
