<?php

namespace App\Http\Controllers\V1\User;

use App\Http\Controllers\V1\Controller;
use App\Models\UserConsumeRecord;
use App\Models\UserInfo;
use App\Models\UserSignRecord;
use Carbon\Carbon;
use Illuminate\Database\QueryException;

class SignController extends Controller
{
    public function setting()
    {
        $setting   = config('global.sign_config');
        $signDays  = $this->checkSignDays();
        $todaySign = $this->checkTodaySign();

        return $this->success([
            'setting'   => $setting,
            'signDays'  => $signDays + $todaySign,
            'todaySign' => $todaySign,
        ]);
    }

    public function handle()
    {
        if ($this->checkTodaySign()) {
            return $this->error('今天已经签到了，明天再来吧');
        }
        $setting  = config('global.sign_config');
        $signDays = $this->checkSignDays();
        $today    = Carbon::now()->toDateString();
        $award    = $setting[$signDays + 1]['award'];

        try {
            \DB::beginTransaction();
            $sign          = new UserSignRecord();
            $sign->user_id = \user()->id;
            $sign->date    = $today;
            $sign->award   = $award;
            $sign->save();

            $user = UserInfo::find(\user()->id);

            // 记录日志
            app(UserConsumeRecord::class)->record(
                \user()->id,
                UserConsumeRecord::TYPE_SIGN,
                $award,
                "{$today}签到奖励"
            );

            // 发放奖励
            $user->integral       = $user->integral       + $award;
            $user->total_integral = $user->total_integral + $award;
            $user->save();

            \DB::commit();

            return $this->success(['award' => $award]);
        } catch (QueryException $e) {
            \DB::rollBack();

            return $this->error('签到失败');
        } catch (\Exception $ex) {
            \DB::rollBack();

            return $this->error('签到失败');
        }
    }

    private function checkTodaySign()
    {
        $today = Carbon::now()->toDateString();

        return UserSignRecord::filterUser()->where('date', $today)->count();
    }

    // 校验连续签到了多少天
    private function checkSignDays()
    {
        $today   = Carbon::now()->toDateString();
        $records = UserSignRecord::filterUser()->where('date', '<', $today)->orderByDesc('id')->limit(7)->get();

        $dates = $records->pluck('date')->toArray();

        rsort($dates);
        $continuedDays = 0;

        $days = static::getDays();

        // 连续签到了七天，从头开始
        if (!array_diff($days, $dates)) {
            return $continuedDays;
        }
        $count = 0;

        foreach ($dates as $date) {
            if (!static::isContinuedSign($date, $count++)) {
                break;
            }
            $continuedDays++;
        }

        return $continuedDays;
    }

    private static function isContinuedSign($date = [], $day = 0)
    {
        $days = static::getDays();
        $day  = $days[$day];

        return $day == $date;
    }

    // 获取持续时间
    private static function getDays($days = 7)
    {
        $startTime = Carbon::now()->subDays($days)->timestamp;
        $endTime   = Carbon::now()->subDays(1)->timestamp;
        $days      = range($startTime, $endTime, 24 * 60 * 60);

        $days = array_map(function ($day) {
            return date('Y-m-d', $day);
        }, $days);
        rsort($days);

        return $days;
    }
}
