<?php

namespace App\Http\Controllers\Api;

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use Illuminate\Http\Request;
use App\Http\Services\Api\GeneralInnerServiceService;
use App\Http\Services\Backend\DataManagement\UrlManagementService;
use App\Http\Controllers\Controller;
use App\Http\Services\ConstDef\GeneralConst;
use App\Http\Services\CheckParamService;

class GeneralInnerServiceController extends Controller
{
    
    private $apicode;
    private $oid;
    private $generalInnerServiceSv;
    private $urlManagementSv;
    private $checkParamSv;
    
    public function __construct(Request $request)
    {
        $this->generalInnerServiceSv = new GeneralInnerServiceService();
        $this->urlManagementSv = new UrlManagementService();
        $this->checkParamSv = new CheckParamService();
        // 鑒權
        $this->oid = $this->generalInnerServiceSv->validate($request->header('userToken'));
        $this->apicode = ($this->oid == 0) ? GeneralConst::API_TOKEN_ERR : GeneralConst::API_OK;
    }
    
    public function store(Request $request)
    {
        // 鑒權
        if ($this->oid == 0) return json_decode(json_encode(['code' => $this->apicode, 'msg' => GeneralConst::$apiMap[ $this->apicode ], 'data' => []], JSON_NUMERIC_CHECK), true);
        // 參數設置
        $urlid = '';
        $mode = $request->mode;
        $id = ($request->mode == 'insert') ? '' : $request->serno; // 只有更新用的到
        $title = $request->title;
        $url = ($request->mode == 'insert') ? $request->url : ''; // 只有新增用的到
        $memo = $request->memo;
        $valid = GeneralConst::URL_OK; // 預設都可用
        // 參數驗證
        if (!in_array($mode, ['insert', 'update'])) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
        if ($mode == 'update') {
            if (!$this->checkParamSv->isnum($id)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
        }
        if ($title != filter_var($title, FILTER_SANITIZE_SPECIAL_CHARS)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
        if (!$this->checkParamSv->LenMToN($title, 1, 20)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
        if ($mode == 'insert') {
            if (filter_var($url, FILTER_VALIDATE_URL) === false) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
            if (!$this->checkParamSv->LenMToN($url, 1, 1024)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
        }
        if ($memo != filter_var($memo, FILTER_SANITIZE_SPECIAL_CHARS)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
        if (!$this->checkParamSv->LenMToN($memo, 0, 20)) return json_decode(json_encode(['code' => GeneralConst::API_PARAM_ERR, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_PARAM_ERR ], 'data' => []], JSON_NUMERIC_CHECK), true);
        // 服務層
        if ($mode == "insert") {
            \Log::info('start getCode');
            $code = $this->urlManagementSv->getCode();
            \Log::info($code);
            // 新增模式
            $urlid = $this->urlManagementSv->insertUrl($title, $url, $code, $memo, $valid, $this->oid);
        } else {
            // 編輯模式
            $this->urlManagementSv->modifyUrl($id, $title, $url, $memo, $valid);
        }
        
        // 返回
        return json_decode(json_encode(['code' => GeneralConst::API_OK, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_OK ], 'data' => $urlid], JSON_NUMERIC_CHECK), true);
    }
    
    public function fetch(Request $request)
    {
        // 鑒權
        if ($this->oid == 0) return json_decode(json_encode(['code' => $this->apicode, 'msg' => GeneralConst::$apiMap[ $this->apicode ], 'data' => []], JSON_NUMERIC_CHECK), true);
        // 服務層
        $recordsTotal = 0;
        $result = $this->urlManagementSv->getUrls(
            $recordsTotal,
            1,
            'asc',
            0,
            1048576, // 由於不分頁，內部單一用戶或事業體不可能用到百萬等級，所以不想額外做功能
            '',
            '',
            '',
            "1900-01-01",
            "2050-12-31",
            GeneralConst::URL_OK, // 只有返回有效的
            $this->oid
        );
        // 整理返回資料
        $data = array();
        for ($i = 0; $i < count($result); $i++) {
            $data[] = [
                'id'     => $result[ $i ]["serno"],
                'code'   => $result[ $i ]["api_code"],
                'url'    => env('ORL_URL') . $result[ $i ]["api_code"],
                'pv'     => $result[ $i ]["pv"],
                'qrcode' => $result[ $i ]["api_qrcode"],
            ];
        }
        
        
        // 返回
        return json_decode(json_encode(['code' => GeneralConst::API_OK, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_OK ], 'data' => $data], JSON_NUMERIC_CHECK), true);
    }

    public function fetchById(Request $request)
    {
        // 鑒權
        if ($this->oid == 0) return json_decode(json_encode(['code' => $this->apicode, 'msg' => GeneralConst::$apiMap[ $this->apicode ], 'data' => []], JSON_NUMERIC_CHECK), true);
        // 服務層
        $orlId = $request->input('orlId');
        $result = $this->urlManagementSv->getUrlById($orlId, $this->oid);
        // 整理返回資料
        $data = [];
        if (!empty($result)) {
            $data = [
                'id'      => $result["serno"],
                'url'     => $result["code"],
                'origUrl' => $result["url"],
                'title'   => $result["title"],
            ];
        }

        // 返回
        return json_decode(json_encode(['code' => GeneralConst::API_OK, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_OK ], 'data' => $data], JSON_NUMERIC_CHECK), true);
    }
    
    public function dateseg(Request $request)
    {
        // 鑒權
        if ($this->oid == 0) return json_decode(json_encode(['code' => $this->apicode, 'msg' => GeneralConst::$apiMap[ $this->apicode ], 'data' => []], JSON_NUMERIC_CHECK), true);
        // 服務層
        $result = $this->urlManagementSv->getDateseg($this->oid);
        // 整理返回資料
        $data = array();
        $tmp = '';
        for ($i = 0; $i < count($result); $i++) {
            if ($tmp != $result[ $i ]["code"]) {
                $tmp = $result[ $i ]["code"];
            }
            $data[ $tmp ][] = [
                'date' => $result[ $i ]["date"],
                'cnt'  => $result[ $i ]["cnt"],
            ];
        }
        
        // 返回
        return json_decode(json_encode(['code' => GeneralConst::API_OK, 'msg' => GeneralConst::$apiMap[ GeneralConst::API_OK ], 'data' => $data], JSON_NUMERIC_CHECK), true);
    }
    
    public function qrcode($code)
    {
        header("Cache-Control: no-cache, must-revalidate");
        header("Pragma: no-cache");
        header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
        header('Content-Description: File Transfer');
        header('Content-Disposition: attachment; filename="' . $code . '.png"');
        header('Content-Transfer-Encoding: binary');
        header('Content-type: image/png');
        $options = new QROptions([
            'version'     => 2,
            'outputType'  => QRCode::OUTPUT_IMAGE_PNG,
            'imageBase64' => false,
        ]);
        echo (new QRCode($options))->render(env('ORL_URL') . $code);
    }
    
}