<?php

namespace App\Console\Book;

use App\Models\Book\Book;
use App\Models\Book\Chapter;
use App\Models\Book\ChapterContent;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use GuzzleHttp\Exception\GuzzleException;

class SyncChaptersFromZwContent extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'chapter:content:sync:from:zw {--bid=} {--after=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '从内容平台同步并更新图书章节';

    /**
     * @var Client
     */
    private $client;

    // 内容中台域名
    private $baseUrl = 'http://cp.yqsd.cn/api/book';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
        $this->client = new Client(['timeout' => 20.0, 'allow_redirects' => true]);
    }

    /**
     * @return void
     * @throws GuzzleException
     */
    public function handle()
    {
        // 传参
        $bid   = (int)$this->option('bid');
        $after = (int)$this->option('after');

        // 获取书籍列表
        $books = $this->getBooks($bid, $after);

        // 执行更新
        $this->syncChapters($books);
    }

    /**
     * 获取待更新书籍列表
     *
     * @param $bid
     * @param $after
     * @return mixed
     */
    private function getBooks($bid, $after)
    {
        // 组装查询条件
        $query = Book::select('id', 'zw_id', 'name')->where('zw_id', '>', '0');

        // 此处bid为原创小程序bid
        if ($bid) {
            if ($after) {
                $query->where('books.id', '>=', $bid);
            }else{
                $query->where('books.id', $bid);
            }
        }

        // 查询
        return $query->get();
    }

    /**
     * @param $books
     * @return void
     * @throws GuzzleException
     */
    private function syncChapters($books): void
    {
        // 判空
        if ($books->isEmpty()) {
            return;
        }

        // 循环执行
        foreach ($books as $book) {
            $this->syncBookChapters($book->id, $book->zw_id);
        }

    }

    /**
     * @param $bid
     * @param $zwId
     * @return void
     * @throws GuzzleException
     */
    private function syncBookChapters($bid, $zwId): void
    {
        dLog('sync')->info('chapter:sync-start', compact('bid', 'zwId'));
        // 判空
        if (empty($bid) || empty($zwId)) {
            return;
        }

        // 获取最新章节信息
        $lastChapter = Chapter::where('bid', $bid)
                              ->where('is_check', 1)
                              ->where('is_draft', 0)
                              ->where('is_deleted', 0)
                              ->orderBy('sequence', 'desc')
                              ->first();

        // 章节相关参数
        $maxSequence   = (int)getProp($lastChapter, 'sequence', 0);
        $lastChapterId = (int)getProp($lastChapter, 'id', 0);
        $zwChapterId   = (int)getProp($lastChapter, 'zw_chapter_id', 0);

        // 获取内容平台章节列表
        $zwChapters = $this->request('/chapterlist/' . $zwId);
        if (empty($zwChapters)) {
            return;
        }

        // 循环章节内容
        foreach ($zwChapters as $zwChapter) {
            $zwCid       = (int)getProp($zwChapter, 'chapter_id', 0);
            $chapterName = getProp($zwChapter, 'chapter_name');

            // 从最新章节开始新增内容
            if ($zwChapterId && $zwChapterId !== $zwCid) {
                continue;
            }

            // 获取内容平台章节内容
            $contentData = $this->request('/chapterContent/' . $zwId . '/' . $zwCid);
            if (empty($contentData)) {
                continue;
            }

            // 先保存章节内容
            $obj                = new ChapterContent();
            $obj->bid           = $bid;
            $obj->zw_bid        = $zwId;
            $obj->zw_chapter_id = $zwCid;
            $obj->chapter_name  = $chapterName;
            $obj->content       = getProp($contentData, 'content');
            $obj->save();

            // 保存章节
            $obj1                     = new Chapter();
            $obj1->bid                = $bid;
            $obj1->name               = $chapterName;
            $obj1->sequence           = (int)getProp($zwChapter, 'sequence');
            $obj1->size               = (int)getProp($zwChapter, 'size');
            $obj1->is_vip             = (int)getProp($zwChapter, 'is_vip');
            $obj1->is_check           = 1;
            $obj1->recent_update_at   = date('Y-m-d H:i:s');
            $obj1->post_time          = date('Y-m-d H:i:s');
            $obj1->zw_bid             = $zwId;
            $obj1->zw_chapter_id      = $zwCid;
            $obj1->chapter_content_id = $obj->id;
            $obj1->save();
        }

        dLog('sync')->info('chapter:sync-end', compact('bid'));

        // 执行更新书籍数据脚本
        $this->call('book:after:spider', ['--bid' => $bid]);

    }

    /**
     * 请求
     *
     * @param $url
     * @return array|mixed|string
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    private function request($url)
    {
        $url = $this->baseUrl . $url;
        try {
            $result = $this->client->request('get', $url)->getBody()->getContents();
            $result = json_decode($result, true);
            $code   = getProp($result, 'code', 0);
            $data   = getProp($result, 'data', []);
        } catch (\Exception $e) {
            return [];
        }

        return $code ? [] : $data;
    }
}