<?php

require_once BASE_PATH . '/app/models/User.php';
require_once BASE_PATH . '/app/models/PasswordReset.php';
require_once BASE_PATH . '/app/models/ActivityLog.php';
require_once BASE_PATH . '/app/models/SystemSetting.php';
require_once BASE_PATH . '/app/models/RememberToken.php';

class ForgotPasswordController
{
    private User $userModel;
    private PasswordReset $passwordResetModel;

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

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

    if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
        $this->forgotSubmit();
        return;
    }

    $errors = [];
    require BASE_PATH . '/app/views/auth/forgot-password.php';
}

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

        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
            $this->resetSubmit();
            return;
        }

        $token = trim($_GET['token'] ?? '');
        $errors = [];
        require BASE_PATH . '/app/views/auth/reset-password.php';
    }

    private function forgotSubmit(): void
{
    $this->requirePost();
    $this->validateCsrf();


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


    /*
    |--------------------------------------------------------------------------
    | Kiểm tra Email
    |--------------------------------------------------------------------------
    */

    if (
        $email === ''
        ||
        !filter_var(
            $email,
            FILTER_VALIDATE_EMAIL
        )
    ) {

        $_SESSION['flash_error'] =
            'Vui lòng nhập địa chỉ email hợp lệ.';

        header(
            'Location: '
            . BASE_URL
            . '/?url=forgot-password'
        );

        exit;
    }


    try {

        /*
        |--------------------------------------------------------------------------
        | Tìm tài khoản
        |--------------------------------------------------------------------------
        */

        $user =
            $this->userModel
                ->findByEmail(
                    $email
                );


        if (!$user) {

            $_SESSION['flash_error'] =
                'Email này không tồn tại trong hệ thống.';

            header(
                'Location: '
                . BASE_URL
                . '/?url=forgot-password'
            );

            exit;
        }


        /*
        |--------------------------------------------------------------------------
        | Kiểm tra tài khoản
        |--------------------------------------------------------------------------
        */

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

            $_SESSION['flash_error'] =
                'Tài khoản này hiện không hoạt động.';

            header(
                'Location: '
                . BASE_URL
                . '/?url=forgot-password'
            );

            exit;
        }


        /*
        |--------------------------------------------------------------------------
        | LOCAL / DEBUG:
        | Nhập đúng email → tạo token → chuyển thẳng sang reset
        |--------------------------------------------------------------------------
        */

        if (
            ($GLOBALS['config']['debug'] ?? false)
            === true
        ) {

            $token =
                $this->passwordResetModel
                    ->createForUser(
                        (int) $user['id']
                    );


            header(
                'Location: '
                . BASE_URL
                . '/?url=reset-password&token='
                . urlencode($token)
            );

            exit;
        }


        /*
        |--------------------------------------------------------------------------
        | PRODUCTION
        |--------------------------------------------------------------------------
        |
        | Khi deploy thật, chỗ này phải gửi token vào Email.
        |--------------------------------------------------------------------------
        */

        $_SESSION['flash_error'] =
            'Chức năng đặt lại mật khẩu trực tiếp chỉ được phép ở môi trường thử nghiệm.';


    } catch (Throwable $e) {

        error_log(
            'Password reset request failed: '
            . $e->getMessage()
        );


        $_SESSION['flash_error'] =
            'Không thể xử lý yêu cầu lúc này. Vui lòng thử lại.';
    }


    header(
        'Location: '
        . BASE_URL
        . '/?url=forgot-password'
    );

    exit;
}

    private function resetSubmit(): void
    {
        $this->requirePost();
        $this->validateCsrf();

        $token = trim($_POST['token'] ?? '');
        $password = $_POST['password'] ?? '';
        $confirmation = $_POST['password_confirmation'] ?? '';

        if (strlen($password) < 8) {
            $this->resetError($token, 'Mật khẩu mới phải có ít nhất 8 ký tự.');
        }

        if ($password !== $confirmation) {
            $this->resetError($token, 'Xác nhận mật khẩu mới không khớp.');
        }

        $userId = $this->passwordResetModel->resetPassword(
            $token,
            password_hash($password, PASSWORD_DEFAULT)
        );

        if ($userId === null) {
            $this->resetError($token, 'Liên kết đặt lại mật khẩu không hợp lệ hoặc đã hết hạn.');
        }

        (new RememberToken())->revokeAllForUser($userId);

        $this->logResetCompleted($userId);
        $_SESSION['flash_success'] = 'Đặt lại mật khẩu thành công. Vui lòng đăng nhập.';
        header('Location: ' . BASE_URL . '/?url=login');
        exit;
    }

    private function logDevelopmentResetUrl(string $token): void
    {
        if (($GLOBALS['config']['debug'] ?? false) !== true) {
            return;
        }

        error_log(
            'DEV password reset URL: ' . BASE_URL
            . '/?url=reset-password&token=' . $token
        );
    }

    private function logResetCompleted(int $userId): void
    {
        try {
            $settings = new SystemSetting();
            if (!$settings->getBoolean('activity_logging_enabled', true)) {
                return;
            }

            (new ActivityLog())->create(
                $userId,
                'customer.password_reset.completed',
                'user',
                $userId,
                [],
                $_SERVER['REMOTE_ADDR'] ?? null,
                $_SERVER['HTTP_USER_AGENT'] ?? null
            );
        } catch (Throwable) {
            // Password reset is already complete; logging must not undo it.
        }
    }

    private function resetError(string $token, string $message): never
    {
        $_SESSION['flash_error'] = $message;
        header(
            'Location: ' . BASE_URL . '/?url=reset-password&token='
            . urlencode($token)
        );
        exit;
    }

    private function redirectLoggedInUser(): never
    {
        $route = ($_SESSION['user']['role'] ?? null) === 'customer'
            ? 'customer/profile'
            : 'home';
        header('Location: ' . BASE_URL . '/?url=' . $route);
        exit;
    }

    private function requirePost(): void
    {
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== '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ệ.');
        }
    }
}
