<?php

namespace App\Console\Book;

use App\Libs\BatchUpdateTrait;
use App\Models\Book\Book;
use App\Models\Book\Chapter;
use App\Models\Book\BookConfig;
use Illuminate\Console\Command;

class BookSpiderAfter extends Command
{
    use BatchUpdateTrait;

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'book:after:spider {--bid=}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '书籍采集后续更新';

    public function handle()
    {
        // 传参
        $bid = (int)$this->option('bid');

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

        // 开始更新
        $this->start($books);
    }

    /**
     * @param $books
     * @return void
     */
    private function start($books): void
    {
        if ($books->isEmpty()) {
            return;
        }

        foreach ($books as $book) {
            $bid = (int)getProp($book, 'id');
            dLog('sync')->info('book:after:spider-start', compact('bid'));

            $this->updateChapterPrevAndNextCid($bid);
            $this->updateBookData($bid);

            dLog('sync')->info('book:after:spider-end', compact('bid'));
        }

    }

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

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

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

    /**
     * 更新书籍数据
     *
     * @param $bid
     * @return bool
     */
    private function updateBookData($bid): bool
    {
        if (empty($bid)) {
            return false;
        }

        // 基本查询条件
        $where = ['bid' => $bid, 'is_check' => 1, 'is_draft' => 0, 'is_deleted' => 0];

        // 获取首个章节
        $firstChapter = Chapter::select('id')->where($where)->orderBy('sequence', 'asc')->first();

        // 获取首个vip章节
        $vipWhere           = $where;
        $vipWhere['is_vip'] = 1;
        $firstVipChapter    = Chapter::select('id', 'sequence')->where($vipWhere)->orderBy('sequence', 'asc')->first();

        // 获取最新章节
        $lastChapter = Chapter::select('id', 'name')->where($where)->orderBy('sequence', 'desc')->first();

        // 获取章节总数
        $count = Chapter::where($where)->count();

        // 更新书籍相关数据
        Book::where('id', $bid)->update([
            'first_cid'     => (int)getProp($firstChapter, 'id'),
            'last_cid'      => (int)getProp($lastChapter, 'id'),
            'last_chapter'  => getProp($lastChapter, 'name'),
            'chapter_count' => $count,
            'updated_at'    => date('Y-m-d H:i:s')
        ]);

        // 更新书籍配置
        BookConfig::where('bid', $bid)->update([
            'vip_seq'    => (int)getProp($firstVipChapter, 'sequence'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        return true;
    }

    /**
     * 更新章节上下章节id
     *
     * @param $bid
     * @return bool
     */
    private function updateChapterPrevAndNextCid($bid): bool
    {
        if (empty($bid)) {
            return false;
        }

        // 基本查询条件
        $where    = ['bid' => $bid, 'is_check' => 1, 'is_draft' => 0, 'is_deleted' => 0];
        $chapters = Chapter::select('id', 'sequence')->where($where)->orderBy('sequence', 'asc')->get();
        if (empty($chapters)) {
            return false;
        }

        // 组装待更新数据
        $seqData = [];
        foreach ($chapters as $chapter) {
            $sequence = (int)getProp($chapter, 'sequence');
            $seqData[$sequence] = ['id' => (int)getProp($chapter, 'id')];
        }

        // 批量更新
        $updateData = [];
        foreach ($seqData as $seq => $seqItem) {
            $prevSeqData = getProp($seqData,$seq - 1, []);
            $nextSeqData = getProp($seqData,$seq + 1, []);
            $updateData[] = [
                'id' => $seqItem['id'],
                'prev_cid' => (int)getProp($prevSeqData, 'id'),
                'next_cid' => (int)getProp($nextSeqData, 'id'),
            ];
        }
        $this->batchUpdateDb('chapters', $updateData);

        return true;
    }
}