<?php

namespace app\service;

use app\model\Permission;
use think\facade\Log;

/**
 * 数据隔离服务
 */
class DataIsolation
{
    /**
     * 构建数据隔离WHERE子句
     *
     * @param Permission $permission 权限记录
     * @param string $endpoint 接口标识 chuku/ruku
     * @param string|null $customerName 客户名称（全量数据权限时可选）
     * @return array ['sql' => string, 'params' => array]
     * @throws \Exception
     */
    public static function buildIsolationClause($permission, $endpoint, $customerName = null)
    {
        // 1. 检查接口权限
        if ($endpoint === 'chuku' && !$permission->canAccess('chuku')) {
            throw new \Exception('该 API Key 未被授权访问销售数据接口');
        }
        if ($endpoint === 'ruku' && !$permission->canAccess('ruku')) {
            throw new \Exception('该 API Key 未被授权访问入库数据接口');
        }

        // 2. 全量数据权限：检查是否传入供方名称过滤
        if ($permission->isFullData()) {
            Log::debug("API Key {$permission->api_key_id} 拥有全量数据权限");
            
            if (!empty($customerName)) {
                $filterField = 'k.[供方全称]';
                $sqlFragment = " AND {$filterField} LIKE :supplier_name";
                $params = ['supplier_name' => '%' . $customerName . '%'];
                Log::debug("全量数据模式下按供方名称过滤: {$filterField} LIKE %{$customerName}%");
                return ['sql' => $sqlFragment, 'params' => $params];
            }
            
            return ['sql' => '', 'params' => []];
        }

        // 3. 根据数据模式确定过滤方式
        $dataMode = $permission->data_mode;

        if ($dataMode === Permission::MODE_FULL) {
            return ['sql' => '', 'params' => []];
        }

        // 4. 使用数据库中已配置的过滤规则
        if (!empty($permission->filter_field) && !empty($permission->filter_values)) {
            return self::buildCustomFilter($permission, $endpoint);
        }

        // 5. 自动过滤：根据接口类型自动选择过滤字段和值
        $apiKey = $permission->apiKey;
        $client = $apiKey->client;

        if (!$client) {
            throw new \Exception('API Key 未关联客户');
        }

        return self::buildAutoFilter($permission, $endpoint, $client);
    }

    /**
     * 构建自定义过滤规则
     */
    private static function buildCustomFilter($permission, $endpoint)
    {
        $filterField = $permission->filter_field;
        $filterValues = $permission->filter_values;

        if (empty($filterField) || empty($filterValues)) {
            Log::warning("API Key {$permission->api_key_id} 使用自定义模式，但未配置过滤规则，拒绝访问");
            throw new \Exception('权限配置不完整：需要手动配置过滤字段和过滤值');
        }

        if (!is_array($filterValues)) {
            $filterValues = json_decode($filterValues, true);
        }

        if ($filterValues === null || !is_array($filterValues) || empty($filterValues)) {
            Log::warning("API Key {$permission->api_key_id} 过滤值为空或无效");
            throw new \Exception('过滤值列表为空或无效，请联系管理员');
        }

        if (!self::validateFilterField($filterField, $endpoint)) {
            throw new \Exception('非法的过滤字段');
        }

        $prefixedField = self::prefixFilterField($filterField, $endpoint);

        $placeholders = [];
        $params = [];
        foreach ($filterValues as $index => $value) {
            $placeholder = ':iso_' . $index;
            $placeholders[] = $placeholder;
            $params['iso_' . $index] = $value;
        }

        $sqlFragment = " AND {$prefixedField} IN (" . implode(',', $placeholders) . ')';
        Log::debug("数据隔离: {$prefixedField} IN " . json_encode($filterValues));

        return ['sql' => $sqlFragment, 'params' => $params];
    }

    /**
     * 为过滤字段添加表别名前缀
     */
    private static function prefixFilterField($field, $endpoint)
    {
        if (strpos($field, '[') === 0) {
            $field = substr($field, 1, -1);
        }
        
        $prefixMap = [
            '供方全称' => 'k.[供方全称]',
            '供方序号' => 'k.[供方序号]',
            '产品名称' => 'p.[产品名称]',
            '产品序号' => 'p.[产品序号]',
        ];
        
        if ($endpoint === 'chuku') {
            $prefixMap['销方全称'] = 'f.[销方全称]';
            $prefixMap['销方序号'] = 'f.[销方序号]';
        }
        
        return $prefixMap[$field] ?? "[{$field}]";
    }

    /**
     * 构建自动过滤规则
     */
    private static function buildAutoFilter($permission, $endpoint, $client)
    {
        $filterField = 'k.[供方全称]';

        $filterValue = $client->name;
        $sqlFragment = " AND {$filterField} = :iso_0";
        $params = ['iso_0' => $filterValue];

        Log::debug("数据隔离: {$filterField} = {$filterValue}");

        return ['sql' => $sqlFragment, 'params' => $params];
    }

    /**
     * 验证过滤字段是否在白名单内（防注入）
     */
    private static function validateFilterField($field, $endpoint)
    {
        $allowedFields = [
            '供方全称', '供方序号',
            '产品名称', '产品序号',
            'customer_name', 'supplier_name', 'customer_code', 'supplier_code',
        ];
        
        if ($endpoint === 'chuku') {
            $allowedFields = array_merge($allowedFields, ['销方全称', '销方序号']);
        }
        
        return in_array($field, $allowedFields);
    }
}