<?php

namespace Application\Service\Extension\CheckLogic;

use Application\Service\Extension\Helper\CheckLogicMessageFormatterHelper;
use Application\Service\Extension\Laminas;
use Laminas\Db\ResultSet\ResultSet;
use Laminas\Db\Sql\Select;
use Laminas\Db\Sql\Sql;
use Laminas\Db\Sql\Where;
use Application\Service\Extension\Helper\ArrayHelper;

class Pointer
{
    use CheckLogicMessageFormatterHelper;

    public array $pointer = [];

    public array $usingVars = [];

    public array $usingField = [];

    public array $note = [];

    private ?int $patientId = null;
    private ?int $checkTimeId = null;
    private ?int $multiId = null;
    public $errorId = null;
    private ?bool $isSpecial = false;

    private ?array $errPointer = null;

    public ?bool $canReply = false;

    private ?int $errorDelStatus = null;

    private bool $isProcess = false;

    public function setPatientId(int $patientId): Pointer
    {
        $this->patientId = $patientId;
        return $this;
    }

    public function setErrorDelStatus(int $errorDelStatus) {
        $this->errorDelStatus = $errorDelStatus;
        return $this;
    }

    public function setCheckTimeId(int $checkTimeId): Pointer
    {
        $this->checkTimeId = $checkTimeId;
        return $this;
    }

    public function setErrorId($errorId): Pointer
    {
        $this->errorId = $errorId;
        return $this;
    }

    public function setIsProcess(bool $isProcess): Pointer
    {
        $this->isProcess = $isProcess;
        return $this;
    }

    public function setMultiId(int $multiId): Pointer
    {
        $this->multiId = $multiId;
        return $this;
    }

    private function getErrorPointer(): ?array
    {
        if ($this->errPointer === null) {
            $condition = [];
            $this->setErrorDelStatus(0);
            if ($this->patientId) {
                $condition['patient_id'] = $this->patientId;
            }

            if ($this->checkTimeId && $this->isProcess === false) {
                $condition['checktime_id'] = $this->checkTimeId;
            }

            if ($this->multiId) {
                $condition['multi_id'] = $this->multiId;
            }

            if ($this->errorId) {
                $condition['error_id'] = $this->errorId;
            }

            if ($this->errorDelStatus !== null) {
                $condition['is_del'] = $this->errorDelStatus;
            }
//            $condition['pointer.is_del'] = 0;
            $condition['form_id'] = $_POST['id'];
            /* $sql = new Sql(Laminas::$app->getServiceManager()->get('edcDbAdapter'));
            $select = $sql->select()->from(['pointer' => 'yikeen_item_patient_form_logic_error_pointer'])
                ->join(['error' => 'yikeen_item_patient_form_logic_error'], 'error.id = pointer.error_id', ['is_closed', 'is_report_special'], Select::JOIN_LEFT)
                ->where($condition);

            $statement = $sql->prepareStatementForSqlObject($select);
            $resultSet = new ResultSet();
            $this->errPointer = $resultSet->initialize($statement->execute())->toArray();*/

            $this->errPointer = Laminas::$serviceManager->itemPatientFormLogicErrorPointer->fetchAll([
                'where' => $condition
            ]);

            if(!empty($this->errPointer)){
                //先查询error表
                $error_condition = $condition;
                unset($error_condition['error_id']);
                $error_infos =  Laminas::$serviceManager->itemPatientFormLogicError->fetchAll([
                    'where' => $error_condition,
                    'columns' => ['id','is_closed', 'submit_role', 'is_report_special']
                ]);
                $errorinfos = ArrayHelper::index($error_infos,'id');
                unset($error_infos);
                unset($error_condition);
                foreach ($this->errPointer as &$poiter_data){
                    $errors = isset($errorinfos[$poiter_data['error_id']]) && !empty($errorinfos[$poiter_data['error_id']]) ? $errorinfos[$poiter_data['error_id']] : [];
                    if(!empty($errors)){
                        $poiter_data['is_closed'] = $errors['is_closed'];
                        $poiter_data['submit_role'] = $errors['submit_role'];
                        $poiter_data['is_report_special'] = $errors['is_report_special'];
                    }
                    unset($errors);
                }
                unset($errorinfos);
            }
            unset($condition);

        }

        return $this->errPointer;
    }

    private function getAnswer($errorId)
    {
        $reply = Laminas::$serviceManager->itemPatientFormLogicErrorQuery->fetchOne([
            'order' => ['id DESC'],
            'where' => ['error_id' => $errorId, 'platform' => 2, 'is_reply' => 1, (new Where())->greaterThanOrEqualTo('create_time', $this->formatterCreateTime)]
        ]);

        if (!$reply) {
            return '';
        }

        $this->formatterIsAuditor = $reply['is_auditor'];

        return $this->setMessage($reply['content'], true)
            ->setItemId($_POST['item_id'])
            ->setCreateTime($reply['create_time'])
            ->setCreateUserId($reply['create_user_id'])
            ->setErrorId($reply['error_id'])
            ->format();
    }
    public function oldgetUsingField()
    {
        $note = function($pointer) {
            $question = $this->setMessage($pointer['error_message'], false)
                ->setErrorIdAlias($pointer['error_id'])
                ->setErrorId($pointer['error_id'])
                ->setCreateUserId($pointer['create_user_id'])
                ->setCreateTime($pointer['create_time'])
                ->format();
            $answer = $this->getAnswer($pointer['error_id']);
            $reply = Laminas::$serviceManager->itemPatientFormLogicErrorQuery->fetchOne([
                'order' => ['id desc'],
                'where' => ['error_id' => $pointer['error_id'], 'is_reply' => 1]
            ]);

            $this->canReply = true;
            if ($reply && $reply['is_auditor'] == 1) {
                $this->canReply = false;
            }
            return [
                'q' => $question, // "$isClosed {$pointer['error_message']} {$this->getErrorType($pointer['error_type'], $pointer['create_user_id'])}" . date('Y/m/d H:i:s', $pointer['create_time']),
                'a' => $answer,
                'message_id' => intval($pointer['id']),
                'is_closed' => $pointer['is_closed'],
                'can_reply' => $this->canReply,
                'error_id' => $pointer['error_id']
            ];
        };
        foreach ($this->getErrorPointer() as $pointer) {
            if (stripos($pointer['prop'], ',') !== false) {
                $ex = explode(',', $pointer['prop']);
                foreach ($ex as $exItem) {
                    $this->usingField[] = $exItem;
                    $this->note[$exItem][] = $note($pointer);
                }
            } else {
                $this->usingField[] = $pointer['prop'];
                $this->note[$pointer['prop']][] = $note($pointer);
            }
        }
        return $this->usingField;
    }


    public function getUsingField()
    {
        if(!empty($this->getErrorPointer())){
            //获取回复数据
            $errorQueryDatas = [];
            $queryDatas = Laminas::$serviceManager->itemPatientFormLogicErrorQuery->fetchAll([
                'where' => ['error_id' => array_values(array_column($this->getErrorPointer(),'error_id')),'is_reply' => 1],
                'columns'=>['error_id','content','create_user_id','create_time','platform','item_id','is_auditor'],
                'order' => ['id desc']
            ]);

            if(!empty($queryDatas)){
                foreach($queryDatas as $queryKey=>$reply){
                    if(!isset($errorQueryDatas[$reply['error_id']])){
                        $this->currentErrorId = $reply['error_id'] ?? 0;
                        $this->formatterCreateUserId = $reply['create_user_id'];
                        $this->formatterCreateTime = $reply['create_time'];
                        $this->formatterPlatform = $reply['platform'];
                        $this->formatterItemId = $_POST['item_id'];
                        $this->formatterIsAuditor = $reply['is_auditor'];
                        if($reply['platform'] == 2){
                            $errorQueryDatas[$reply['error_id']]['replays'] = $this->setMessage($reply['content'], true)->setErrorIdAlias($reply['error_id'])->setCreateTime($reply['create_time'])->setCreateUserId($reply['create_user_id'])->format();
                        }
                        $errorQueryDatas[$reply['error_id']]['canreplays'] = $reply;
                    }
                    unset($queryDatas[$queryKey]);
                }
            }

            unset($queryDatas);
            foreach ($this->getErrorPointer() as $pointer) {
                $this->formatterLogicErrorId = $pointer['error_id'];
                $this->formatterCreateUserId = $pointer['create_user_id'];
                $this->formatterCreateTime = $pointer['create_time'];
                $this->formatterItemId = $pointer['item_id'];
                $this->formatterCheckType = $pointer['error_type'];
                $question = $this->formatMessage($pointer['error_message']);
                $reply_infos = isset($errorQueryDatas[$pointer['error_id']]['replays']) && !empty($errorQueryDatas[$pointer['error_id']]['replays']) ? $errorQueryDatas[$pointer['error_id']]['replays'] : '';
                $can_reply_infos = isset($errorQueryDatas[$pointer['error_id']]['canreplays']) && !empty($errorQueryDatas[$pointer['error_id']]['canreplays']) ? $errorQueryDatas[$pointer['error_id']]['canreplays'] : '';
                $this->canReply = true;
                //判断是否可回复使用
                if ($can_reply_infos && $can_reply_infos['is_auditor'] == 1) {
                    $this->canReply = false;
                }
                if(!empty($reply_infos) && isset($reply_infos['is_auditor'])){
                    unset($reply_infos['is_auditor']);
                }
                $note_data = [
                    'q' => $question,
                    'a' => $reply_infos,
                    'message_id' => intval($pointer['id']),
                    'is_closed' => $pointer['is_closed'],
                    'can_reply' => $this->canReply,
                    'error_id' => $pointer['error_id']
                ];
                unset($question);
                if (stripos($pointer['prop'], ',') !== false) {
                    $ex = explode(',', $pointer['prop']);
                    foreach ($ex as $exItem) {
                        $this->usingField[] = $exItem;
                        $this->note[$exItem][] = $note_data;
                    }
                } else {
                    $this->usingField[] = $pointer['prop'];
                    $this->note[$pointer['prop']][] = $note_data;
                }
                unset($note_data);
            }
            unset($errorQueryDatas);
        }

        return $this->usingField;
    }

    public function getFieldError(string $fieldId)
    {
        return $this->note[$fieldId];
    }
}