<?php

namespace App\Console\Book;

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

class SyncBooksFromZwContent extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'book:sync:from:zw {--zw_ids=}';

    /**
     * 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()
    {
        // 传参
        $zwIds  = $this->filterParams();

        // 获取书籍列表
        if (empty($zwIds)) {
            $zwIds = Book::select('id', 'zw_id')->where('zw_id', '>', '0')->plunck('zw_id');
        }

        // 执行更新
        $this->syncZwBooks($zwIds);
    }

    /**
     * @return array
     */
    private function filterParams(): array
    {
        // 传参
        $idsStr = $this->option('zw_ids');
        $ids    = explode(',', $idsStr);
        if (empty($ids)) {
            return [];
        }

        $result = [];
        foreach ($ids as $id) {
            if (in_array($id, $result) || !is_numeric($id) || (int)$id < 1) {
                continue;
            }

            $result[] = (int)$id;
        }

        return $result;
    }

    /**
     * @param $zwIds
     *
     * @return void
     * @throws GuzzleException
     */
    private function syncZwBooks($zwIds): void
    {
        // 判空
        if (empty($zwIds)) {
            return;
        }

        // 循环执行
        foreach ($zwIds as $zwId) {
            $this->syncZwBook($zwId);
        }

    }

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

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

        // 获取书籍
        $book = Book::where('zw_id', $zwId)->first();
        if (!$book) {
            $book = new Book();
            $book->zw_id = $zwBook['bid'];
        }

        $book->name = $zwBook['name'];
        $book->author = $zwBook['author'];
        $book->intro = trim(str_replace("&nbsp;", "", $zwBook['intro']));
        $book->cover = $zwBook['cover'];
        $book->keyword = $zwBook['keyword'];
        $book->gender = $zwBook['gender'];  # 1男 2女 //TODO 是否要调整
        $book->category_id = $zwBook['category_id'];
        $book->category_name = $zwBook['category_name'];
        $book->ncategory_id = $zwBook['ncategory_id'];
        $book->size = $zwBook['size'];
        $book->status = $zwBook['status'];
        $book->chapter_count = $zwBook['chapter_count'];
        $book->save();


        // 获取书籍配置
        $bookConfig = BookConfig::where('bid', $book->id)->first();
        if (!$bookConfig) {
            $bookConfig              = new BookConfig();
            $bookConfig->bid         = $book->id;
            $bookConfig->charge_type = 'CHAPTER';
            $bookConfig->is_on_shelf = 0;
            $bookConfig->copyright_limit_data = '0000-00-00';
        }
        $bookConfig->cover = $zwBook['cover'];
        $bookConfig->book_name = $zwBook['name'];
        $bookConfig->source_domain = $zwBook['gender'] == 1 ? 'fanqqe.com' : 'fanqrj.com';
        $bookConfig->cp_source = $zwBook['cp'];
        $bookConfig->save();

        dLog('sync')->info('book:sync-end', compact('zwId'));
    }

    /**
     * 请求
     *
     * @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;
    }
}