<?php

/**
 * Created by PhpStorm.
 * User: hp
 * Date: 2017/11/21
 * Time: 10:42
 */

namespace App\Modules\User\Services;

use App\Modules\Book\Services\BookService;
use App\Modules\User\Models\ReadRecordFromRedis;
use Redis;
use Hashids;
use App\Modules\Book\Services\BookConfigService;
use App\Modules\Book\Models\Chapter;
use App\Modules\User\Models\ReadLog;
use DB;

class ReadRecordService
{
    public static function getBookReadRecordStatic(int $uid, int $bid)
    {
        $record = Redis::hGet('book_read:' . $uid, $bid);
        if ($record) {
            $cid  = explode('_', $record)[0];
            $name = self::cid2ChapterName($cid,0);
            return ['record_chapter_id' => $cid, 'record_chapter_name' => $name];
        }
        return false;
    }

    /**
     * 删除最近阅读记录
     * @param int   $uid
     * @param array $bids
     */
    public static function delReadRecordStatic(int $uid, array $bids)
    {
        $key             = 'book_read:' . $uid;
        $last_record     = explode('_', Redis::hGet($key, 'last_read'));
        $last_record_bid = $last_record[0];
        $is_del_last     = false;
        foreach ($bids as $bid) {
            if ($bid == $last_record_bid) {
                $is_del_last = true;
            }
            Redis::hDel($key, $bid);
        }
        if ($is_del_last) {
            self::reSetLastRecord($uid);
        }
    }

    /**
     * 重置用户最近阅读记录
     * @param int $uid
     */
    public static function reSetLastRecord($uid)
    {
        $key            = 'book_read:' . $uid;
        $alls           = Redis::hGetAll($key);
        $has_record     = false;
        $last_timestamp = 0;
        $last_record    = '';
        foreach ($alls as $k => $v) {
            if (is_numeric($k)) {
                $has_record = true;
                $record     = explode('_', $v);
                $timestamp  = $record[1];
                if ($last_timestamp < $timestamp) {
                    $last_record    = $k . '_' . $v;
                    $last_timestamp = $timestamp;
                }
            }
        }
        if ($last_record) {
            Redis::hSet($key, 'last_read', $last_record);
        }
        if (!$has_record) {
            Redis::hDel($key, 'last_read');
        }
    }

    //阅读记录数
    const RECORD_COUNT = 50;

    private static $not_uid_key = ['last_read', 'send_order_id', 'sign_count', 'sign_counts', 'sign_info', 'sign_day', 'smart_push', 'inner_send_order_id', 'gxhp', 'property', 'bind_phone_status', 'ua', 'sign_version', 'new_outer', 'new_inner', 'new_total', 'next_push_hour', 'person_account_id'];



    /**
     * 获取 升级版
     * @param $uid
     * @return array
     */
    public static function getReadRecord($uid)
    {
        self::delTheLastRecord($uid);
        $read_bids = Redis::hgetall('book_read:' . $uid);
        $res       = [];
        $i         = 0;
        foreach ($read_bids as $key => $v) {
            if (in_array($key, self::$not_uid_key)) {
                continue;
            }
            $record           = explode('_', $v);
            $latest_read_cid  = $record[0];
            $latest_read_time = $record[count($record) - 1];
            $channel_name = '';
            $book_name        = self::bid2BookName($key,$channel_name);

            $change_chapter_name = 0;

            list($is_split,$is_change_chapter_name) = BookService::splitContent($key);
            if($is_split && ($channel_name == '男频' || $is_change_chapter_name) ){
                $change_chapter_name = 1;
            }


            $chapter_name     = self::cid2ChapterName($latest_read_cid,$change_chapter_name);
            $res[$i]          = ['book_name' => $book_name, 'bid' => $key, 'cid' => (int)$latest_read_cid, 'time' => (int)$latest_read_time, 'chapter_name' => $chapter_name];
            $i++;
        }
        usort($res, function ($a, $b) {
            if ($a['time'] >= $b['time']) return -1;
            return 1;
        });
        return collect($res)->sortByDesc('time')->values()->all();
    }


    /**
     * 添加阅读记录升级版
     * @param $param
     * @return bool
     * @throws \Exception
     */
    public static function addReadRecord($param)
    {
        // 第一章不计入阅读记录
        $sequence = (int)getProp($param, 'sequence');
//        if ($sequence <= 1) {
//            return false;
//        }

        $uid          = $param['uid'];
        $bid          = $param['bid'];
        $cid          = $param['cid'];
        $book_name    = getProp($param, 'book_name');
        $chapter_name = getProp($param, 'chapter_name');
        $book_key     = 'wap:string:book:' . $bid;
        $chapter_key  = 'wap:string:chapter:' . $cid;
        if ($book_name) {
            Redis::setex($book_key, 3600, $book_name);
        }
        if ($chapter_name) {
            Redis::setex($chapter_key, 3600, $chapter_name);
        }
        Redis::hmset('book_read:' . $uid, 'last_read', "{$bid}_{$cid}_" . time(), $bid, "{$cid}_" . time(), 'next_push_hour', 8);
        $num = random_int(1, 100);
        if ($num <= 3) {
            self::delTheLastRecord($uid);
        }

        return true;
    }

    /**
     * 获取最近一条阅读记录(升级版)
     * @param $uid
     * @return array
     */
    public static function getFirstReadRecord($uid)
    {
        self::delBookBase($uid);
        $record = Redis::hget('book_read:' . $uid, 'last_read');
        if ($record) {
            $record_arr   = explode('_', $record);
            $bid          = $record_arr[0];
            $bid          = Hashids::encode($bid);
            $cid          = $record_arr[1];
            $time         = $record_arr[2];
            $book_info    = BookConfigService::getBookById($bid);
            $book_name    = isset($book_info->book_name) ? $book_info->book_name : '';
            $cover        = isset($book_info->cover) ? $book_info->cover : '';
            $channel_name = isset($book_info->channel_name) ? $book_info->channel_name : '';
            $res          = [
                'url'          => '/reader?bid=' . $bid . '&cid=' . $cid,
                'book_name'    => $book_name,
                'cover'        => $cover,
                'channel_name' => $channel_name,
                'time'         => $time
            ];
            return $res;
        }
        return [];
    }

    /**
     * 获取简单阅读记录
     * @param $uid
     * @return int
     */
    public static function getSimpleFirstReadRecord($uid)
    {
        try {
            $record = Redis::hget('book_read:' . $uid, 'last_read');
            if ($record) {
                $record_arr = explode('_', $record);
                $bid        = $record_arr[0];
                return (int)$bid;
            }
        } catch (\Exception $e) {
        }
        return 0;
    }


    /**
     * 获取某本书的阅读记录
     */
    public static function getRecordByUidBid($uid, $bid)
    {
        return Redis::hget('book_read:' . $uid, $bid);
    }

    /**
     * 根据bid获取书名
     * @param $bid
     * @return bool|null|string
     */
    public static function bid2BookName($bid,&$channel_name)
    {
        $book_key  = 'wap:string:book:' . $bid;
        $book_name = Redis::get($book_key);
        Redis::EXPIRE($book_key, 3600);
        if (!$book_name) {
            $book_name = '';
            $book_info = BookConfigService::getBookById($bid);
            if ($book_info && isset($book_info->book_name)) {
                $book_name = $book_info->book_name;
                $channel_name = $book_info->channel_name;
            }
        }
        return $book_name;
    }

    /**
     * 根据cid获取章节名
     * @param $cid
     * @return bool|null|string
     */
    public static function cid2ChapterName($cid,$change_chapter_name)
    {
        $chapter_key  = 'wap:string:chapter:' . $cid;
        $chapter_name = Redis::get($chapter_key);
        Redis::EXPIRE($chapter_key, 3600);
        if (!$chapter_name) {
            $chapter_name = '';
            $chapter_info = Chapter::getChapterNameById($cid);
            if ($chapter_info && isset($chapter_info->name)) {
                //$chapter_name = $chapter_info->name;
                if($change_chapter_name){
                    $chapter_name = '第'.$chapter_info->sequence.'章';
                }else{
                    $chapter_name = $chapter_info->name;
                }
            }
        }
        return $chapter_name;
    }


    public static function delBookBase($uid)
    {
        $base_record = Redis::hget('book_base:' . $uid, 'last_read');
        if ($base_record) {
            Redis::del('book_base:' . $uid);
            Redis::hset('book_read:' . $uid, 'last_read', $base_record);
        }
    }

    /**
     * 获取简单阅读记录只有bid
     * @param int $uid
     * @return array
     */
    public static function getSimpleReadRecord(int $uid): array
    {
        $read_bids = Redis::hgetall('book_read:' . $uid);
        $res       = [];
        if (!$read_bids) {
            return $res;
        }
        foreach ($read_bids as $key => $v) {
            if (in_array($key, self::$not_uid_key)) {
                continue;
            }
            array_push($res, $key);
        }
        return $res;
    }


    /**
     * 获取当前的send_order_id
     * @param int $uid
     * @return int
     */
    public static function getSendOrderId(int $uid)
    {
        try {
            $send_order_id = Redis::hget('book_read:' . $uid, 'send_order_id');
            if ($send_order_id)
                return (int)$send_order_id;
        } catch (\Exception $e) {
        }
        return 0;
    }

    /**
     * 签到日期
     * @param int $uid
     * @return mixed
     */
    public static function getSignDay(int $uid)
    {
        try {
            return Redis::hget('book_read:' . $uid, 'sign_day');
        } catch (\Exception $e) {
        }
        return -1;
    }

    public static function setSignDay(int $uid)
    {
        return Redis::hset('book_read:' . $uid, 'sign_day', date('Y-m-d'));
    }

    /**
     * 签到次数和日期
     * @param int $uid
     */
    public static function sign(int $uid, bool $is_incr)
    {
        try {
            if ($is_incr) {
                Redis::hincrby('book_read:' . $uid, 'sign_counts', 1);
            } else {
                self::setSignCount($uid, 1);
            }
            self::setSignDay($uid);
        } catch (\Exception $e) {
            \Log::info('sign_ept:' . $e->getMessage());
        }
        return;
    }

    /**
     * @param int $uid
     * @return int
     */
    public static function getSignCount(int $uid)
    {
        try {
            $count = Redis::hget('book_read:' . $uid, 'sign_counts');
            if ($count) {
                return $count;
            }
        } catch (\Exception $e) {
        }
        return 0;
    }

    /**
     * 获取简单签到次数
     * @param int $uid
     * @return int
     */
    public static function getSignCountSimple(int $uid)
    {
        try {
            $count = Redis::hget('book_read:' . $uid, 'sign_counts');
            if ($count) {
                return (int)$count;
            }
            return 0;
        } catch (\Exception $e) {
        }
        return 0;
    }

    public static function setSignCount(int $uid, int $count)
    {
        Redis::hset('book_read:' . $uid, 'sign_counts', $count);
    }


    public static function setSignInfo(int $uid, string $info)
    {
        Redis::hset('book_read:' . $uid, 'sign_info', $info);
    }



    public static function getByField(int $uid, $field)
    {
        try {
            return Redis::hget('book_read:' . $uid, $field);
        } catch (\Exception $e) {
        }
        return '';
    }

    public static function getByMultiField(int $uid, ...$field)
    {
        try {
            return Redis::hmget('book_read:' . $uid, $field);
        } catch (\Exception $e) {
        }
        return '';
    }

    public static function setByField(int $uid, $field, $value)
    {
        if (!in_array($field, self::$not_uid_key)) {
            return false;
        }
        try {
            return Redis::hset('book_read:' . $uid, $field, $value);
        } catch (\Exception $e) {
        }
        return '';
    }

    public static function setByMultiField(int $uid, $kv)
    {
        $keys = array_keys($kv);
        foreach ($keys as $field) {
            if (!in_array($field, self::$not_uid_key)) {
                return false;
            }
        }
        try {
            return Redis::hmset('book_read:' . $uid, $kv);
        } catch (\Exception $e) {
        }
        return '';
    }


    //删除多余的阅读纪律
    public static function delTheLastRecord($uid)
    {
        $length = Redis::hlen('book_read:' . $uid);
        if ($length <= self::RECORD_COUNT + count(self::$not_uid_key)) {
            return;
        }
        $read_bids = Redis::hgetall('book_read:' . $uid);
        $i         = 0;
        foreach ($read_bids as $key => $v) {
            if (in_array($key, self::$not_uid_key)) {
                continue;
            }
            $record           = explode('_', $v);
            $latest_read_cid  = $record[0];
            $latest_read_time = $record[count($record) - 1];
            $res[$i++]        = ['bid' => $key, 'cid' => (int)$latest_read_cid, 'time' => (int)$latest_read_time];
        }
        usort($res, function ($a, $b) {
            if ($a['time'] >= $b['time']) return -1;
            return 1;
        });

        $j = 0;
        foreach ($res as $v) {
            if ($j++ >= self::RECORD_COUNT) {
                Redis::hdel('book_read:' . $uid, $v['bid']);
            }
        }
    }

    /**
     * 添加用户的阅读记录
     */
    public static function addReadLog(int $uid, array $data)
    {
        $log = ReadLog::model($uid);
        $log->create($data);
    }
}
