<?php

namespace App\Http\Controllers\Fpdx;

use Illuminate\Http\Request;
use App\Models\Fpdx\MediaKeyModel;
use App\Http\Controllers\Wechat\SendMsg;
use App\Http\Controllers\Controller;

abstract class Listen extends Controller
{
    protected $media_id;
    protected $request;
    protected $message;
    protected $plat;

    public function __construct(string $plat)
    {
        $this->plat = $plat;
    }

    // 开启应用
    abstract public function open();

    // 触发应用
    public function trigger()
    {
        libxml_disable_entity_loader(true);
        $object = simplexml_load_string($this->message, 'SimpleXMLElement', LIBXML_NOCDATA);
        $array = array(
            [
                'Title' => '点此报名参加“72小时恋爱体验”活动',
                'Description' => '70万+有趣灵魂在这里相遇，不问结果，无关物质',
                'PicUrl' => 'http://oss.pocketuniversity.cn/media/2018-06-19/5b28deef543a8.jpg',
                'Url' => config('app.pocket_url') . "/chargePartner/http/index?page=couple&media_id={$this->media_id}"
            ]
        );
        return SendMsg::news($object, $array);
    }

    // 初始化公众号
    abstract public function initMedia(string $media_id);

    // 同步公众号信息
    abstract public function syncMedia(string $media_id);

    // 获取公众号信息
    abstract public function getMediaInfo(string $media_id);

    /**
     * @param  Request  $request
     * @return array|\Illuminate\Contracts\View\Factory|\Illuminate\View\View|void
     * @throws \Exception
     */
    public function listen(Request $request)
    {
        $this->message = file_get_contents('php://input');
        $this->media_id = $request->input('media_id');
        $this->request = $request;
        switch ($request->type) {
            case 'open':
                return $this->open();
            case 'config':
                return $this->config();
            case 'close':
                return $this->close();
            case 'trigger':
                return $this->trigger();
            case 'keyword':
                return $this->keyword();
            default:
                return;
        }
    }

    /**
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    protected function config()
    {
        $this->syncMedia($this->media_id);
        return view("fpdx");
    }

    /**
     * @return array
     * @throws \Exception
     */
    protected function close()
    {
        $message = json_decode($this->message);
        $this->media_id = $message->media_id;
        MediaKeyModel::where([
            ['media_id', $this->media_id],
            ['app', 'fpdx'],
            ['plat', $this->plat]
        ])->delete();
        return [
            'errcode' => 0,
            'errmsg' => 'success'
        ];
    }

    /**
     * @return array
     */
    protected function keyword()
    {
        $message = json_decode($this->message);
        $this->media_id = $message->media_id;
        MediaKeyModel::updateOrCreate([
            'media_id' => $this->media_id,
            'app' => 'fpdx',
            'plat' => $this->plat
        ], ['keywords' => json_encode($message->keyword)]);
        return [
            'errcode' => 0,
            'errmsg' => 'success'
        ];
    }

    /**
     * 计算签名
     * @param  array
     * @return string sign 签名
     */
    protected function sign($param_array)
    {
        $names = array_keys($param_array);
        sort($names, SORT_STRING);
        $item_array = array();
        foreach ($names as $name) {
            $item_array[] = "{$name}={$param_array[$name]}";
        }
        $str = implode('&', $item_array) . '&key=' . config('fpdx.' . $this->plat . '.secret');
        return strtoupper(md5($str));
    }
}
