<?php

namespace App\Modules\Activity\Services;

use App\Consts\SysConsts;
use App\Modules\Activity\Models\ActivityNationalDay;
use App\Modules\User\Services\UserService;
use Redis;
use DB;
use Exception;

/**
 * 个人微信号——用户国庆活动
 * @property int $uid
 * @property int $sign_day 累计签到天数
 * @property bool $is_sign 今天是否已签到
 * @property int $bonus 今天签到获取奖金币
 */
class UserNationalDay
{
    use NationalDay {
        __construct as private baseConfig;
    }

    private $uid;
    public $is_sign;
    public $sign_day;
    public $bonus;

    public function __construct(int $uid)
    {
        $this->baseConfig();
        $this->uid = $uid;
        $this->sign_day = $this->getUserSignDays();
        $this->is_sign = $this->judgeIsSign();
    }

    /**
     * 签到
     */
    public function sign()
    {
        if ($this->is_begin && !$this->is_sign) {
            $this->sign_day++;
            $this->bonus = $this->getSignBonusMoney($this->sign_day);
            $this->saveRedisSign();
            $this->saveSign();
        }
    }

    /**
     * 获取用户签到配置项
     */
    public function getSignConfigs()
    {
        return collect($this->sign_config)->map(function ($item) {
            $item['is_get'] = $item['day'] <= $this->sign_day;
            return $item;
        })->all();
    }

    /**
     * 判断今天用户是否签到
     * @return bool
     */
    private function judgeIsSign()
    {
        $result = Redis::sismember($this->redis_key, $this->uid);
        if (!$result) {
            $result = ActivityNationalDay::where('uid', $this->uid)->where('created_at', '>=', date('Y-m-d'))->exists();
            if ($result) {
                $this->saveRedisSign();
            }
        }
        return $result;
    }

    /** 
     * 获取用户累计签到天数
     */
    private function getUserSignDays()
    {
        return ActivityNationalDay::where('uid', $this->uid)->count();
    }

    /**
     * redis签到
     */
    private function saveRedisSign()
    {
        Redis::sAdd($this->redis_key, $this->uid);
        Redis::expire($this->redis_key, SysConsts::ONE_DAY_SECONDS);
    }

    /**
     * 保存签到信息
     */
    private function saveSign()
    {
        try {
            DB::beginTransaction();
            $day = new  ActivityNationalDay;
            $day->uid = $this->uid;
            $day->bonus = $this->bonus;
            $day->save();
            UserService::addBalance($this->uid, $this->bonus, 0, $this->bonus);
            DB::commit();
        } catch (Exception $e) {
            Log::error('national_day: ' . $e->getMessage());
            DB::rollback();
        }
    }
}
