<?php

namespace App\Http\Controllers;

use App\Facades\WechatService;
use App\Jobs\AddErrorLog;
use App\Models\User;
use App\Models\UserInfo;
use App\Models\UserStep;
use App\Models\UserStepApply;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class StepController extends Controller
{
    public function getUserStep(Request $request)
    {
        try {
            $code = $request->input('code');
            $iv = $request->input('iv');
            $encryptedData = $request->input('encryptedData');
            if (empty($code)) return $this->failure('未获取到code');

            $user = auth()->user();
            if (!$user->stature) {
                return $this->failure('请设置您的身高');
            }
            $weight = UserInfo::query()->where('user_id', $user->id)->value('weight');
            if (!$weight) {
                return $this->failure('请设置您的体重');
            }

            $user_step = WechatService::getUserStep($code,$iv,$encryptedData);

            $step_list = $user_step['stepInfoList'];
            foreach ($step_list as $item) {
                if ($item['step'] == 0) {
                    continue;
                }
                $date = date('Y-m-d', $item['timestamp']);
                UserStep::query()->updateOrCreate(
                    ['user_id' => $user->id, 'date' => $date],
                    ['user_id' => $user->id, 'date' => $date, 'step' => $item['step']]
                );
            }

            $date = date('Y-m-d');
            $yesterday_step = $step_list[count($step_list) - 2]['step'] ?? 0;

            $cal = get_cal_by_step($user_step['step'],$user->stature,$weight);
            $km = get_km_by_step($user_step['step'],$user->stature);

            $today_count = UserStep::query()->where('date', $date)->count();
            $exceed_count = UserStep::query()->where('date', $date)
                ->where('step', '<', $user_step['step'])
                ->count();

            $exceed_ratio = '0%';

            if ($today_count) {
                if ($today_count == 1 & $exceed_count == 0) {
                    $exceed_ratio = 100;
                } else {
                    $exceed_ratio = number_format($exceed_count / $today_count * 100, 2);
                }
                $exceed_ratio .= '%';
            }

            $max_step_data = UserStep::query()->where('user_id',$user->id)
                ->orderByDesc('step')
                ->first();

            $data = [
                'step' => $user_step['step'],
                'cal' => $cal,
                'km' => $km,
                'yesterday_step' => $yesterday_step,
                'exceed_ratio' => $exceed_ratio,
                'history_max' => [
                    'date' => $max_step_data->date ?? $date,
                    'step' => $max_step_data->step ?? 0,
                    'cal' => $max_step_data ? get_cal_by_step($max_step_data->step,$user->stature,$weight) : 0
                ]
            ];

            return $this->success('ok',$data);
        }catch (\Exception $e){
            Log::error('getUserStep:'.$e->getMessage());
            return $this->failure($e->getMessage());
        }
    }

    /**
     * 步数排行榜
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getStepRanks(Request $request)
    {
        try {
            $data = UserStep::query()->with('user:id,name,avatar')
                ->where('date',date('Y-m-d'))
                ->orderByDesc('step')
                ->paginate();
            return $this->success('ok',$data);
        }catch (\Exception $e){
            Log::error('getUserStepRanks:'.$e->getMessage());
            return $this->failure($e->getMessage());
        }
    }

    /**
     * 获取历史步数
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getHistoryStep(Request $request)
    {
        try {
            $user = auth()->user();
            $data = UserStep::query()->where('user_id',$user->id)
                ->orderByDesc('date')
                ->paginate();
            return $this->success('ok',$data);
        }catch (\Exception $e){
            Log::error('getHistoryStep:'.$e->getMessage());
            return $this->failure($e->getMessage());
        }
    }

    /**
     * 保存身高体重数据
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function saveBodyData(Request $request)
    {
        try {
            $user = auth()->user();
            $stature = $request->input('stature', 0);
            if (!is_numeric($stature)) {
                return $this->failure('身高参数错误');
            }
            $weight = $request->input('weight', 0);
            if (!is_numeric($weight)) {
                return $this->failure('体重参数错误');
            }
            DB::beginTransaction();
            if ($stature) {
                User::where('id', $user->id)->update(compact('stature'));
            }
            if ($weight) {
                UserInfo::where('user_id', $user->id)->update(compact('weight'));
            }
            DB::commit();
            return $this->success('ok');
        } catch (\Exception $e) {
            DB::rollback();
            Log::error('saveBodyData:' . $e->getMessage());
            return $this->failure($e->getMessage());
        }
    }

    public function applyStep(){
        try {
            $user = auth()->user();
            $exists = UserStepApply::where('user_id',$user->id)->whereIn('status',[UserStepApply::STATUS_APPLY,UserStepApply::STATUS_PASS])->exists();
            if($exists) return $this->failure('您已申请，等待审核');
            UserStepApply::create(['user_id'=>$user->id]);
            return $this->success('ok');
        }catch (\Exception $e){
            AddErrorLog::dispatch('applyStep file:'.$e->getFile().' line:'.$e->getLine().' message:'.$e->getMessage())->onQueue('health');
            return $this->failure('申请失败');
        }
    }
}