<?php

namespace App\Http\Controllers\QuickApp\Book;

use App\Modules\SendOrder\Services\SendOrderService;
use App\Modules\Statistic\Services\WapVisitStatService;
use Illuminate\Http\Request;
use App\Http\Controllers\QuickApp\BaseController;
use Redis;
use App\Modules\Book\Services\ChapterService;
use App\Modules\User\Services\ReadRecordService;
use App\Http\Controllers\QuickApp\Book\Transformers\ChapterTransformer;
use App\Modules\Book\Services\BookConfigService;
use App\Http\Controllers\QuickApp\Book\Transformers\ChapterListTransformer;
use App\Jobs\UserRententionJob;
use App\Modules\Book\Services\BookService;
use App\Modules\Subscribe\Services\BookOrderService;
use App\Modules\Subscribe\Services\ChapterOrderService;
use App\Modules\Subscribe\Services\YearOrderService;
use App\Modules\OfficialAccount\Services\ForceSubscribeService;
use App\Modules\Subscribe\Services\ChapterReminderService;
use App\Modules\User\Services\UserDeepReadTagService;
use App\Modules\UserTask\Services\BaseTask;
use App\Modules\UserTask\Services\UserTaskService;

class ChapterController extends BaseController
{

    private $book_info;

    public function getCatalog(Request $request, $bid)
    {
        $bid = BookService::decodeBidStatic($bid);
        $lists = ChapterService::getChapterLists($bid);
        $book_info = BookConfigService::getBookById($bid);
        if (!$book_info) {
            return response()->error('PARAM_ERROR');
        }
        $lists = $this->getChapterCatalog($bid, $lists, $book_info);
        return response()->collection(new ChapterListTransformer, $lists);
    }

    public function getCatalogPerPage(Request $request, $bid)
    {
        $bid = BookService::decodeBidStatic($bid);
        $book_info = BookConfigService::getBookById($bid);
        if (!$book_info) {
            return response()->error('PARAM_ERROR');
        }
        $page_size = $request->input('page_size', 15);
        if ($page_size >= 100) $page_size = 100;
        $res = ChapterService::getChapterListsPage($bid, $page_size);
        $lists = $this->getChapterCatalog($bid, $res, $book_info);
        return response()->pagination(new ChapterListTransformer, $lists);
    }

    private function getChapterCatalog(int $bid, $chapters, $book_info)
    {
        switch ($book_info->charge_type) {
            case 'BOOK':
                $price = $this->getPrice($book_info);
                $is_need_charge = $this->isBookNeedCharge($bid, $price);
                foreach ($chapters as $v) {
                    $v->is_need_charge = $v->is_vip ? $is_need_charge : false;
                    $v->price = $price;
                }
                break;
            default:
                foreach ($chapters as $v) {
                    $v->price = $v->is_vip ? $this->getPrice($book_info, $v->size) : 0;
                    $v->is_need_charge = $v->is_vip ? $this->isChapterNeedCharge($bid, $v->id, $v->price) : false;
                }
                break;
        }
        return $chapters;
    }

    public function index(Request $request, $bid, $cid)
    {
        $oldbid = $bid;
        $bid = BookService::decodeBidStatic($bid);
        //获取图书信息
        $book_info  = BookConfigService::getBookById($bid);
        if (empty($book_info))
            return response()->error('QAPP_SYS_ERROR');
        $this->book_info = $book_info;
        //获取章节信息
        $chapter = ChapterService::getChapterNameById($cid, $bid);
        if (!$chapter) {
            return response()->error('QAPP_SYS_ERROR');
        }

        $is_next_day = date('Y-m-d', strtotime($this->user_info->created_at)) == date('Y-m-d', strtotime('-1 days'));
        if ($is_next_day) {
            $job = new UserRententionJob($this->uid, now(), $this->user_info->created_at);
            dispatch($job)->onConnection('rabbitmq')->onQueue('user_rentention_queue');
        }

        if ($chapter->is_vip == 0) {
            ReadRecordService::addReadRecord([
                'uid' => $this->uid, 'bid' => $bid, 'book_name' => $book_info->book_name,
                'cid' => $cid, 'chapter_name' => $chapter->name
            ]);

            return response()->item(new ChapterTransformer, $this->getChapter($bid, $cid, $chapter));
        }

        //已经付费
        if ($this->getOrderRecord($bid, $cid)) {
            ReadRecordService::addReadRecord([
                'uid' => $this->uid, 'bid' => $bid, 'book_name' => $book_info->book_name,
                'cid' => $cid, 'chapter_name' => $chapter->name
            ]);

            return response()->item(new ChapterTransformer, $this->getChapter($bid, $cid, $chapter));
        }

        //未付费 要提醒
        $user_info = $this->user_info;
        //未付费 余额不足
        $fee = $this->getPrice($book_info, $chapter->size);
        $data = [
            'book_id' => $oldbid,
            'book_name' => $book_info->book_name,
            'chapter_name' => $chapter->name,
            'chapter_id' => $cid,
            'pay_type' => $book_info->charge_type,
            'fee' => $fee,
            'user_balance' => $user_info->balance,
            'product_id' => $book_info->product_id,
            'uid' => $this->uid,
            'distribution_channel_id' => $this->distribution_channel_id,
            'is_discount' => 0,
            'discount_fee' => '',
            'discount' => ''

        ];

        if ($user_info['balance'] < $fee) {
            if ($book_info->charge_type == 'BOOK') {
                return response()->error('QAPP_BOOK_INSUFFICIENT_BALANCE', $data);
            } elseif ($book_info->charge_type == 'CHAPTER') {
                return response()->error('QAPP_CHAPTER_INSUFFICIENT_BALANCE', $data);
            } else {
                return response()->error('QAPP_SYS_ERROR');
            }
        }
        //付费 不提醒
        if ($this->balancePay($book_info, $cid, $chapter->size, $chapter->name, 0)) {
            UserTaskService::addUserTaskQueue($this->uid, BaseTask::read, UserTaskService::judge_trigger);
            ReadRecordService::addReadRecord([
                'uid' => $this->uid, 'bid' => $bid, 'book_name' => $book_info->book_name,
                'cid' => $cid, 'chapter_name' => $chapter->name
            ]);

            return response()->item(new ChapterTransformer, $this->getChapter($bid, $cid, $chapter));
        } else {
            if ($book_info->charge_type == 'BOOK') {
                return response()->error('QAPP_BOOK_INSUFFICIENT_BALANCE', $data);
            } elseif ($book_info->charge_type == 'CHAPTER') {
                return response()->error('QAPP_CHAPTER_INSUFFICIENT_BALANCE', $data);
            } else {
                return response()->error('QAPP_SYS_ERROR');
            }
        }
    }



    public function pay(Request $request, $bid, $cid)
    {
        $remind = (int) $request->input('remind');
        $oldbid = $bid;
        $bid = BookService::decodeBidStatic($bid);
        $book_info = BookConfigService::getBookById($bid);;
        if (empty($book_info)) response()->error('QAPP_SYS_ERROR');

        if ($book_info->is_on_shelf == 0 || $book_info->is_on_shelf == 3) {
            if (!$this->isBookOrdered($bid)) {
                response()->error('QAPP_OFF_SHELF');
            }
        }
        //获取章节
        $chapter = ChapterService::getChapterNameById($cid, $bid);
        if (!$chapter) {
            return response()->error('QAPP_SYS_ERROR');
        }


        if ($this->balancePay($book_info, $cid, $chapter->size, $chapter->name, $remind)) {
            ReadRecordService::addReadRecord([
                'uid' => $this->uid, 'bid' => $bid, 'book_name' => $book_info->book_name,
                'cid' => $cid, 'chapter_name' => $chapter->name
            ]);

            return response()->item(new ChapterTransformer, $this->getChapter($bid, $cid, $chapter));
        } else {
            $fee = $this->getPrice($book_info, $chapter->size);

            $data = [
                'book_id' => $oldbid,
                'book_name' => $book_info->book_name,
                'chapter_name' => $chapter->name,
                'chapter_id' => $cid,
                'pay_type' => $book_info->charge_type,
                'fee' => $fee,
                'user_balance' => $this->user_info['balance'],
                'product_id' => $book_info->product_id,
                'uid' => $this->uid,
                'distribution_channel_id' => $this->distribution_channel_id,
                'is_discount' => 0,
                'discount_fee' => '',
                'discount' => ''
            ];
            if ($book_info->charge_type == 'BOOK') {
                return response()->error('QAPP_BOOK_INSUFFICIENT_BALANCE', $data);
            } elseif ($book_info->charge_type == 'CHAPTER') {
                return response()->error('QAPP_CHAPTER_INSUFFICIENT_BALANCE', $data);
            } else {
                return response()->error('QAPP_SYS_ERROR');
            }
        }
    }



    /**
     * 余额支付
     * @param $book_info
     * @param $chapter_id
     * @param $chapter_size
     * @return bool
     */
    protected function balancePay($book_info, $chapter_id, $chapter_size, $chapter_name, $is_remind)
    {
        $fee = $this->getPrice($book_info, $chapter_size);
        if ((int) $this->user_info['balance'] >= $fee) {
            if ($this->bookOrderOrChapterOrder($book_info, $chapter_id, $fee, $chapter_name, $is_remind)) {
                return true;
            }
            return false;
        } else {
            return false;
        }
    }


    /**
     * 获取章节内容
     * @param $bid
     * @param $cid
     * @return bool|mixed
     */
    protected function getChapter($bid, $cid, $chapter)
    {
        $chapter_content = ChapterService::getChapter($bid, $cid);
        if (!$chapter_content) return false;
        $chapter->content = trim(str_replace($chapter_content->name, '', $chapter_content->content));
        //统计点击率
        $key = 'book_click_num_bid_' . $bid;
        $field = date('Y-m-d');
        $old = Redis::hget($key, $field);
        if (!$old)  $old = 0;
        Redis::hset($key, $field, $old + 1);
        $force_add_desk_type = $this->addDesktopType($bid, $chapter->sequence);
        $chapter->force_add_desk_type = $force_add_desk_type;
        //统计
        $this->stats();
        return $chapter;
    }

    /**
     * 添加订购记录
     * @param $book_info
     * @param $chapter_id
     * @param $fee
     * @return bool
     */
    protected function bookOrderOrChapterOrder($book_info, $chapter_id, $fee, $chapter_name, $is_remind)
    {
        if ($book_info['charge_type'] == 'BOOK') {
            $data = [
                'uid' => $this->uid,
                'fee' => $fee,
                'u' => $this->send_order_id,
                'distribution_channel_id' => $this->distribution_channel_id,
                'bid' => $book_info->bid,
                'book_name' => $book_info->book_name,
                'send_order_id' => $this->send_order_id,
            ];
            return BookOrderService::addOrderRecodeAndDecrUserBalance($data, $this->uid);
        } else {
            $data = [
                'uid' => $this->uid,
                'fee' => $fee,
                'cid' => $chapter_id,
                'bid' => $book_info->bid,
                'distribution_channel_id' => $this->distribution_channel_id,
                'book_name' => $book_info->book_name,
                'chapter_name' => $chapter_name,
                'send_order_id' => $this->send_order_id,
                'is_remind' => $is_remind
            ];
            if ($is_remind) {
                $this->addOrderRemind($book_info->bid);
            }
            return ChapterOrderService::addOrderAndDecrUserBalance($data, $this->uid);
        }
    }


    protected  function  addOrderRemind($bid)
    {
        if (ChapterReminderService::checkIsNoReminder($this->uid, $bid)) {
            return true;
        } else {
            ChapterReminderService::add($this->uid, $bid);
            return true;
        }
    }
    /**
     * 是否订购提醒
     * @param $chapter_id
     * @return bool
     */
    protected function isOrderRemind($bid)
    {
        $is_no_reminder = ChapterReminderService::checkIsNoReminder($this->uid, $bid) ? 1 : 0;
        return $is_no_reminder == 0;
    }

    /**
     * 用户是否关注
     * @param $uid
     * @return bool
     */
    protected  function getSubscribe()
    {
        $res = ForceSubscribeService::forceSubscribeUsersByUid(['uid' => $this->uid]);
        if ($res) return true;
        return false;
    }


    /**
     * 获取订购记录
     * @param $book_info
     * @param $chapter_id
     * @return bool
     */
    protected function getOrderRecord($bid, $chapter_id)
    {
        //包年记录
        $uid = $this->uid;
        $res = YearOrderService::getRecord($uid);
        if ($res) return true;
        $res = null;

        //单本订购记录
        $res = BookOrderService::getRecordByuidBid($uid, $bid);
        if ($res) return true;
        $res = null;

        //章节订购记录
        $chapterOrder = new ChapterOrderService();

        if ($chapterOrder->checkIsOrdered($uid, $bid, $chapter_id))  return true;

        return false;
    }


    /**
     * 计算价格
     * @param $book_info
     * @param $chapter_size
     * @return float
     */
    private function getPrice($book_info, $chapter_size = 0)
    {
        if ($book_info->charge_type == 'BOOK') {
            if (BookOrderService::isHasBookOrder($this->uid)) {
                $this->is_first_book_order = 0;
                return 1399;
            } else {
                $this->is_first_book_order = 1;
                return  899;
            }
        } else {
            $fee = BookService::getPrice($book_info, $this->distribution_channel_id, $chapter_size);
            return $fee;
        }
    }



    /**
     * 用户添加标签
     * @param $book_info
     */
    protected function addTag($book_info)
    {
        if (!UserDeepReadTagService::isAddTag($this->uid, $book_info->bid)) {
            try {
                UserDeepReadTagService::addTag([
                    'uid' => $this->uid,
                    'bid' => $book_info->bid,
                    'book_name' => $book_info->book_name,
                    'category_id' => $book_info->category_id,
                    'category_name' => $book_info->category_name,
                    'sex_preference' => $book_info->channel_name ? $book_info->channel_name : '',
                    'distribution_channel_id' => $this->distribution_channel_id ? $this->distribution_channel_id : '0',
                    'send_order_id' => $this->send_order_id,
                ]);
            } catch (\Exception  $e) {
            }
        }
    }


    protected function isBookOrdered($bid)
    {

        $chapter_order = ChapterOrderService::checkBookIsOrdered($this->uid, $bid);
        if ($chapter_order) return true;

        $res = BookOrderService::getRecordByuidBid($this->uid, $bid);
        if ($res) return true;
        return false;
    }

    /**
     * 判断是否需要充值
     */
    private function isBookNeedCharge(int $bid, float $price)
    {
        $book_order = $this->getOrderRecord($bid, 0);
        if ($book_order) {
            return false;
        } else {
            $user_info = $this->user_info;
            return $user_info['balance'] < $price;
        }
    }

    /**
     * 判断章节是否需要充值
     */
    private function isChapterNeedCharge(int $bid, int $cid, float $price)
    {
        $book_order = $this->getOrderRecord($bid, $cid);
        if ($book_order) {
            return false;
        } else {
            $user_info = $this->user_info;
            return $user_info['balance'] < $price;
        }
    }


    private function stats()
    {
        //阅读器统计
        WapVisitStatService::recordReaderUvAndPv($this->uid, $this->distribution_channel_id);
    }

    //加桌类型
    private function addDesktopType($bid, $sequence)
    {
        $force_add_desk_type = 0;
        $send_order_id = ReadRecordService::getSendOrderId($this->uid);
        if (!$send_order_id) return $force_add_desk_type;
        $send_order_info = SendOrderService::getById($send_order_id);
        if (!$send_order_info)  return $force_add_desk_type;
        if ($send_order_info->book_id == $bid) {
            if ($send_order_info->force_add_desk_type == 1 && $send_order_info->force_add_desk_seq) {
                if($sequence >= $send_order_info->force_add_desk_seq){
                    $force_add_desk_type = $send_order_info->force_add_desk_type;
                }
            }
            if ($send_order_info->force_add_desk_type == 2) {
                if ($sequence >= $this->book_info->force_subscribe_chapter_seq && $sequence <= $this->book_info->force_subscribe_chapter_seq + 3) {
                    $force_add_desk_type = $send_order_info->force_add_desk_type;
                }
            }
        }
        return $force_add_desk_type;
    }
}