<?php
declare (strict_types = 1);

namespace app\admin\validate\v1;

use app\admin\model\v1\SysConfigModel;
use think\Validate;

class SysConfigValidate extends Validate
{
    /**
     * 定义验证规则
     * 格式：'字段名' =>  ['规则1','规则2'...]
     *
     * @var array
     */
    protected $rule = [
        'id'       => 'require|integer',
        'group_id' => 'require|integer',
        'title'    => 'require|max:64',
        'name'     => 'require|unique:sys_config,group_id^name|max:64',
        'value'    => 'max:5120',
        'extra'    => 'max:5120|checkLinkage',
        'type'     => 'max:64',
        'sort'     => 'integer',
        'remark'   => 'max:255'
    ];

    /**
     * 定义错误信息
     * 格式：'字段名.规则名' =>  '错误信息'
     *
     * @var array
     */
    protected $message = [
        'id.require'       => 'ID不能为空',
        'id.integer'       => 'ID必须是整数',
        'group_id.require' => '分组ID不能为空',
        'group_id.integer' => '分组ID必须是整数',
        'title.require'    => '标题不能为空',
        'title.max'        => '标题最多不能超过64个字符',
        'name.require'     => '标识不能为空',
        'name.unique'      => '标识已存在',
        'name.max'         => '名称最多不能超过64个字符',
        'value.max'        => '值最多不能超过5120个字符',
        'extra.max'        => '额外信息最多不能超过5120个字符',
        'type.max'         => '类型最多不能超过64个字符',
        'sort.integer'     => '排序必须是整数',
        'remark.max'       => '备注最多不能超过255个字符',
    ];

    // 新增场景
    public function sceneAdd()
    {
        return $this->remove('id', 'require|integer');
    }

    // 验证额外配置项中联动数据配置
    protected function checkLinkage($value, $rule, $data)
    {
        if (empty($value)) {
            return true;
        }

        $submit_linkage_names = [];
        $submit_extra         = explode(PHP_EOL, $value);
        foreach ($submit_extra as $v) {
            if (preg_match('/^([^:]+):(.*?)(?:\[(.*?)\])?$/i', trim($v), $match)) {
                if (isset($match[3])) {
                    $submit_linkage_names = array_merge($submit_linkage_names, array_map(function ($it) {
                        return str_replace(['"', "'"], '', trim($it));
                    }, explode(',', $match[3])));
                }
            }
        }

        $configs_extra  = SysConfigModel::whereNotNull('extra')
            ->where('extra', '<>', '')
            ->where(function($query) use($data) {
                if (isset($data['id'])) {
                    $query->where('id', '<>', $data['id']);
                }
            })
            ->column('extra');
        $exists_linkage_names = [];
        foreach ($configs_extra as $it) {
            $exists_extra = explode(PHP_EOL, $it);
            foreach ($exists_extra as $v) {
                if (preg_match('/^([^:]+):(.*?)(?:\[(.*?)\])?$/i', trim($v), $match)) {
                    if (isset($match[3])) {
                        $exists_linkage_names = array_merge($exists_linkage_names, array_map(function ($it) {
                            return str_replace(['"', "'"], '', trim($it));
                        }, explode(',', $match[3])));
                    }
                }
            }
        }

        $intersect = array_intersect($submit_linkage_names, $exists_linkage_names);
        if (!empty($intersect)) {
            $v = implode(',', $intersect);
            return "{$v}被多次设为联动配置项";
        }
        
        return true;
    }
}
