<?php

namespace Application\Service\Extension\Queue\jobs;

use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Helper\CurlHelper;
use Application\Service\Extension\Helper\LogHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Helper\SyncPatientHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Queue\BaseJob;
use Application\Service\Extension\Xml\FormContentXmlGenerator;
use Application\Service\Extension\Xml\PatientXmlGenerator;
use Application\Service\Extension\Xml\XmlBuilder;

/**
 * 同步受试者Job
 */
class SyncPatientFormJob extends BaseJob
{
    public int $patientId = 0;

    public string $itemSignId = '0';

    public int $itemId = 0;

    public int $formId = 0;

    public int $checkTimeId = 0;

    public bool $isSync = true;

    /**
     * 删除指定的表单id
     * 一对多才生效
     * @var int
     */
    public int $deleteMultiId = 0;

    public function execute(): \Closure
    {
        return function () {

            $startTime = microtime(true);

            $xmlGenerator = new FormContentXmlGenerator();

            $xmlGenerator->patientId = $this->patientId;

            $xmlGenerator->itemSignId = $this->itemSignId;

            $xmlGenerator->itemId = $this->itemId;

            $xmlGenerator->formId = $this->formId;

            $xmlGenerator->checkTimeId = $this->checkTimeId;

            if ($xmlGenerator->isSync() === false || $xmlGenerator->getFormContent('fetchOne', false) === false) {
                return;
            }

            $xmlGenerator->formContent = [];

            if ($this->deleteMultiId !== 0) {
                $xmlGenerator->deleteMultiId($this->deleteMultiId);
            }

            $xml = $xmlGenerator->generate();

            $builder = new XmlBuilder();

            $record = json_encode($builder->build($xml), JSON_UNESCAPED_SLASHES);

            $generateTime = microtime(true) - $startTime;

            $requestStartTime = microtime(true);

            if ($this->isSync === true) {
                $response = CurlHelper::syncArkEdc($record);

                $isJson = StringHelper::jsonDecode($response, false);

                // 对方没有给我返回一个JSON格式的数据
                if (!$isJson) {
                    LogHelper::save([
                        'msg' => '数据同步失败了, 好像那面报错了.',
                        'ODMResponseData' => $isJson,
                        'requestData' => $record,
                    ], 'ERROR', 'syncODMPatient[ERROR]');
                    return;
                }

                if ($isJson['statusCode'] != 200) {
                    LogHelper::save([
                        'msg' => '数据同步失败了, 返回不是200的状态码.',
                        'prop' => [
                            'itemId' => $xmlGenerator->itemId,
                            'patientId' => $xmlGenerator->patientId,
                            'formId' => $xmlGenerator->formId,
                            'checkTimeId' => $xmlGenerator->checkTimeId,
                        ],
                        'ODMResponseData' => $isJson,
                        'requestData' => $record,
                    ], 'WARNING', 'syncODMPatient[WARNING]');

                     // 根据返回的结果来生成出对应的sql,
                    if (stripos($isJson['message'], '无法重复添加') !== false) {
                        $syncField = json_encode($xmlGenerator->syncField ?: []);
                        $sqlStrFun = function ($multiID) use ($xmlGenerator, $syncField) {
                            return ("INSERT INTO `sdm_scitrials`.`yikeen_odm_sync_record_ark` (`sync_type`, `patient_id`, `item_id`, `item_sign_id`, `form_id`, `sync_field`, `is_del`, `checktime_id`, `multi_id`) VALUES (2, {$xmlGenerator->patientId}, {$xmlGenerator->itemId}, {$xmlGenerator->itemSignId}, {$xmlGenerator->formId}, '{$syncField}', 0, {$xmlGenerator->checkTimeId}, {$multiID});");
                        };

                        if (!$xmlGenerator->multiId) {
                            $sqlStr[] = $sqlStrFun(0);
                        }

                        if (is_array($xmlGenerator->multiId)) {
                            foreach ($xmlGenerator->multiId as $v) {
                                $sqlStr[] = $sqlStrFun($v);
                            }
                        }

                    } else if (stripos($isJson['message'], '无法修改!') !== false) {
                        $sqlStr[] = "DELETE FROM `sdm_scitrials`.`yikeen_odm_sync_record_ark` WHERE `patient_id` = {$xmlGenerator->patientId} AND `form_id` = {$xmlGenerator->formId} AND `checktime_id` = {$xmlGenerator->checkTimeId};";
                    }

                    if (!$sqlStr) {
                        return;
                    }
                    LogHelper::save([
                        'msg' => implode(PHP_EOL, $sqlStr),
                    ], 'INFO', 'syncFixSql');
                    return;
                }

                LogHelper::save([
                    'msg' => '数据同步成功了.',
                    'ODMResponseData' => $isJson,
                    'requestData' => $record,
                    'generateTime' => $generateTime,
                    'requestTime' => microtime(true) - $requestStartTime,
                ], 'INFO', 'syncODMPatient');
//
//            // 记录受试者同步状态
                SyncPatientHelper::setIsSync($this->patientId);
            }




            if ($xmlGenerator->getFormData()['group_id'] == FormGroup::CHECK_OCR) {
                $xmlGenerator->saveOcrRecord();
            }
            // 记录存储的字段
            $record = [
                'sync_type' => $xmlGenerator->getSyncType(),
                'patient_id' => $xmlGenerator->patientId,
                'item_id' => $xmlGenerator->itemId,
                'item_sign_id' => $xmlGenerator->itemSignId,
                'form_id' => $xmlGenerator->formId,
                'sync_field' => json_encode($xmlGenerator->getSyncField()),
                'is_del' => 0,
                'checktime_id' => $this->checkTimeId,
                'multi_id' => ''
            ];

            if ($xmlGenerator->recordId !== 0) {
                $record['id'] = $xmlGenerator->recordId;
            }

            if ($xmlGenerator->multiId) {
                foreach ($xmlGenerator->multiId as $value) {
                    $record = [
                        'sync_type' => $xmlGenerator->getSyncType(),
                        'patient_id' => $xmlGenerator->patientId,
                        'item_id' => $xmlGenerator->itemId,
                        'item_sign_id' => $xmlGenerator->itemSignId,
                        'form_id' => $xmlGenerator->formId,
                        'sync_field' => json_encode($xmlGenerator->getSyncField()),
                        'is_del' => $this->deleteMultiId == $value ? 1 : 0,
                        'checktime_id' => $this->checkTimeId,
                        'multi_id' => $value
                    ];
                    if ($has = Laminas::$serviceManager->odmSyncRecord->fetchOne(['columns' => ['id'], 'where' => $record])) {
                        $record['id'] = $has['id'];
                    }
                    Laminas::$serviceManager->odmSyncRecord->save($record);
                }
            } else {
                Laminas::$serviceManager->odmSyncRecord->save($record);
            }
        };
    }
}