<?php
/**
 *
 * @file:WechatMinprogramUserService.php
 * @Date: 2023/5/19
 * @Time: 11:07
 */


namespace Modules\Channel\Services\WechatMinprogram;

use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;
use Modules\Channel\Models\MiniprogramUserVip;
use Modules\Channel\Models\Order;
use Modules\Channel\Models\Videos;
use Modules\Channel\Models\VideoSeries;
use Modules\Channel\Services\Order\OrderService;
use Modules\Manage\Models\Miniprogram;

class WechatMinprogramUserService
{
    public const WATCH_RECORD_REDIS_KEY = 'watchrecord:uid:%s';
    public const WATCH_RECORD_REDIS_FIELD_PREFIX = 'video_id:';


    /**
     *  获取微信小程序用户信息
     * name: userInfoDetail
     * @param $uid
     * date 2023/05/19 11:08
     */
    public static function userInfoDetail($uid)
    {
        $userInfo = DB::table(getMiniProgramTableName(1, 'users'))->where('id', $uid)->first();
        if (!$userInfo) {
            return $userInfo;
        }
        $ju_chang = Miniprogram::where('id', $userInfo->miniprogram_id)->value('play_name');
        $result = [
            'uid' => $userInfo->id,
            'openid' => $userInfo->openid,
            'yu_chang' => $ju_chang,
            'ranse_start_at' => $userInfo->ranse_start_at ?: "",
            'charge_coin' => $userInfo->charge_coin,
            'reward_coin' => $userInfo->reward_coin,
        ];

        return array_merge($result, self::getLevelText($uid));

    }

    /**
     *  用户等级文字
     * name: getLevelText
     * @param $uid
     * @return array
     * date 2023/05/26 15:41
     */
    public static function getLevelText($uid)
    {
        $record = self::userVipRecord($uid);
        if ($record && Carbon::now()->lt(Carbon::createFromTimestamp(strtotime($record->end_time)))) {
            return ['is_vip' => 1, 'vip_text' => "vip会员", 'vip_end' => $record->end_time];
        }
        return ['is_vip' => 0, 'vip_text' => "-", 'vip_end' => ""];

    }

    public static function isVipUser(int $uid)
    {
        $record = self::userVipRecord($uid);
        if (!$record) {
            return false;
        }
        return Carbon::now()->lt(Carbon::createFromTimestamp(strtotime($record->end_time)));
    }

    private static function userVipRecord(int $uid)
    {
        return MiniprogramUserVip::where('uid', $uid)->first();
    }

    /**
     *  根据用户查充值记录
     * name: getUserOrderList
     * @param int $uid
     * date 2023/05/19 14:57
     */
    public static function getUserOrderList(int $uid, $param)
    {
        $pool = [
            'MONTH' => '包月',
            'QUARTER' => '包季度',
            'YEAR' => '包年',
        ];
        $list = Order::join('pay_products', 'pay_products.id', '=', 'orders.pay_product_id')
            ->select('orders.price', 'orders.trade_no', "orders.video_id", 'orders.pay_end_at', 'pay_products.type', 'pay_products.price as product_price', 'orders.status','pay_products.given')
            ->where('orders.status','<>', 'UNPAID')
            ->where('orders.uid', $uid);
        if (getProp($param, 'puser_id', 0) > 0) {
            $list->where('orders.puser_id', $param['puser_id']);
        }
        if (getProp($param, 'user_id', 0) > 0) {
            $list->where('orders.user_id', $param['user_id']);
        }

        $list = $list->orderBy('orders.id', 'desc')
            ->paginate(getProp($param,'limit',15));
        $status = array_column( OrderService::getOrderPayType(), null, 'value');
        foreach ($list as $item) {
            $item->pay_name = '微信支付';
            if ($item->type == 'COIN') {
                $item->rechare_coin = $item->product_price * 100;
                $item->pay_result =- $item->product_price * 100 + $item->given;
            } elseif (isset($pool[$item->type])) {
                $item->rechare_coin = "-";
                $item->pay_result = $pool[$item->type];
            } else {
                $item->rechare_coin = "-";
                $item->pay_result = '充值';
            }
            $item->status_txt = $status[$item->status]['name'] ?? "-";
            $item->from_page = $item->video_id > 0 ? "播放页" : "充值页";
        }
        return $list;

    }

    /**
     *  观看记录
     * name: getUserWatchRecord
     * @param mixed $uid 用户id
     * @return array
     * date 2023/05/19 15:57
     */
    public static function getUserWatchRecord($uid)
    {
        $key = sprintf(self::WATCH_RECORD_REDIS_KEY, $uid);
        $record = Redis::hgetall($key);
        $result = [];
        foreach ($record as $video_field => $watch_info) {
            if (!Str::startsWith($video_field, self::WATCH_RECORD_REDIS_FIELD_PREFIX)) {
                continue;
            }
            $video_id = Str::replace(self::WATCH_RECORD_REDIS_FIELD_PREFIX, '', $video_field);
            $info = explode('_', $watch_info);
            $result[] = [
                'video_id' => $video_id,
                "video_name" =>  Videos::where('id',$video_id)->value('name'),
                'video_series_sequence' => $info[0],
                'watch_at' => get_date($info[1]),
                'watch_time' => $info[1]
            ];
        }
        usort($result, function ($item1, $item2) {
            return $item1['watch_time'] > $item2['watch_time'];
        });

        return $result;
    }

    /***
     *  用户消费记录
     * name: getUserConsumeRecord
     * @param mixed $uid
     * @param int $limit
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     * date 2023/05/26 15:40
     */
    public static function getUserConsumeRecord(mixed $uid,$limit = 15)
    {
        $tableName = 'coin_cost_record_' . ($uid % 8);
        $result = DB::table($tableName)->where('uid', $uid)->orderBy('id', 'desc')->paginate($limit);
        foreach ($result as $item) {
            $item->series_name = VideoSeries::where('video_id', $item->video_id)->where('series_sequence', $item->sequence)->select('series_name')->first()->series_name;
            $item->video_name = Videos::where('id', $item->video_id)->value('name');
            $item->coin_cost = $item->charge_coin_cost + $item->reward_coin_cost;
        }
        return $result;
    }


}
