<?php

namespace Application\Controller;

use Application\Common\StatusCode;
use Application\Form\FieldForm;
use Application\Form\FormForm;
use Application\Form\research\ContentForm;
use Application\Mvc\Controller\BasicController;
use Application\Service\DB\Dictionary\Form;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\FormFormatter;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Validator\FormValidator;
use Application\Service\Extension\Validator\ValidatorApplication;
use Application\Service\Logs;
use Exception;
use Laminas\Db\Sql\Expression;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Validator\Between;
use Laminas\Validator\Db\NoRecordExists;
use Laminas\Validator\Db\RecordExists;
use Laminas\Validator\Digits;
use Laminas\Validator\Exception\InvalidArgumentException;
use Laminas\Validator\GreaterThan;
use Laminas\Validator\InArray;
use Laminas\Validator\LessThan;
use Laminas\Validator\NotEmpty;
use Laminas\Validator\StringLength;
use Laminas\View\Model\JsonModel;
use Laminas\View\Model\ViewModel;


class FieldController extends BasicController
{
    /** @var string 表单字段配置key */
    public const FORM_VALIDATOR = 'itemFormField';

    public const LOG_TARGET = 'DictionaryFormField';
    /**
     * 字段列表
     * @doc https://www.showdoc.com.cn/p/e986fbe555c06367a9a8b96459908abd
     * @url http://xx.com/dictionary/form/field
     * @return JsonModel
     * @throws Exception
     */
    public function indexAction(): JsonModel
    {
        $validator = new ValidatorApplication();
        // TODO id验证
        $validator->attach(
            [['version', 'id'], 'required'],
        );
        if (!$validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $validator->getFirstErrorToString());
        }

        $data = $this->LocalService()->dictionaryFormVersion->getField([
            'form_id' => $validator->attributes['id'],
            'version' => $validator->attributes['version'],
        ]);

        return $this->RenderApiJson()->Success($data);
    }

    /**
     * 版本列表
     * @doc https://www.showdoc.com.cn/p/38faccc31ac49c9c8e0cc678bb6d56cd
     * @url http://xx.com/dictionary/field/version
     * @return JsonModel
     */
    public function versionAction(): JsonModel
    {
        $validator = new ValidatorApplication();
        $validator->attach(
            [['id'], 'required']
        );
        if (!$validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $validator->getFirstErrorToString());
        }

        // 获取所有版本
        // 新增无版本, 返回默认值
        $query = $this->LocalService()->dictionaryFormVersion->fetchAll([
            'columns' => ['version as label', 'version as value'],
            'where' => ['form_id' => $validator->attributes['id']]
        ]) ?: [['label' => 'v1.0', 'value' => 'v1.0']];

        return $this->RenderApiJson()->Success($query);
    }

    /**
     * 创建表单
     * @doc https://www.showdoc.com.cn/p/624d4f2f3c33f1e7b8e0f5adf6a2f776
     * @url http://xx.com/api/dictionary/field/create
     * @return JsonModel
     * @throws Exception
     */
    public function createAction(): JsonModel
    {
        $this->validator->attach(
            [['form_id'], 'required'],
            [['form_id'], 'exist', 'targetClass' => $this->LocalService()->dictionaryForm, 'targetAttribute' => 'id'], // 验证 form_id 是否存在
            [['form_type'], 'default', 'value' => FieldForm::FORM_CONFIG_TEXT],
            [['is_list', 'is_booked_time','is_hide','dicform_id'], 'default', 'value' => 0],
            [['is_export'], 'default', 'value' => 1],
            [['value'], 'function', 'targetClass' => FieldForm::class, 'method' => 'invalidRadioValue'],
            [['is_booked_time'], 'function', 'targetClass' => FieldForm::class, 'method' => 'invalidBookedTime']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        // 前端传的 `default` 字段可能会有前缀, 需要处理一下
        $default = 'default' . $this->validator->attributes['type'];
        if (isset($this->validator->attributes[$default])) {
            $this->validator->attributes['default'] = $this->validator->attributes[$default];
        }

        if(isset($this->validator->attributes['checkname_id'])){
            if(is_array($this->validator->attributes['checkname_id'])){
                $this->validator->attributes['checkname_id'] = !empty($this->validator->attributes['checkname_id']) ? implode(',',$this->validator->attributes['checkname_id']) : '';
            }else{
                $this->validator->attributes['checkname_id'] = !empty($this->validator->attributes['checkname_id']) ? trim($this->validator->attributes['checkname_id'],',') : '';
            }
        }
        //选项无关联信息时，关联分类、关联类型默认为空值
        if(isset($this->validator->attributes['relation_information']) && empty($this->validator->attributes['relation_information'])){
            $this->validator->attributes['relation_classification'] = 0;
            $this->validator->attributes['relation_type'] = 0;
        }
        
        $model = new FieldForm($this->validator);
        if ($this->validator->attributes['id']) {
            //先验证是否可以修改
            $model->editCheck();
            //查询选项值 判断本次是否修改了表单选项的字典项 如果修改了 提示先去删除旧的选项值  再进行修改
            $childen_count = $this->LocalService()->dictionaryFormField->getCount([
                'is_del' => 0,
                'parent' => $this->validator->attributes['id'],
            ]);
            $oldform_id = $this->LocalService()->dictionaryFormField->getOneFieldVal('dicform_id',[
                'id' => $this->validator->attributes['id'],
            ]);
            $oldform_id = !empty($oldform_id) ? $oldform_id : 0;
            if($childen_count > 0 && $this->validator->attributes['dicform_id'] != $oldform_id){
                return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '请先删除旧的选项值再进行修改选项字典！');
            }

            $model->editField();
            //处理选项值
            if($childen_count == 0 && isset($this->validator->attributes['dicform_id']) && !empty($this->validator->attributes['dicform_id'])){
                //查询对应的选项值
                $where_value = [
                    'where'=> [
                        'is_del' => 0,
                        'form_id' => $this->validator->attributes['dicform_id'],
                    ],
                    'columns'=>['id','value_name','option_value','option_variable','is_score','score_value']
                ];
                $value_datas = $this->LocalService()->dictionaryLevervalue->fetchAll($where_value);
                if(!empty($value_datas)){
                    $i = 1;
                    foreach ($value_datas as $value_data){
                        $i++;
                        $res =[
                            'parent'    => $this->validator->attributes['id'],
                            'name'      => $value_data['value_name'], //选项名称
                            'var_name'  => $value_data['option_variable'], //变量名
                            'value'     => $value_data['option_value'], //选项值
                            'is_check'  => 0, //是否默认选中
                            'is_score'  => $value_data['is_score'], //分值选项
                            'score'     => $value_data['score_value'], //分值
                            'form_id'   => $this->validator->attributes['form_id'],
                            'form_type' => 'RADIO', //分值选项
                            'version'   => $this->validator->attributes['version'],
                            'order'     => $i,
                        ];
                        //print_r($res);die;
                        //选项值入库
                        $newresult_id = $model->createField($res,1);
                        $this->LocalService()->log->saveFileLog(
                            $newresult_id,
                            self::LOG_TARGET . '.' . $this->validator->attributes['form_type'] . '.form',
                            $this->validator->attributes,
                            Logs::OPERATE_CREATE,
                            '创建字典项表单字段'
                        );
                    }
                }
            }
            $this->LocalService()->log->saveFileLog(
                $this->validator->attributes['id'],
                self::LOG_TARGET . '.' . $this->validator->attributes['form_type'] . '.form',
                $this->validator->attributes,
                Logs::OPERATE_EDIT,
                '编辑字典项表单字段'
            );
        } else {
            $result_id = $model->createField();
            $res = [];
            //判断是否选择了表单选项的字典项 选了的话 把选项值直接带过来保存到本次表单字段的子集中
            if(isset($this->validator->attributes['dicform_id']) && !empty($this->validator->attributes['dicform_id'])){
               //查询对应的选项值
                $where_value = [
                    'where'=> [
                        'is_del' => 0,
                        'form_id' => $this->validator->attributes['dicform_id'],
                    ],
                    'columns'=>['id','value_name','option_value','option_variable','is_score','score_value']
                ];
                $value_datas = $this->LocalService()->dictionaryLevervalue->fetchAll($where_value);

                if(!empty($value_datas)){
                    $i = 1;
                    foreach ($value_datas as $value_data){
                        $i++;
                        $res =[
                            'parent'    => $result_id,
                            'name'      => $value_data['value_name'], //选项名称
                            'var_name'  => $value_data['option_variable'], //变量名
                            'value'     => $value_data['option_value'], //选项值
                            'is_check'  => 0, //是否默认选中
                            'is_score'  => $value_data['is_score'], //分值选项
                            'score'     => $value_data['score_value'], //分值
                            'form_id'   => $this->validator->attributes['form_id'],
                            'form_type' => 'RADIO', //分值选项
                            'version'   => $this->validator->attributes['version'],
                            'order'     => $i,
                        ];
                        //print_r($res);die;
                        //选项值入库
                        $newresult_id = $model->createField($res,1);
                        $this->LocalService()->log->saveFileLog(
                            $newresult_id,
                            self::LOG_TARGET . '.' . $this->validator->attributes['form_type'] . '.form',
                            $this->validator->attributes,
                            Logs::OPERATE_CREATE,
                            '创建字典项表单字段'
                        );
                    }
                }
            }
            $this->LocalService()->log->saveFileLog(
                $result_id,
                self::LOG_TARGET . '.' . $this->validator->attributes['form_type'] . '.form',
                $this->validator->attributes,
                Logs::OPERATE_CREATE,
                '创建字典项表单字段'
            );
        }

        return $this->RenderApiJson()->Success();
    }

    /**
     * Notes: 处理旧的研究分层的字段数据  手写 和系统分配的默认显示字段
     * @param
     * @return
     * @author haojinhua
     * @date 2025-02-24
     */
    public function setolddataAction(){
        //查询所有小项目id
        $item_ids = $this->LocalService()->itemInfo->fetchCol('id','is_del= 0 and fid > 0');
        //查询所有小项目中的随机分组类型的表单
        $randomgroup_id = $this->LocalService()->dictionaryFormGroup->getOneFieldVal('id', 'is_del = 0 and code = "RDG"');
        //查询所有随机分组的表单
        $form_ids = $this->LocalService()->itemForm->fetchCol('id',[
            'is_del' => 0,
            'group_id' => $randomgroup_id,
            'item_id' => StringHelper::toArray($item_ids),
        ]);
       //字段id信息
        $form_filed_infos = $this->LocalService()->itemFormField->fetchAll([
            'where' => [
                'is_del' => 0,
                'form_id' => StringHelper::toArray($form_ids),
                'type' => 12
            ],
            'columns'=>['id','form_id']
        ]);
        if(!empty($form_filed_infos)){
            foreach ($form_filed_infos as $form_filed_info){
                $var_name = $form_filed_info['var_name'];
                if(in_array($var_name,['RANDOM_GROUP_CUSTOM', 'RANGC'])){
                    //手写随机分组
                    $show_name = '随机号';
                }else{
                    //系统分配
                    $show_name = '随机号/方案分组';
                }
                //修改随机号字段名称信息及缓存表
                $this->LocalService()->itemFormField->updateField($form_filed_info['id'], 'showfiled_name', $show_name);
                $v = $this->LocalService()->itemForm->buildFieldVersion($form_filed_info['form_id']);
                $this->LocalService()->itemFormVersion->update(['field' => $v], ['form_id' => $form_filed_info['form_id']]);
            }
            echo "处理完成！";die;
        }
    }

    /**
     * Notes:处理itemFormVersion 表中历史数据增加是否隐私字段的值
     * @param
     * @return
     * @author haojinhua
     * @date 2025-03-31
     */
    public function setversiondataAction(){
        //查询所有小项目id
        $item_ids = $this->LocalService()->itemInfo->fetchCol('id','is_del= 0 and fid > 0');
        //查询所有小项目中的常规识别类型的表单
        $gcogroup_id = $this->LocalService()->dictionaryFormGroup->getOneFieldVal('id', 'is_del = 0 and code = "GCO"');
        //查询所有随机分组的表单
        $form_ids = $this->LocalService()->itemForm->fetchCol('id',[
            'is_del' => 0,
            'group_id' => $gcogroup_id,
            'item_id' => StringHelper::toArray($item_ids),
        ]);

        foreach ($form_ids as $form_id){
            $v = $this->LocalService()->itemForm->buildFieldVersion($form_id);
        }

        echo "处理完成！";die;
    }

    /**
     * 添加版本
     * @doc https://www.showdoc.com.cn/p/28696c346fb0381c8b38250b30929375
     * @url http://xx.com/dictionary/field/addVersion
     * @return JsonModel
     * @throws Exception
     */
    public function addVersionAction(): JsonModel
    {
        $validator = new ValidatorApplication();
        $validator->attach(
            [['version', 'form_id'], 'class' => new NotEmpty(), 'message' => fn($attr) => "{$attr}不能为空"]
        );

        if (!$validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, current($validator->getErrors()));
        }

        $form = [
            'version' => $validator->attributes['version'],
            'field' => '[]',
            'form_id' => $validator->attributes['form_id'],
        ];

        $query = $this->LocalService()->dictionaryFormVersion->fetchOne([
            'where' => [
                'version' => $validator->attributes['version'],
                'form_id' => $validator->attributes['form_id']
            ]
        ]);

        if ($query) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '版本号重复啦~~');
        }

        $this->LocalService()->dictionaryFormVersion->insert($form);

        return $this->RenderApiJson()->Success();
    }

    /**
     * 表单详情
     * @doc https://www.showdoc.com.cn/p/45af2714da57a616fcb21b118c25fa98
     * @url http://xx.com/dictionary/field/view
     * @return JsonModel
     * @throws Exception
     */
    public function viewAction(): JsonModel
    {
        $validator = new ValidatorApplication();
        $validator->attach(
            [['id', 'form_type', 'form_id'], 'required', 'strict' => true], // 验证参数是否为 null
            [['form_id'], 'integer'], // 验证 form_id 是否为整数
            [['form_id'], 'exist', 'targetClass' => $this->LocalService()->dictionaryForm, 'targetAttribute' => 'id'] // 验证 form_id 是否存在
        );

        if (!$validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $validator->getFirstErrorToString());
        }

        $model = new FieldForm($validator);

        $query = $model->view() ?: ['order' => $this->getOrder()];

        return $this->RenderApiJson()->Success($query, 'OK', [
            'FormFileData' => $model->getFieldConfig(),
        ]);
    }


    /**
     * 获取order
     * @return int
     */
    protected function getOrder(): int
    {
        return ($this->LocalService()->dictionaryFormField->getCount(['form_id' => $this->validator->attributes['form_id']]) + 1) * 10;
    }

    /**
     * @param string $type
     * @param string $validatorName
     * @return mixed
     */
    protected function getFieldConfig(string $type = '', string $validatorName = 'DictionaryFormField')
    {
        $config = include Laminas::$app->getConfig()['formValidator'][$validatorName];

        $default = FieldForm::FORM_CONFIG_TEXT;

        if ($type) {
            $default = $type;
        }

        $formType = $this->LocalService()->dictionaryForm->fetchOne(['where' => ['id' => $this->validator->attributes['form_id']]])['type'];

        if ($formType == Form::FORM_TYPE_SINGLE) {
            unset($config[$default]['form']['is_list']);
        }

        $config[$default]['form'] = array_values($config[$default]['form'] ?? []);

        return $config[$default];
    }

    /**
     * 删除字段
     * @doc https://www.showdoc.com.cn/p/6c88b2eada517628bfdc3ba0d87ce931
     * @url http://xx.com/dictionary/field/del
     * @return JsonModel
     * @throws Exception
     */
    public function delAction(): JsonModel
    {
        $this->validator->attach(
            [['id'], 'required'],
            [['id'], 'function', 'targetClass' => FieldForm::class, 'method' => 'invalidDeleteId']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        $model = new FieldForm($this->validator);
        $model->delete();

        $this->LocalService()->log->saveFileLog($this->validator->attributes['id'], self::LOG_TARGET, $this->validator->attributes, Logs::OPERATE_DELETE, '删除字段');
        return $this->RenderApiJson()->Success();
    }

    public function getRelationInformationAction()
    {
        $this->validator->attach(
            [['type'], 'required'],
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        if ($this->validator->attributes['type'] == 0) {
            return $this->RenderApiJson()->Success([
                ['label' => '无关联信息', 'value' => '0']
            ]);
        } elseif ($this->validator->attributes['type'] == 1) { // 表单
            $query = $this->LocalService()->dictionaryForm->fetchAll([
                'columns' => [ new Expression('name as label'),new Expression('id as value')],
                'where' => ['is_del' => 0]
            ]);

            return $this->RenderApiJson()->Success($query);
        } elseif ($this->validator->attributes['type'] == 2) { // 属性
            $query = Laminas::$serviceManager->dictionaryFormVersion->getField([
                'form_id' => $this->validator->attributes['form_id'],
                'version' => 'v1.0'
            ], true);

            $options[] = ['label' => '无关联信息', 'value' => '0'];
            foreach ($query as $v) {
                $options[] = ['label' => $v['name'], 'value' => $v['id']];
            }

            return $this->RenderApiJson()->Success($options);
        }
    }
}
