<?php
declare(strict_types=1);

namespace app\dice\helper;

use app\dice\model\player\DicePlayer;
use plugin\saiadmin\app\model\system\SystemUser;
use plugin\saiadmin\exception\ApiException;

/**
 * 大富翁数据范围：按渠道 dept_id 隔离（关联 sa_system_dept）
 */
class AdminScopeHelper
{
    /** 超管查看默认配置模板 */
    public const DEFAULT_TEMPLATE_DEPT = 0;

    /**
     * 当前管理员所属渠道 ID；超级管理员(id=1) 返回 null 表示不限制
     */
    public static function getDeptId(?array $adminInfo): ?int
    {
        if (empty($adminInfo) || !isset($adminInfo['id'])) {
            return null;
        }
        $adminId = (int) $adminInfo['id'];
        if ($adminId <= 1) {
            return null;
        }
        $deptList = $adminInfo['deptList'] ?? [];
        if (!empty($deptList['id'])) {
            return (int) $deptList['id'];
        }
        if (!empty($adminInfo['dept_id'])) {
            return (int) $adminInfo['dept_id'];
        }
        return 0;
    }

    public static function isSuperAdmin(?array $adminInfo): bool
    {
        return !empty($adminInfo['id']) && (int) $adminInfo['id'] <= 1;
    }

    /**
     * 解析配置类接口的渠道 ID（请求参数 dept_id）
     * 超管：0 或空=默认模板(null)；>0=指定渠道
     * 普通管理员：固定本渠道
     */
    public static function resolveConfigDeptId(?array $adminInfo, $requestDeptId): int
    {
        $scopeDeptId = self::getDeptId($adminInfo);
        if ($scopeDeptId !== null) {
            return $scopeDeptId > 0 ? $scopeDeptId : self::DEFAULT_TEMPLATE_DEPT;
        }
        if ($requestDeptId === null || $requestDeptId === '') {
            return self::DEFAULT_TEMPLATE_DEPT;
        }
        $id = (int) $requestDeptId;
        if ($id === self::DEFAULT_TEMPLATE_DEPT) {
            return self::DEFAULT_TEMPLATE_DEPT;
        }
        return $id > 0 ? $id : self::DEFAULT_TEMPLATE_DEPT;
    }

    public static function isTemplateDeptId($deptId): bool
    {
        return $deptId === null || $deptId === '' || (int) $deptId === self::DEFAULT_TEMPLATE_DEPT;
    }

    /**
     * 同渠道下可访问的管理员 ID
     *
     * @return int[]|null null=不限制
     */
    public static function getAllowedAdminIds(?array $adminInfo): ?array
    {
        if (empty($adminInfo) || !isset($adminInfo['id'])) {
            return [];
        }
        $adminId = (int) $adminInfo['id'];
        if ($adminId <= 1) {
            return null;
        }
        $deptId = self::getDeptId($adminInfo);
        if ($deptId === null) {
            return null;
        }
        if ($deptId <= 0) {
            return [$adminId];
        }
        $ids = SystemUser::where('dept_id', $deptId)->column('id');
        return array_map('intval', $ids ?: [$adminId]);
    }

    public static function fillDeptId(array &$data, ?array $adminInfo, $requestDeptId = null): void
    {
        if (isset($data['dept_id']) && $data['dept_id'] !== '' && $data['dept_id'] !== null) {
            return;
        }
        $deptId = self::resolveConfigDeptId($adminInfo, $requestDeptId ?? ($data['filter_dept_id'] ?? null));
        if ($deptId > 0) {
            $data['dept_id'] = $deptId;
        } elseif (!isset($data['dept_id']) || self::isTemplateDeptId($data['dept_id'])) {
            $data['dept_id'] = self::DEFAULT_TEMPLATE_DEPT;
        }
    }

    /**
     * 业务数据新增：按渠道写入 dept_id（玩家、记录等）
     * 优先级：已有 dept_id → 所属管理员 admin_id → 请求渠道 → 当前登录人渠道
     */
    public static function fillBusinessDeptId(array &$data, ?array $adminInfo, $requestDeptId = null): void
    {
        if (isset($data['dept_id']) && $data['dept_id'] !== '' && $data['dept_id'] !== null) {
            $data['dept_id'] = (int) $data['dept_id'];
            if ($data['dept_id'] > 0) {
                return;
            }
        }

        if (!empty($data['player_id'])) {
            $playerDeptId = self::resolveDeptIdByPlayerId($data['player_id']);
            if ($playerDeptId !== null && $playerDeptId > 0) {
                $data['dept_id'] = $playerDeptId;
                return;
            }
        }

        if (!empty($data['admin_id'])) {
            $ownerDeptId = self::resolveDeptIdByAdminId($data['admin_id']);
            if ($ownerDeptId !== null && $ownerDeptId > 0) {
                $data['dept_id'] = $ownerDeptId;
                return;
            }
        }

        $deptId = self::resolveBusinessDeptId($adminInfo, $requestDeptId);
        if ($deptId !== null && $deptId > 0) {
            $data['dept_id'] = $deptId;
            return;
        }

        $scopeDeptId = self::getDeptId($adminInfo);
        if ($scopeDeptId !== null && $scopeDeptId > 0) {
            $data['dept_id'] = $scopeDeptId;
        }
    }

    /**
     * 业务新增：解析请求渠道并填充 dept_id，缺失时抛错
     */
    public static function prepareBusinessSaveData(
        array &$data,
        ?array $adminInfo,
        $inputDeptId = null,
        array $body = []
    ): void {
        $requestDeptId = self::pickRequestDeptId($inputDeptId, $body);
        self::fillBusinessDeptId($data, $adminInfo, $requestDeptId);
        self::assertBusinessDeptId($data);
    }

    /**
     * 配置新增：解析请求渠道并填充 dept_id
     */
    public static function prepareConfigSaveData(
        array &$data,
        ?array $adminInfo,
        $inputDeptId = null,
        array $body = []
    ): void {
        $requestDeptId = self::pickRequestDeptId($inputDeptId, $body);
        self::fillDeptId($data, $adminInfo, $requestDeptId);
    }

    /**
     * 业务表 dept_id 必须 > 0（非默认模板）
     */
    public static function assertBusinessDeptId(array $data): void
    {
        if (!isset($data['dept_id']) || $data['dept_id'] === '' || $data['dept_id'] === null) {
            throw new ApiException('CHANNEL_DEPT_ID_REQUIRED');
        }
        if ((int) $data['dept_id'] <= 0) {
            throw new ApiException('INVALID_CHANNEL_DEPT_ID');
        }
    }

    /**
     * 根据玩家 ID 解析所属渠道
     */
    public static function resolveDeptIdByPlayerId($playerId): ?int
    {
        if ($playerId === null || $playerId === '') {
            return null;
        }
        $player = DicePlayer::field('dept_id,admin_id')->find($playerId);
        if (!$player || $player->isEmpty()) {
            return null;
        }
        $deptId = $player->dept_id ?? null;
        if ($deptId !== null && $deptId !== '' && (int) $deptId > 0) {
            return (int) $deptId;
        }
        if (!empty($player->admin_id)) {
            return self::resolveDeptIdByAdminId($player->admin_id);
        }

        return null;
    }

    /**
     * 根据后台管理员 ID 解析所属渠道
     */
    public static function resolveDeptIdByAdminId($adminId): ?int
    {
        if ($adminId === null || $adminId === '') {
            return null;
        }
        $admin = SystemUser::find($adminId);
        if (!$admin || $admin->isEmpty()) {
            return null;
        }
        $deptId = $admin->dept_id ?? null;
        if ($deptId !== null && $deptId !== '' && (int) $deptId > 0) {
            return (int) $deptId;
        }

        return null;
    }

    /**
     * 规范化记录上的 dept_id（null 视为默认模板 0）
     */
    public static function normalizeRecordDeptId($recordDeptId): int
    {
        if ($recordDeptId === null || $recordDeptId === '') {
            return self::DEFAULT_TEMPLATE_DEPT;
        }
        return (int) $recordDeptId;
    }

    /**
     * 玩家端读取游戏配置时使用的渠道 ID（玩家 dept_id 优先，否则按所属管理员）
     */
    public static function resolvePlayerConfigDeptId($player): int
    {
        $deptId = null;
        $adminId = null;
        if (is_array($player)) {
            $deptId = $player['dept_id'] ?? null;
            $adminId = $player['admin_id'] ?? null;
        } elseif (is_object($player)) {
            $deptId = $player->dept_id ?? null;
            $adminId = $player->admin_id ?? null;
        }
        if ($deptId !== null && $deptId !== '' && (int) $deptId > 0) {
            return (int) $deptId;
        }
        if ($adminId !== null && $adminId !== '') {
            $fromAdmin = self::resolveDeptIdByAdminId($adminId);
            if ($fromAdmin !== null && $fromAdmin > 0) {
                return $fromAdmin;
            }
        }
        return self::DEFAULT_TEMPLATE_DEPT;
    }

    /**
     * 从请求参数或请求体中解析 dept_id（兼容 PUT JSON 仅出现在 body 的情况）
     */
    public static function pickRequestDeptId($inputDeptId, array $body = [])
    {
        if ($inputDeptId !== null && $inputDeptId !== '') {
            return $inputDeptId;
        }
        if (isset($body['dept_id']) && $body['dept_id'] !== '' && $body['dept_id'] !== null) {
            return $body['dept_id'];
        }
        return null;
    }

    public static function canAccessDept(?array $adminInfo, $recordDeptId, $requestDeptId = null): bool
    {
        $recordDeptId = self::normalizeRecordDeptId($recordDeptId);
        $scopeDeptId = self::getDeptId($adminInfo);
        if ($scopeDeptId === null) {
            if ($requestDeptId === null || $requestDeptId === '') {
                return true;
            }
            $target = self::resolveConfigDeptId($adminInfo, $requestDeptId);
            if (self::isTemplateDeptId($target)) {
                return self::isTemplateDeptId($recordDeptId);
            }
            return $recordDeptId === $target;
        }
        if ($recordDeptId === self::DEFAULT_TEMPLATE_DEPT && $scopeDeptId > 0) {
            return false;
        }
        return $recordDeptId === $scopeDeptId;
    }

    /**
     * 业务页渠道 ID：超管通过请求 dept_id 筛选；未传或 <=0 时不限制
     */
    public static function resolveBusinessDeptId(?array $adminInfo, $requestDeptId): ?int
    {
        $scopeDeptId = self::getDeptId($adminInfo);
        if ($scopeDeptId !== null) {
            return $scopeDeptId > 0 ? $scopeDeptId : null;
        }
        if ($requestDeptId === null || $requestDeptId === '') {
            return null;
        }
        $id = (int) $requestDeptId;
        return $id > 0 ? $id : null;
    }

    /**
     * 业务数据列表（玩家、记录、工作台等）
     */
    public static function applyAdminScope($query, ?array $adminInfo, $requestDeptId = null): void
    {
        if (self::getDeptId($adminInfo) === null) {
            $target = self::resolveBusinessDeptId($adminInfo, $requestDeptId);
            if ($target !== null && $target > 0) {
                $query->where('dept_id', $target);
            }
            return;
        }
        $deptId = self::getDeptId($adminInfo);
        if ($deptId <= 0) {
            $query->whereRaw('1=0');
            return;
        }
        $query->where('dept_id', $deptId);
    }

    /**
     * 配置类列表：超管按所选渠道/默认模板筛选
     */
    public static function applyConfigScope($query, ?array $adminInfo, $requestDeptId = null, string $deptColumn = 'dept_id'): void
    {
        $targetDeptId = self::resolveConfigDeptId($adminInfo, $requestDeptId);
        $scopeDeptId = self::getDeptId($adminInfo);

        if ($scopeDeptId !== null && !self::isSuperAdmin($adminInfo)) {
            if ($scopeDeptId <= 0) {
                $query->whereRaw('1=0');
                return;
            }
            $query->where($deptColumn, $scopeDeptId);
            return;
        }

        if (self::isTemplateDeptId($targetDeptId)) {
            $templateId = self::DEFAULT_TEMPLATE_DEPT;
            $query->where(function ($q) use ($templateId, $deptColumn) {
                $q->where($deptColumn, $templateId)->whereOr($deptColumn, null);
            });
            return;
        }
        $query->where($deptColumn, $targetDeptId);
    }
}
