<?php

namespace console\controllers;

use common\models\ApiToken;
use yii\console\Controller;
use common\models\RiaLabD;
use common\models\RiaFrmHVLAB;
use common\models\HisRequest;
use common\models\LisResult;
use Yii;

class LisSendController extends Controller
{
    public function actionCreate()
    {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        // ===== ดึงข้อมูล Lab =====
        $RiaLabD = RiaLabD::find()
            ->alias('d')
            ->leftJoin(['h' => RiaFrmHVLAB::tableName()], 'd.RiaHDocID = h.RiaHDocID')
            ->where([
                'h.CustID' => '1087',
                'd.RiaLDApprvFlag' => 1,
            ])
            ->andWhere(['>', 'h.RiaHDocDate', '2025-10-20'])
            ->orderBy(['h.RiaHDocDate' => SORT_DESC])
            ->asArray()
            ->all();

        // ===== สร้าง LisResult และ TestList =====
        $testList = [];
        foreach ($RiaLabD as $rows) {
            $riaH = RiaFrmHVLAB::findOne(['RiaHDocID' => $rows['RiaHDocID']]);
            $hisReq = HisRequest::find()->where(['HN' => $riaH->PatHN, 'CustomerCode' => $riaH->CustID])->one();

            $LisResult = LisResult::find()->where(['lab_no' => $hisReq->LabNo, 'test_code' => $rows['LabID']])->one();
            if (!$LisResult) {
                $LisResult = new LisResult();
                $LisResult->lab_no = $hisReq->LabNo;
                $LisResult->riah_doc_id = $rows['RiaHDocID'];
                $LisResult->riah_doc_date = $rows['RiaHDocDate'];
                $LisResult->test_code = $rows['LabID'];
                $LisResult->test_name = $rows['LabName'];
                $LisResult->cust_id = $riaH->CustID;
                $LisResult->hn = $riaH->PatHN;
                $LisResult->result_value = $rows['RiaLDRsltAnal'];
                $LisResult->result_unit = $rows['LabUnit'];
                $LisResult->reference_range = $rows['LabNormal1'];
                $LisResult->status = 0; // ยังไม่ได้ส่ง
                $LisResult->save(false);
            }

            // สร้าง TestList
            $testList[] = [
                'LabNo' => $hisReq->LabNo,
                'RequestRemark' => '',
                'ResultStatus' => '',
                'TestList' => [
                    'TestCode' => (string)$rows['LabID'],
                    'TestName' => (string)$rows['LabName'],
                    'TestRemark' => '',
                    'InformCriticalByCode' => '',
                    'InformCriticalBy' => '',
                    'InformCriticalTo' => '',
                    'InformCriticalDateTime' => '',
                    'CriticalFlag' => '',
                    'ReportResultByCode' => '',
                    'ReportResultBy' => (string)($rows['RiaLDUserNameEntry'] ?? ''),
                    'ReportResultDateTime' => $this->dateTimeFormat($rows['RiaLDUserDateEntry']),
                    'ApproveResultByCode' => '',
                    'ApproveResultBy' => (string)($rows['RiaLDUserNameAppr'] ?? ''),
                    'ApproveResultDateTime' => $this->dateTimeFormat($rows['RiaLDUserDateAppr']),
                    'FileName' => '',
                    'Filebase64' => '',
                    'ResultList' => [
                        'ResultCode' => (string)$rows['LabID'],
                        'ResultName' => (string)$rows['LabName'],
                        'ResultValue' => (string)($rows['RiaLDRsltAnal'] ?? ''),
                        'ResultUnit' => (string)($rows['LabUnit'] ?? ''),
                        'ResultFlag' => '',
                        'ReferenceRange' => (string)($rows['LabNormal1'] ?? ''),
                        'ResultRemark' => '',
                    ],
                ]
            ];
        }

        // ===== ดึง token =====
        $cfg = Yii::$app->params['external_api'] ?? null;
        if (!$cfg) return ['error' => 'ค่าการตั้งค่า external_api ไม่ถูกต้อง'];

        $token = $this->getValidApiToken($cfg);

        // ===== ส่ง payload =====
        $url = $cfg['receiveUrl'];
        $response = $this->postJsonCurl($url, $testList, [
            'Authorization' => "Bearer {$token}",
        ]);

        // ===== อัปเดต LisResult status =====
        $statusToSave = (isset($response['http_code']) && $response['http_code'] == 200) ? 1 : 0;
        foreach ($RiaLabD as $rows) {
            $riaH = RiaFrmHVLAB::findOne(['RiaHDocID' => $rows['RiaHDocID']]);
            $hisReq = HisRequest::find()->where(['HN' => $riaH->PatHN, 'CustomerCode' => $riaH->CustID])->one();
            $LisResult = LisResult::find()->where(['lab_no' => $hisReq->LabNo, 'test_code' => $rows['LabID']])->one();
            if ($LisResult) {
                $LisResult->status = $statusToSave;
                $LisResult->save(false);
            }
        }

        // ===== Retry สำหรับ LisResult ที่ status = 0 =====
        if ($statusToSave == 0) {
            foreach (LisResult::find()->where(['status' => 0])->all() as $LisResult) {
                $success = false;
                $retry = 0;
                $maxRetry = 3; // สามารถปรับจำนวน retry
                while (!$success && $retry < $maxRetry) {
                    $success = $this->sendLisResult($LisResult);
                    $retry++;
                    if (!$success) sleep(1); // delay 1 วินาที
                }
            }
        }

        return ['sent_payload' => $testList, 'response' => $response];
    }

    // ===== helper ส่ง LisResult เดี่ยว ๆ =====
    protected function sendLisResult($LisResult)
    {
        $cfg = Yii::$app->params['external_api'] ?? null;
        if (!$cfg) return false;
        $token = $this->getValidApiToken($cfg);

        $payload = [
            'LabNo' => $LisResult->lab_no,
            'TestList' => [
                'TestCode' => $LisResult->test_code,
                'TestName' => $LisResult->test_name,
                'ResultList' => [
                    'ResultCode' => $LisResult->test_code,
                    'ResultValue' => $LisResult->result_value,
                ]
            ]
        ];

        $response = $this->postJsonCurl($cfg['receiveUrl'], $payload, [
            'Authorization' => "Bearer {$token}",
        ]);

        if (isset($response['http_code']) && $response['http_code'] == 200) {
            $LisResult->status = 1;
            $LisResult->save(false);
            return true;
        }
        return false;
    }

    // ===== helper ดึง token =====
    protected function getValidApiToken($cfg)
    {
        $apiName = 'external_api';
        $tokenModel = ApiToken::find()->where(['api_name' => $apiName])->one();
        $token = null;
        $nowTs = time();
        $refreshMargin = $cfg['refreshMargin'] ?? 300;

        $needRequest = !$tokenModel || strtotime($tokenModel->expires_at) <= ($nowTs + $refreshMargin);
        if ($needRequest) {
            $tokenResp = $this->getApiToken($cfg['tokenUrl'], $cfg['username'], $cfg['password']);
            if (!$tokenResp['ok'] && $tokenModel) return $tokenModel->token;
            elseif (!$tokenResp['ok']) return null;
            $token = $tokenResp['token'];
            $expiresAt = $tokenResp['expires_at'] ?? date('Y-m-d H:i:s', time() + 3600);
            if (!$tokenModel) {
                $tokenModel = new ApiToken();
                $tokenModel->api_name = $apiName;
            }
            $tokenModel->token = $token;
            $tokenModel->expires_at = $expiresAt;
            $tokenModel->save(false);
        } else {
            $token = $tokenModel->token;
        }

        return $token;
    }

    // ===== helper แปลง datetime =====
    public function dateTimeFormat($value)
    {
        if (empty($value)) return '';
        try {
            $dt = new \DateTime($value);
            return $dt->format('d/m/Y H:i:s');
        } catch (\Throwable $e) {
            return '';
        }
    }
}
