<?php
namespace App\Controllers;

use App\Core\Controller;
use App\Models\ReferralModel;
use App\Models\UserModel;

class AuthController extends Controller
{
    private function denyIfUnauthorized(): bool
    {
        return false;
    }

    public function login(): void
    {
        if ($this->denyIfUnauthorized()) {
            $loginUsername = (string)(flash('login_username') ?? '');
            view('auth/login', [
                'title' => app_zh('登录'),
                'layout' => 'auth',
                'auth_blocked' => true,
                'login_username' => $loginUsername,
                'login_math' => app_login_math_payload($loginUsername),
            ]);
            return;
        }

        if ($this->user) {
            redirect('dashboard');
        }

        $loginUsername = (string)(flash('login_username') ?? '');
        view('auth/login', [
            'title' => app_zh('登录'),
            'layout' => 'auth',
            'auth_blocked' => false,
            'login_username' => $loginUsername,
            'login_math' => app_login_math_payload($loginUsername),
        ]);
    }

    public function loginPost(): void
    {
        if ($this->denyIfUnauthorized()) {
            redirect('login');
        }

        if (!verify_csrf()) {
            flash('error', app_zh('安全验证失败'));
            redirect('login');
        }

        $input = app_request_data();
        $username = app_clean_text((string)($input['username'] ?? ''), 64);
        $password = (string)($input['password'] ?? '');
        $mathAnswer = app_clean_text((string)($input['math_answer'] ?? ''), 32);
        flash('login_username', $username);

        if (!app_login_math_verify($username, $mathAnswer)) {
            app_login_math_increment_failure($username);
            app_log_security_event('web_login_math_failed', [
                'username' => $username,
                'ip' => app_client_ip(),
            ]);
            flash('error', app_zh('计算题校验失败，请重试'));
            redirect('login');
        }

        $rate = app_rate_limit_consume('web_login_post', 15, 600, app_client_ip() . '|' . strtolower($username));
        if (!empty($rate['limited'])) {
            app_log_security_event('web_login_rate_limited', [
                'username' => $username,
            ]);
            flash('error', app_zh('登录请求过于频繁，请') . (string)($rate['retry_after'] ?? 60) . app_zh('秒后再试'));
            redirect('login');
        }
        $user = (new UserModel())->findByUsername($username);

        if (!$user || $user['status'] !== 'active' || !verify_password($password, (string)$user['password_hash'])) {
            $failCount = app_login_math_increment_failure($username);
            app_log_security_event('web_login_failed', [
                'username' => $username,
                'ip' => app_client_ip(),
                'fail_count' => $failCount,
            ]);
            $message = app_zh('账号或密码错误');
            if ($failCount >= app_login_math_threshold()) {
                app_login_math_payload($username);
                $message .= app_zh('，已触发计算题验证');
            }
            flash('error', $message);
            redirect('login');
        }

        app_login_math_reset_failures($username);
        session_regenerate_id(true);
        $_SESSION['user_id'] = $user['id'];
        unset($_SESSION['_login_math']);
        app_log_audit_event('web_login_success', [
            'user_id' => (int)$user['id'],
            'username' => $username,
        ]);
        flash('success', app_zh('登录成功'));
        redirect('dashboard');
    }

    public function register(): void
    {
        if ($this->denyIfUnauthorized()) {
            redirect('login');
        }

        if ($this->user) {
            redirect('dashboard');
        }

        view('auth/register', ['title' => app_zh('注册'), 'layout' => 'auth']);
    }

    public function registerPost(): void
    {
        if ($this->denyIfUnauthorized()) {
            redirect('login');
        }

        if (!verify_csrf()) {
            flash('error', app_zh('安全验证失败'));
            redirect('register');
        }

        $input = app_request_data();
        $username = app_clean_text((string)($input['username'] ?? ''), 64);
        $password = (string)($input['password'] ?? '');
        $password2 = (string)($input['password2'] ?? '');
        $referralRaw = app_clean_text((string)($input['referral'] ?? ''), 128);
        $rate = app_rate_limit_consume('web_register_post', 8, 900, app_client_ip());
        if (!empty($rate['limited'])) {
            flash('error', app_zh('注册请求过于频繁，请') . (string)($rate['retry_after'] ?? 60) . app_zh('秒后再试'));
            redirect('register');
        }

        if ($username === '' || strlen($username) < 4 || $password === '' || strlen($password) < 6 || $password !== $password2 || $referralRaw === '') {
            flash('error', app_zh('请检查账号、密码和推荐码'));
            redirect('register');
        }

        $userModel = new UserModel();
        if ($userModel->findByUsername($username)) {
            flash('error', app_zh('账号已存在'));
            redirect('register');
        }

        $refModel = new ReferralModel();
        if (preg_match('/^[a-fA-F0-9]{64}$/', $referralRaw)) {
            $refHash = strtolower($referralRaw);
        } else {
            $refHash = hash('sha256', strtoupper($referralRaw));
        }

        $code = $refModel->findByCodeHash($refHash);
        if (!$code || $code['used_by']) {
            flash('error', app_zh('推荐码无效或已使用'));
            redirect('register');
        }

        $userId = $userModel->create([
            'username' => $username,
            'password_hash' => create_password($password),
            'role' => 'reseller',
            'status' => 'active',
            'balance' => $code['set_balance'],
            'uplink_id' => $code['created_by'],
        ]);

        $refModel->markUsed((int)$code['id'], $userId);
        app_log_audit_event('web_register_success', [
            'user_id' => $userId,
            'username' => $username,
        ]);

        flash('success', app_zh('注册成功，请登录'));
        redirect('login');
    }

    public function logout(): void
    {
        if (!verify_csrf()) {
            flash('error', app_zh('安全验证失败'));
            redirect('login');
        }
        app_destroy_session();
        redirect('login');
    }
}
