<?php
namespace App\Controllers\Subsys;

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

/**
 * 分系统用户管理（CRM/PSI 共用）。
 * 仅该系统管理员可访问：管理「属于本系统的用户」及其页面权限。
 * 普通用户仅能看到/访问自己被授权的页面（由 subsys_page_can 控制）。
 */
abstract class UsersController extends Controller
{
    /** 子类返回 'crm' | 'psi' */
    abstract protected function sys(): string;

    private function sysName(): string
    {
        return $this->sys() === 'psi' ? 'PSI 进销存' : 'CRM 客户管理';
    }

    private function nav(): array
    {
        return \subsys_nav($this->sys());
    }

    public function index()
    {
        $sys = $this->sys();
        $other = $sys === 'crm' ? 'psi' : 'crm';
        $col = $sys . '_role';
        $rows = Db::query("SELECT * FROM admin_users WHERE `{$col}` != 'none' ORDER BY id ASC")->fetchAll();
        // 子系统管理员仅管理「本系统的用户」，严格执行边界隔离：
        //  - 不可越权操作后台超管 / 全局管理员；
        //  - 不可跨界看到 / 管理另一系统（CRM 看不到 PSI，PSI 看不到 CRM）。
        if (admin_role() !== 'super_admin') {
            $rows = array_filter($rows, static function ($r) use ($other) {
                // 排除后台超管 / 全局管理员
                if (in_array($r['role'] ?? 'none', ['super_admin', 'admin'], true)) return false;
                // 排除另一系统的管理员（防跨界）
                if (($r[$other . '_role'] ?? 'none') === 'admin') return false;
                return true;
            });
        }
        return $this->renderSubsys($sys, 'subsys/users', [
            'users'   => $rows,
            'sysName' => $this->sysName(),
            'pages'   => \subsys_pages($sys),
            'sys'     => $sys,
        ], $this->nav(), 'users');
    }

    public function create()
    {
        $sys = $this->sys();
        $user = [
            'id' => 0, 'username' => '', 'name' => '', 'status' => 1,
            $sys . '_role'  => 'user',
            $sys . '_perms' => '',
        ];
        return $this->renderSubsys($sys, 'subsys/user_form', [
            'user'   => $user,
            'sysName'=> $this->sysName(),
            'pages'  => \subsys_pages($sys),
            'sys'    => $sys,
            'edit'   => false,
        ], $this->nav(), 'users');
    }

    public function store()
    {
        $sys = $this->sys();
        $upper = strtoupper($sys);
        if (!csrf_check()) {
            $this->flash('表单已过期，请重试', 'err');
            return $this->redirect($upper . '/users/create');
        }
        $username = trim($this->post('username'));
        $name     = trim($this->post('name'));
        $pwd      = $this->post('password');
        $role     = $this->post($sys . '_role') === 'admin' ? 'admin' : 'user';
        $perms    = $this->collectPerms($sys);
        $status   = $this->post('status') === '0' ? 0 : 1;

        if ($username === '' || $pwd === '') {
            $this->flash('用户名和密码不能为空', 'err');
            return $this->redirect($upper . '/users/create');
        }
        if (!preg_match('/^[a-zA-Z0-9_]{3,30}$/', $username)) {
            $this->flash('账号须为 3-30 位字母/数字/下划线', 'err');
            return $this->redirect($upper . '/users/create');
        }
        if (strlen($pwd) < 6) {
            $this->flash('密码至少 6 位', 'err');
            return $this->redirect($upper . '/users/create');
        }
        if ((new AdminUser())->byUsername($username)) {
            $this->flash('用户名已存在', 'err');
            return $this->redirect($upper . '/users/create');
        }

        (new AdminUser())->insert([
            'username'   => $username,
            'password'   => password_hash($pwd, PASSWORD_DEFAULT),
            'name'       => $name,
            'role'       => 'none',              // 子系统账号：全局后台角色为 none
            $sys . '_role'  => $role,
            $sys . '_perms' => json_encode($perms, JSON_UNESCAPED_UNICODE),
            'status'     => $status,
            'created_at' => date('Y-m-d H:i:s'),
        ]);
        $this->flash('用户已创建', 'ok');
        return $this->redirect($upper . '/users');
    }

    public function edit($id)
    {
        $sys = $this->sys();
        $user = (new AdminUser())->find($id);
        if (!$user || !$this->manageable($user)) {
            return $this->redirect(strtoupper($sys) . '/users');
        }
        return $this->renderSubsys($sys, 'subsys/user_form', [
            'user'   => $user,
            'sysName'=> $this->sysName(),
            'pages'  => \subsys_pages($sys),
            'sys'    => $sys,
            'edit'   => true,
        ], $this->nav(), 'users');
    }

    public function update($id)
    {
        $sys = $this->sys();
        $upper = strtoupper($sys);
        if (!csrf_check()) {
            $this->flash('表单已过期，请重试', 'err');
            return $this->redirect($upper . '/users');
        }
        $user = (new AdminUser())->find($id);
        if (!$user || !$this->manageable($user)) {
            $this->flash('无权操作该用户', 'err');
            return $this->redirect($upper . '/users');
        }
        $username = trim($this->post('username'));
        $name     = trim($this->post('name'));
        $pwd      = $this->post('password');
        $role     = $this->post($sys . '_role') === 'admin' ? 'admin' : 'user';
        $perms    = $this->collectPerms($sys);
        $status   = $this->post('status') === '0' ? 0 : 1;

        if ($username === '' || !preg_match('/^[a-zA-Z0-9_]{3,30}$/', $username)) {
            $this->flash('账号不合法', 'err');
            return $this->redirect($upper . '/users/edit/' . $id);
        }
        $existing = (new AdminUser())->byUsername($username);
        if ($existing && (int)$existing['id'] !== (int)$id) {
            $this->flash('用户名已存在', 'err');
            return $this->redirect($upper . '/users/edit/' . $id);
        }
        if ($pwd !== '' && strlen($pwd) < 6) {
            $this->flash('密码至少 6 位', 'err');
            return $this->redirect($upper . '/users/edit/' . $id);
        }

        $data = [
            'username'   => $username,
            'name'       => $name,
            $sys . '_role'  => $role,
            $sys . '_perms' => json_encode($perms, JSON_UNESCAPED_UNICODE),
            'status'     => $status,
        ];
        if ($pwd !== '') {
            $data['password'] = password_hash($pwd, PASSWORD_DEFAULT);
        }
        (new AdminUser())->update($id, $data);
        $this->flash('用户已更新', 'ok');
        return $this->redirect($upper . '/users');
    }

    public function destroy($id)
    {
        $sys = $this->sys();
        $upper = strtoupper($sys);
        if (!csrf_check()) {
            $this->flash('操作已失效，请重试', 'err');
            return $this->redirect($upper . '/users');
        }
        $user = (new AdminUser())->find($id);
        if (!$user || !$this->manageable($user) || (int)$user['id'] === (int)admin_uid()) {
            $this->flash('无法删除该用户', 'err');
            return $this->redirect($upper . '/users');
        }
        (new AdminUser())->delete($id);
        $this->flash('用户已删除', 'ok');
        return $this->redirect($upper . '/users');
    }

    /** 管理员为该用户重置密码 */
    public function reset($id)
    {
        $sys = $this->sys();
        $upper = strtoupper($sys);
        $user = (new AdminUser())->find($id);
        if (!$user || !$this->manageable($user)) {
            $this->flash('无权操作该用户', 'err');
            return $this->redirect($upper . '/users');
        }
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (!csrf_check()) {
                $this->flash('表单已过期，请重试', 'err');
                return $this->redirect($upper . '/users/reset/' . $id);
            }
            $pwd = $this->post('password');
            if ($pwd === '' || strlen($pwd) < 6) {
                $this->flash('密码至少 6 位', 'err');
                return $this->redirect($upper . '/users/reset/' . $id);
            }
            (new AdminUser())->update($id, ['password' => password_hash($pwd, PASSWORD_DEFAULT)]);
            $this->flash('密码已重置', 'ok');
            return $this->redirect($upper . '/users');
        }
        return $this->renderSubsys($sys, 'subsys/user_reset', [
            'user'   => $user,
            'sysName'=> $this->sysName(),
            'sys'    => $sys,
        ], $this->nav(), 'users');
    }

    /** 收集页面权限：返回 {page: bool} 形式（与后台 UserController 一致，登录时按 JSON 解码） */
    private function collectPerms(string $sys): array
    {
        $out = [];
        foreach (\subsys_pages($sys) as $p) {
            if ($p === 'dashboard') continue;
            $out[$p] = $this->post('perm_' . $p) ? true : false;
        }
        return $out;
    }

    /** 当前登录管理员是否可管理该目标用户（严格边界隔离：只管本系统用户，禁止跨界） */
    private function manageable(array $target): bool
    {
        if (admin_role() === 'super_admin') return true;
        $sys = $this->sys();
        $other = $sys === 'crm' ? 'psi' : 'crm';
        // 不能管理后台超管 / 全局管理员
        if (in_array($target['role'] ?? 'none', ['super_admin', 'admin'], true)) return false;
        // 只能管理本系统用户
        if (($target[$sys . '_role'] ?? 'none') === 'none') return false;
        // 不能跨界管理另一系统的管理员（CRM 管不了 PSI，PSI 管不了 CRM）
        if (($target[$other . '_role'] ?? 'none') === 'admin') return false;
        return true;
    }
}
