<?php

namespace App\Http\Controllers\QuickApp\Book;

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\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;

class ChapterController extends BaseController
{

    /**
     * @apiDefine Chapter 章节
     */

    /**
     * @apiVersion 1.0.0
     * @apiDescription 章节列表不分页
     * @api {get} books/{bid}/allcatalog 章节列表不分页
     * @apiParam {String}  [token]  token
     * @apiHeader {String} [Authorization]  token 两个token任选其一
     * @apiGroup Chapter
     * @apiName getCatalog
     * @apiSuccess {int}         code 状态码
     * @apiSuccess {String}      msg  信息
     * @apiSuccess {object}      data 结果集
     * @apiSuccess {Array}       data.list 分页结果集
     * @apiSuccess {Int}         data.list.bid   bid
     * @apiSuccess {Int}         data.list.chapter_id   章节id
     * @apiSuccess {String}      data.list.chapter_name   章节名称
     * @apiSuccess {Int}         data.list.chapter_sequence   序号
     * @apiSuccess {Int}         data.list.chapter_is_vip   是否vip
     * @apiSuccess {Int}         data.list.chapter_size   章节大小
     * @apiSuccess {Int}         data.list.prev_cid   上一章节id
     * @apiSuccess {Int}         data.list.next_cid   下一章节
     * @apiSuccess {String}      data.list.recent_update_at   更新时间
     * @apiSuccess {Int}      data.list.is_need_charge  是否需要充值
     * @apiSuccess {object}      data.meta   分页信息
     * @apiSuccess {Int}         data.meta.total  总条数
     * @apiSuccess {Int}         data.meta.per_page  每页条数
     * @apiSuccess {Int}         data.meta.current_page 当前页
     * @apiSuccess {Int}         data.meta.last_page  最后页
     * @apiSuccess {String}      data.meta.next_page_url  下一页
     * @apiSuccess {String}      data.meta.prev_page_url  上一页
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data:
     *            [
     *             {
     *               bid: 5,
     *               chapter_id: 5,
     *               chapter_name: "第1240章 不是我",
     *               chapter_sequence: 1239,
     *               chapter_is_vip: 1,
     *               chapter_size: 2422,
     *               prev_cid: 0,
     *               next_cid: 0,
     *               recent_update_at: 2017-11-20 15:01:56,
     *               is_need_charge: 0,
     *            },
     *             {
     *               bid: 5,
     *               chapter_id: 5,
     *               chapter_name: "第1240章 不是我",
     *               chapter_sequence: 1239,
     *               chapter_is_vip: 1,
     *               chapter_size: 2422,
     *               prev_cid: 0,
     *               next_cid: 0,
     *               recent_update_at: 2017-11-20 15:01:56,
     *               is_need_charge: 0,
     *            },
     *          ]
     *       }
     */
    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);
    }

    /**
     * @apiVersion 1.0.0
     * @apiDescription 章节列表分页
     * @api {get} books/{bid}/catalog 章节列表分页
     * @apiParam {String}  [token]  token
     * @apiHeader {String} [Authorization]  token 两个token任选其一
     * @apiGroup Chapter
     * @apiName getCatalogPerPage
     * @apiParam   {Int}         page_size  分页大小(默认15)
     * @apiParam   {Int}         page  页码(默认1)
     * @apiSuccess {int}         code 状态码
     * @apiSuccess {String}      msg  信息
     * @apiSuccess {object}      data 结果集
     * @apiSuccess {Array}       data.list 分页结果集
     * @apiSuccess {Int}         data.list.bid   bid
     * @apiSuccess {Int}         data.list.chapter_id   章节id
     * @apiSuccess {String}      data.list.chapter_name   章节名称
     * @apiSuccess {Int}         data.list.chapter_sequence   序号
     * @apiSuccess {Int}         data.list.chapter_is_vip   是否vip
     * @apiSuccess {Int}         data.list.chapter_size   章节大小
     * @apiSuccess {Int}         data.list.prev_cid   上一章节id
     * @apiSuccess {Int}         data.list.next_cid   下一章节
     * @apiSuccess {String}      data.list.recent_update_at   更新时间
     * @apiSuccess {Int}      data.list.is_need_charge  是否需要充值
     * @apiSuccess {object}      data.meta   分页信息
     * @apiSuccess {Int}         data.meta.total  总条数
     * @apiSuccess {Int}         data.meta.per_page  每页条数
     * @apiSuccess {Int}         data.meta.current_page 当前页
     * @apiSuccess {Int}         data.meta.last_page  最后页
     * @apiSuccess {String}      data.meta.next_page_url  下一页
     * @apiSuccess {String}      data.meta.prev_page_url  上一页
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data:
     *            list:[
     *             {
     *               bid: 5,
     *               chapter_id: 5,
     *               chapter_name: "第1240章 不是我",
     *               chapter_sequence: 1239,
     *               chapter_is_vip: 1,
     *               chapter_size: 2422,
     *               prev_cid: 0,
     *               next_cid: 0,
     *               recent_update_at: 2017-11-20 15:01:56,
     *               is_need_charge: 0,
     *            },
     *             {
     *               bid: 5,
     *               chapter_id: 5,
     *               chapter_name: "第1240章 不是我",
     *               chapter_sequence: 1239,
     *               chapter_is_vip: 1,
     *               chapter_size: 2422,
     *               prev_cid: 0,
     *               next_cid: 0,
     *               recent_update_at: 2017-11-20 15:01:56,
     *               is_need_charge: 0,
     *            },
     *          ]
     *          meta:{
     *              total: 1253,
     *              per_page: 15,
     *              current_page: 1,
     *              last_page: 84,
     *              next_page_url: "http://myapi.cn/api/books/1/chapter?page=2",
     *              prev_page_url: ""
     *         }
     *       }
     */
    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;
    }


    /**
     * @apiVersion 1.0.0
     * @apiDescription 章节内容
     * @api {get} books/{bid}/chapters/{chapter_id} 章节内容
     * @apiParam {String}  [token]  token
     * @apiHeader {String} [Authorization]  token 两个token任选其一
     * @apiGroup Chapter
     * @apiName index
     * @apiSuccess {int}         code 状态码
     * @apiSuccess {String}      msg  信息
     * @apiSuccess {object}      data 结果集
     * @apiSuccess {Int}         data.chapter_id   章节id
     * @apiSuccess {String}      data.chapter_name   章节名称
     * @apiSuccess {Int}         data.chapter_sequence   序号
     * @apiSuccess {Int}         data.chapter_is_vip   是否vip
     * @apiSuccess {Int}         data.chapter_size   章节大小
     * @apiSuccess {Int}         data.prev_cid   上一章节id
     * @apiSuccess {Int}         data.next_cid   下一章节
     * @apiSuccess {String}      data.recent_update_at   更新时间
     * @apiSuccess {String}      data.chapter_content  章节内容
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data: {
     *               chapter_id: 5,
     *               chapter_name: "第1240章 不是我",
     *               chapter_sequence: 1239,
     *               chapter_is_vip: 1,
     *               chapter_size: 2422,
     *               prev_cid: 0,
     *               next_cid: 0,
     *               recent_update_at: 2017-11-20 15:01:56,
     *               chapter_content: "叶妩被司行霈的阴阳怪气一吓,思路偏得太远了。 她张口结舌,忘记了自己要说什么。",
     *            }
     *       }
     */
    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');
        //获取章节信息
        $chapter = ChapterService::getChapterNameById($cid, $bid);
        if (!$chapter) {
            return response()->error('QAPP_SYS_ERROR');
        }
        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)) {

            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');
            }
        }
    }



    /**
     * @apiVersion 1.0.0
     * @apiDescription 余额支付
     * @api {get} books/{bid}/balance/chapterOrders/{cid} 余额支付
     * @apiParam {String}  [token]  token
     * @apiHeader {String} [Authorization]  token 两个token任选其一
     * @apiGroup Chapter
     * @apiName pay
     * @apiParam   (Int)         remind 提醒
     * @apiSuccess {int}         code 状态码
     * @apiSuccess {String}      msg  信息
     * @apiSuccess {object}      data 结果集
     * @apiSuccess {Int}         data.chapter_id   章节id
     * @apiSuccess {String}      data.chapter_name   章节名称
     * @apiSuccess {Int}         data.chapter_sequence   序号
     * @apiSuccess {Int}         data.chapter_is_vip   是否vip
     * @apiSuccess {Int}         data.chapter_size   章节大小
     * @apiSuccess {Int}         data.prev_cid   上一章节id
     * @apiSuccess {Int}         data.next_cid   下一章节
     * @apiSuccess {String}      data.recent_update_at   更新时间
     * @apiSuccess {String}      data.chapter_content  章节内容
     * @apiSuccessExample {json} Success-Response:
     *     HTTP/1.1 200 OK
     *     {
     *       code: 0,
     *       msg: "",
     *       data: {
     *               chapter_id: 5,
     *               chapter_name: "第1240章 不是我",
     *               chapter_sequence: 1239,
     *               chapter_is_vip: 1,
     *               chapter_size: 2422,
     *               prev_cid: 0,
     *               next_cid: 0,
     *               recent_update_at: 2017-11-20 15:01:56,
     *               chapter_content: "叶妩被司行霈的阴阳怪气一吓,思路偏得太远了。 她张口结舌,忘记了自己要说什么。",
     *            }
     *       }
     */
    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);
        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
     */
    protected function getPrice($book_info, $chapter_size = 0)
    {
        if ($book_info->charge_type == 'BOOK')
            return $book_info->price * 100;
        return   ceil($chapter_size / 100);
    }




    /**
     * 用户添加标签
     * @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 = BookOrderService::getRecordByuidBid($this->uid, $bid);
        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)
    {
        $chapter_order = ChapterOrderService::checkIsOrderedStatic($this->uid, $bid, $cid);
        if ($chapter_order) {
            return false;
        } else {
            $user_info = $this->user_info;
            return $user_info['balance'] < $price;
        }
    }
}