<?php

namespace Api\PhpServices\Printer\Fei;

/**
 * 飞蛾 打印实现类
 *
 * @author mengweifu
 * @date 2021-7-25 14:00:00
 */

use Api\PhpUtils\Http\HttpUtil;

class FeiPrinter extends \Api\PhpServices\Printer\Printer
{
    /**
     * *必填*：账号名
     */
    private  const  USER = "yonghui.chen@linkingcities.com";
    /**
     * *必填*: 飞鹅云后台注册账号后生成的UKEY 【备注：这不是填打印机的KEY】
     */
    private  const  UKEY = "VjPMkB64QNuIIcgQ";
    /**
     * 飞鹅云打印 api前缀 不需要修改
     */
    private  const  API = "http://api.feieyun.cn/Api/Open/";

    /**
     * 打印订单
     */
    private  const  API_PRINT = "Open_printMsg";
    /**
     * 查询打印订单状态
     */
    private  const  API_ORDER_STATUS = "Open_queryOrderState";
    /**
     * 获取某台打印机状态
     */
    private  const  API_PRINTER_STATUS = "Open_queryPrinterStatus";

    /**
     * 添加打印机
     */
    private  const  API_ADD_PRINTER = "Open_printerAddlist";


    /**
     * @param string $apiName api 名字
     * @return array
     */
    private function buildQuery(string $apiName) : array
    {
        $timestamp = time();
        return [
            'user'      => self::USER,
            'stime'     => $timestamp,
            'sig'       => $this->signature(self::USER, self::UKEY, $timestamp),
            'apiname'   => $apiName
        ];
    }

    private function signature(String $user, String $uKey, int $sTime): string
    {
        return sha1($user . $uKey . $sTime);
    }

    /**
     * 内部函数 查询
     * @param string $apiName
     * @param array $param
     * @return array
     */
    private function request(string $apiName,array $param): array
    {
        $param = $this->buildQuery($apiName) + $param;
        return HttpUtil::post(self::API, http_build_query($param));
    }

    /**
     * @inheritDoc
     * @throws \Exception
     */
    public function addPrinter(array $param): bool
    {
        $res = $this->request(self::API_ADD_PRINTER, [
            'printerContent'       => "{$param['printer_sn']} # {$param['printer_key']} # {$param['ota_name']}",
        ]);
        if ($res['code'] == 0 && isset($res['response'])) {
            if ($res['response']['ret'] == 0) {
                return $res['response']['data'];
            }
            throw new \Exception($res['response']['msg']);
        }
        throw new \Exception("接口调用异常");
    }

    /**
     * @inheritDoc
     */
    public function deletePrinter(string $printerId): bool
    {
        // TODO: Implement deletePrinter() method.
    }

    /**
     * @inheritDoc
     * @throws \Exception
     */
    public function getPrinterStatus(string $printerId): string
    {
        $res = $this->request(self::API_PRINTER_STATUS, [
            'sn'    => $printerId,
        ]);
        if ($res['code'] == 0 && isset($res['response'])) {
            if ($res['response']['ret'] == 0) {
                return $res['response']['data'];
            }
            throw new \Exception($res['response']['msg']);
        }
        throw new \Exception("接口调用异常");
    }


    /**
     * @inheritDoc
     * @throws \Exception
     */
    public function printContent(string $printerId, array $content):string
    {
        $formattedContent = "";
        $first = true;
        foreach ($content as $row) {
            $formattedRow = is_array($row) ? implode(' ', $row) : $row;
            if ($first) {
                $formattedContent .= "<CB>$formattedRow</CB><BR>";
            }
            else {
                $formattedContent .= "$formattedRow<BR>";
            }
            $first = false;
        }

        $res = $this->request(self::API_PRINT, [
            'sn'         => $printerId,
            'content'   => $formattedContent,
            'times'     => 1,// 打印联数
        ]);
        if ($res['code'] == 0 && isset($res['response'])) {
            if ($res['response']['ret'] == 0) {
                return $res['response']['data'];
            }
            throw new \Exception($res['response']['msg']);
        }
        throw new \Exception("接口调用异常");
    }

    /**
     * @inheritDoc
     * @throws \Exception
     */
    public function getOrderStatus(string $orderId): bool
    {
        $res = $this->request(self::API_ORDER_STATUS, [
            'orderid'       => $orderId,
        ]);
        if ($res['code'] == 0 && isset($res['response'])) {
            if ($res['response']['ret'] == 0) {
                return (bool) $res['response']['data'];
            }
            throw new \Exception($res['response']['msg']);
        }
        throw new \Exception("接口调用异常");
    }
}