<?php
namespace App\Controllers\Admin;

use App\Controllers\Controller;
use App\Models\AdminUser;
use Core\App;

class AuthController extends Controller
{
    protected $layout = 'layouts/admin';

    public function login()
    {
        if (is_admin()) { $this->redirect(login_landing()); }
        $error = '';
        $blocked = false;
        $ip = $_SERVER['REMOTE_ADDR'] ?? '';
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            // 质量红线：登录必须校验 CSRF + 验证码 + IP 级双窗口限速（失败 10 分钟/5 次、成功 30 分钟/5 次），杜绝机器人暴力破解
            if (!csrf_check()) {
                $error = '表单已过期，请刷新页面后重试';
            } elseif (ip_login_blocked($ip)) {
                $error = '尝试次数过多，请 30 分钟后再试';
                $blocked = true;
            } elseif (!captcha_check($this->post('captcha'))) {
                $error = '验证码错误，请重新计算';
            } else {
                $u = trim($this->post('username'));
                $p = $this->post('password');
                $ok = false;
                $user = null;
                $found = (new AdminUser())->byUsername($u);
                if ($found && (int)($found['status'] ?? 1) === 1 && password_verify($p, $found['password'])) {
                    $ok = true; $user = $found;
                } elseif ($this->fallbackEnabled() && $u === \Core\App::config('admin.username') && $p === \Core\App::config('admin.password')) {
                    // 配置文件兜底账号：仅本地/演示模式开启（本地规则要求生产禁用默认密码后门）
                    $ok = true;
                    $user = ['id' => 0, 'username' => $u, 'name' => '管理员', 'role' => 'super_admin'];
                }
                if ($ok) {
                    ip_login_register_success($ip); // 记录成功登录（纳入 30 分钟 5 次上限），并重置失败计数
                    session_regenerate_id(true); // 防会话固定
                    $_SESSION['admin_logged'] = true;
                    $_SESSION['admin_id']     = $user['id'] ?? 0;
                    $_SESSION['admin_name']   = $user['name'] ?? $u;
                    $_SESSION['admin_role']   = $user['role'] ?? 'super_admin';
                    $_SESSION['crm_role']     = $user['crm_role']  ?? 'none';
                    $_SESSION['psi_role']     = $user['psi_role']  ?? 'none';
                    $dec = function ($v) { $a = @json_decode((string)$v, true); return is_array($a) ? $a : null; };
                    $_SESSION['crm_perms']    = $dec($user['crm_perms'] ?? null);
                    $_SESSION['psi_perms']    = $dec($user['psi_perms'] ?? null);
                    $this->redirect(login_landing());
                }
                ip_login_register_fail($ip); // 记录一次失败（纳入 10 分钟 5 次上限）
                $error = '用户名或密码错误';
            }
        }
        // 被限速（IP 失败/成功过多）时返回 429 + Retry-After，明确告知客户端稍后再试
        if ($blocked && !headers_sent()) {
            http_response_code(429);
            header('Retry-After: ' . ip_login_remaining($ip));
        }
        $captcha = captcha_make(); // 每次渲染都发放新的算术验证码
        return $this->view('admin/login', ['error' => $error, 'captcha' => $captcha]);
    }

    /** 配置文件兜底账号是否启用：生产（mysql 模式）默认关闭，本地演示可开 */
    private function fallbackEnabled(): bool
    {
        return (bool) \Core\App::config('admin.allow_config_fallback', false)
            && \Core\App::config('app.driver', 'file') !== 'mysql';
    }

    /** 修改当前登录账号的密码 */
    public function password()
    {
        admin_required();
        $error = '';
        $ok = '';
        $uid = admin_uid();
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!csrf_check()) {
                $error = '表单已过期，请重试';
            } else {
                $cur = $this->post('current_password');
                $new = $this->post('new_password');
                $confirm = $this->post('confirm_password');
                $m = new AdminUser();
                $me = $uid ? $m->find($uid) : null;
                if (!$me) {
                    $error = '账号异常，请重新登录';
                } elseif (!password_verify($cur, $me['password'])) {
                    $error = '当前密码不正确';
                } elseif (strlen($new) < 6) {
                    $error = '新密码至少 6 位';
                } elseif ($new !== $confirm) {
                    $error = '两次输入的密码不一致';
                } else {
                    $m->update($uid, ['password' => password_hash($new, PASSWORD_DEFAULT)]);
                    $ok = '密码修改成功';
                }
            }
        }
        return $this->view('admin/password', ['error' => $error, 'ok' => $ok]);
    }

    public function logout()
    {
        unset($_SESSION['admin_logged'], $_SESSION['admin_name'], $_SESSION['admin_id'], $_SESSION['admin_role'], $_SESSION['crm_role'], $_SESSION['psi_role'], $_SESSION['crm_perms'], $_SESSION['psi_perms']);
        $this->redirect('admin/login');
    }
}
