<?php

namespace App\Http\Controllers\H5;

use App\Facades\CommonService;
use App\Http\Controllers\Controller;
use App\Http\Controllers\HealthController;
use App\Http\Response\ResponseJson;
use App\Jobs\AddErrorLog;
use App\Models\FatKind;
use App\Models\FatLog;
use App\Models\Group;
use App\Models\HealthKind;
use App\Models\HealthLog;
use App\Models\User;
use App\Services\FatService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class FatController extends Controller
{
    use ResponseJson;

    const WEIGHT_RATE = 2.2;
    const WEIGHT_JIN_LB_RATE = 1.1;
    const WEIGHT_JIN_KG_RATE = 2;

    /**
     * 体脂记录
     * @param Request $request
     */
    public function fatLogs(Request $request)
    {
        $chat_id = $request->input('chat_id');
        $group = Group::with('order')->where('chat_id', $chat_id)->first();
        if (empty($group) || empty($group->order)) return $this->failure("缺少群信息或者订单信息");
        if (empty($group->order->user_id)) return $this->failure("订单用户未完成小程序个人信息");
        $user = User::find($group->order->user_id);
        $unit = $user->unit;
        $logs = FatLog::where(['user_id' => $user->id, 'fat_name' => "体重"])->orderByDesc('id')->select('id', 'fat_name', 'fat_data', 'tested_at')->paginate();
        foreach ($logs as $log) {
            $log->yearMonth = date('Y年m月', strtotime($log->tested_at));
            $log->dayHour = date('d日 H:i', strtotime($log->tested_at));
            $log->unit = get_user_unit($user->language,$unit);
            if ($unit != 'kg') {
                if(($unit == 'lb' || $unit == '斤') && $user->language == 1){
                    $log->fat_data = get_two_float($log->fat_data * self::WEIGHT_RATE, 2);
                }else{
                    $log->fat_data = get_two_float($log->fat_data * 2, 2);
                }
            }
        }
        return $this->success('ok', $logs);
    }

    /**
     * 云康宝体脂记录,之前的结构设计就这样了,将错就错,时间来不及,等有时候再考虑重构合并吧,有缘人记得把公用的代码提取出来,这样只需要改一个地方
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|void
     */
    public function healthFatLogs(Request $request){
        try {
            $chat_id = $request->input('chat_id');
            $group = Group::with('order')->where('chat_id', $chat_id)->first();
            if (empty($group) || empty($group->order)) return $this->failure("缺少群信息或者订单信息");
            if (empty($group->order->user_id)) return $this->failure("订单用户未完成小程序个人信息");
            $user = User::find($group->order->user_id);
            $unit = $user->unit;
            $logs = HealthLog::where(['user_id' => $user->id, 'e_name' => "Weight"])->orderBy('id', 'desc')->select('id', 'e_name', 'score', 'tested_at')->paginate();
            $language = $user->language;
            foreach ($logs as $log) {
                $log->yearMonth = date('Y年m月', strtotime($log->tested_at));
                $log->dayHour = date('d日 H:i', strtotime($log->tested_at));
                $log->unit = get_user_unit($language, $unit);
                if ($unit != 'kg') {
                    if (($unit == 'lb' || $unit == '斤') && $language == User::LANGUAGE_EN) {
                        $log->score = get_two_float($log->score * self::WEIGHT_RATE, 2);
                    } else {
                        $log->score = get_two_float($log->score * self::WEIGHT_JIN_KG_RATE, 2);
                    }
                }
            }
            return $this->success('ok',$logs);
        }catch (\Exception $e){
            Log::error('healthFatLogs:'.$e->getMessage());
            return $this->failure('获取失败');
        }
    }

    /**
     * 获取云康宝体脂记录
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function healthFatLog(Request $request){
        try {
            $chat_id = $request->input('chat_id');
            $group = Group::with('order')->where('chat_id', $chat_id)->first();
            if (empty($group) || empty($group->order)) return $this->failure("缺少群信息或者订单信息");
            $tested_at = $request->input('tested_at');
            if(empty($tested_at)) throw new \Exception("缺少参数.tested_at");
            if (empty($group->order->user_id)) return $this->failure("订单用户未完成小程序个人信息");
            $user = User::find($group->order->user_id);
            $unit = $user->unit;
            $language = $user->language;
            $logs_arr = HealthLog::with('healthKind:name,e_name,unit,icon,h_icon', 'healthLevel:desc_key,name,color', 'healthLevels:name,e_name,color')
                ->where(['user_id' => $user->id, 'tested_at' => $tested_at])
                ->whereNotIn('e_name', ['WeightControl', 'FatControl', 'SinewControl', 'BodyfatMass'])
                ->select('e_name', 'score', 'desc', 'desc_key', 'tested_at', 'boundaries')
                ->get()->toArray();
            $logs = [];
            $health = new HealthController();
            if (count($logs_arr)) {
                foreach ($logs_arr as $log) {
                    if ($log['e_name'] != 'Score') {
                        $log = $health->changeUnit($log, $unit, $language);
                        $log['boundaries'] = json_decode($log['boundaries'], true);
                        $log['control'] = $health->calHealth($log);
                        $logs[$log['e_name']] = $log;
                    }
                }
            }
            return $this->success('ok', $logs);
        }catch (\Exception $e){
            Log::error('healthFatLog:'.$e->getMessage());
            return $this->failure('获取失败');
        }
    }

    public function fatLog(Request $request)
    {
        $chat_id = $request->input('chat_id');
        $group = Group::with('order')->where('chat_id', $chat_id)->first();
        if (empty($group) || empty($group->order)) return $this->failure("缺少群信息或者订单信息");
        $tested_at = $request->input('tested_at');
        if(empty($tested_at)) throw new \Exception("缺少参数.tested_at");
        if (empty($group->order->user_id)) return $this->failure("订单用户未完成小程序个人信息");
        $user = User::find($group->order->user_id);
        $unit = $user->unit;

        $logs = FatLog::with('fatKind:fat_name,icon')->where(['user_id' => $user->id, 'tested_at' => $tested_at])->get()->toArray();
        if (count($logs)) {
            foreach ($logs as &$log) {
                if ($log['unit'] == 'kg') {
                    $log = $this->changeUnit($log, $unit);
                }
            }
        }
        return $this->success('ok', $logs);
    }

    public function changeUnit($log, $unit)
    {
        if ($log['unit'] == 'kg' && $unit == '斤') {
            $log['fat_data'] = number_format($log['fat_data'] * 2, 2);
            $log['unit'] = '斤';
        }
        return $log;
    }

    public function fatKinds(Request $request)
    {
        $user = $request->group->order->user;
        $kinds = FatKind::where(function ($sql) {
            $sql->where('icon', '!=', '');
        })->get();
        $fat_names = [
            '脂肪占比'=>'脂肪率',
            '体内水分'=>'水分率',
            '肌肉占比'=>'肌肉率',
            '卡路里'=>'基础代谢',
            '体脂重量'=>'脂肪重量',
            '蛋白质'=>'蛋白质重量',
            '脂肪控制'=>'体重控制量',
        ];
        foreach ($kinds as $kind) {
            if(!$user){
                continue;
            }
            if ($kind->unit == 'kg' && $user->unit != $kind->unit) {
                $kind->unit = change_unit($user->language,$user->unit);
            }
            if(isset($fat_names[$kind->fat_name])){
                $kind->fat_name = $fat_names[$kind->fat_name];
            }
        }
        return $this->success('ok', $kinds);
    }

    public function healthKinds(Request $request)
    {
        $user = $request->group->order->user;
        $kinds = HealthKind::where(function ($sql) {
            $sql->where('icon', '!=', '')->where('e_name', '!=', 'BodyShape');
        })->get();
        foreach ($kinds as $kind) {
            if(!$user){
                continue;
            }
            if ($kind->unit == 'kg' && $user->unit != $kind->unit) {
                $kind->unit = '斤';
            }
        }
        return $this->success('ok', $kinds);
    }

    /**
     * 获取图表统计数据
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function healthStat(Request $request){
        $user = $request->group->order->user;
        $e_name = $request->input('e_name');
        $start_date = $request->input('start_date');
        $end_date = $request->input('end_date');
        if ($start_date && $end_date) {
            $day_arr = CommonService::daliy($start_date, $end_date);
        } else {
            $day_arr = CommonService::daliy(date('Y-m-d', strtotime('-180 days')), date('Y-m-d'));
        }
        $unit = $user->unit??'kg';
        $x_arr = [];
        $y_arr = [];
        $z_arr = [];
        $health = new HealthController();
        foreach ($day_arr as $day) {
            $x_arr[] = date('m/d', strtotime($day));
            $day_end = date('Y-m-d', strtotime($day) + 24 * 3600);
            $score = $mix_score = 0;
            if(!$user){
                $y_arr[] = $score;
                continue;
            }
            $log = HealthLog::with('healthKind:name,e_name,unit,icon,h_icon', 'healthLevel:desc_key,name,color', 'healthLevels:name,e_name,color')
                ->where('user_id', $user->id)->where('e_name', $e_name)
                ->where('created_at', '>', $day)->where('created_at', '<', $day_end)
                ->orderByDesc('score')
                ->select('e_name', 'score', 'desc', 'desc_key', 'tested_at', 'boundaries')->first();

            $mix_log = HealthLog::with('healthKind:name,e_name,unit,icon,h_icon', 'healthLevel:desc_key,name,color', 'healthLevels:name,e_name,color')
                ->where('user_id', $user->id)->where('e_name', $e_name)
                ->where('created_at', '>', $day)->where('created_at', '<', $day_end)
                ->orderBy('score','asc')
                ->select('e_name', 'score', 'desc', 'desc_key', 'tested_at', 'boundaries')->first();
            if ($log) {
                $log = $log->toArray();
                if ($log['health_kind']['unit'] == 'kg') {
                    $log = $health->changeUnit($log, $unit, $user->language);
                }
                $score = $log['score'];
            }
            $y_arr[] = $score;

            if ($mix_log) {
                $mix_log = $mix_log->toArray();
                if ($mix_log['health_kind']['unit'] == 'kg') {
                    $mix_log = $health->changeUnit($mix_log, $unit, $user->language);
                }
                $mix_score = $mix_log['score'];
            }
            $z_arr[] = $mix_score;
        }
        return $this->success('ok', compact('x_arr', 'y_arr','z_arr'));
    }

    public function fatStat(Request $request)
    {
        $user = $request->group->order->user;
        $fat_name = $request->input('fat_name');
        $start_date = $request->input('start_date');
        $end_date = $request->input('end_date');
        if ($start_date && $end_date) {
            $day_arr = CommonService::daliy($start_date, $end_date);
        }else {
            $day_arr = CommonService::daliy(date('Y-m-d', strtotime('-180 days')), date('Y-m-d'));
            //获取用户第一次称的时间
//            $test_date = FatLog::where('user_id',auth()->id())->where('fat_name', $fat_name)->value('created_at');
//            $day_arr = CommonService::daliy(date('Y-m-d', strtotime($test_date)), date('Y-m-d'));
        }
        $x_arr = [];
        $y_arr = [];
        $z_arr = [];
        $unit = $user->unit??'kg';

        //这只是为了兼容之前不好的旧结构设计，有缘人自己把整个结构改了，我没时间重构整个旧数据结构，将错就错
        $fat_names = [
            '脂肪率'=>['脂肪占比','脂肪率'],
            '水分率'=>['体内水分','水分率'],
            '肌肉率'=>['肌肉占比','肌肉率'],
            '卡路里'=>['基础代谢','卡路里'],
            '脂肪重量'=>['体脂重量','脂肪重量'],
            '蛋白质重量'=>['蛋白质','蛋白质重量'],
            '体重控制量'=>['脂肪控制','体重控制量'],
        ];
        if(isset($fat_names[$fat_name])){
            $fat_name = $fat_names[$fat_name];
        }else{
            $fat_name = explode(',',$fat_name);
        }
        $fat = new \App\Http\Controllers\FatController();
        foreach ($day_arr as $day) {
            $x_arr[] = date('m/d', strtotime($day));
            $day_end = date('Y-m-d', strtotime($day) + 24 *3600);
            $fat_data = 0;
            if(!$user){
                $y_arr[] = $fat_data;
                continue;
            }
            $log = FatLog::where('user_id', $user->id)->whereIn('fat_name', $fat_name)->where('created_at', '>', $day)->where('created_at', '<', $day_end)->orderByDesc('fat_data')->first();
            $mix_log = FatLog::where('user_id', auth()->id())->whereIn('fat_name', $fat_name)->where('created_at', '>', $day)->where('created_at', '<', $day_end)->orderBy('fat_data','asc')->first();
            $fat_data = $fat_mix = 0;
            if ($log) {
                $log = $log->toArray();
                if ($log['unit'] == 'kg') {
                    $log = $fat->changeUnit($log, $unit,$user->language);
                }
                $fat_data = $log['fat_data'];
            }
            $y_arr[] = $fat_data;

            if ($mix_log) {
                $mix_log = $mix_log->toArray();
                if ($mix_log['unit'] == 'kg') {
                    $mix_log = $fat->changeUnit($mix_log, $unit,$user->language);
                }
                $fat_mix = $mix_log['fat_data'];
            }
            $z_arr[] = $fat_mix;

        }
        return $this->success('ok', compact('x_arr', 'y_arr','z_arr'));
    }

    /**
     * 获取图表统计
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getFatStat(Request $request){
        try {
            $name = $request->input('fat_name');
            $start_date = $request->input('start_date');
            $end_date = $request->input('end_date');

            $user = $request->group->order->user;

            $fatService = new FatService();
            $res = $fatService->getFatStat($name,$start_date,$end_date,$user);

            if(!$res['status']){
                return $this->failure($res['msg']);
            }
            return $this->success('ok',$res['data']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('getFatStat:'.$e->getMessage())->onQueue('health');
            return $this->failure('获取失败');
        }
    }

    /**
     * 获取图标数据
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getFatKinds(Request $request)
    {
        try {
            $user = $request->group->order->user;
            $fatService = new FatService();
            $res = $fatService->getFatKinds($user);

            if(!$res['status']){
                return $this->failure($res['msg']);
            }
            return $this->success('ok',$res['data']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('fatKinds:'.$e->getMessage())->onQueue('health');
            return $this->failure('查询失败');
        }
    }
    /**
     * 获取图表统计
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getFatStatV1(Request $request){
        try {
            $user_id = $request->input('user_id');
            if(empty($user_id)){
                return $this->failure('用户id不为空');
            }
            $name = $request->input('fat_name');
            $start_date = $request->input('start_date');
            $end_date = $request->input('end_date');

            $user = User::find($user_id);

            $fatService = new FatService();
            $res = $fatService->getFatStat($name,$start_date,$end_date,$user);

            if(!$res['status']){
                return $this->failure($res['msg']);
            }
            return $this->success('ok',$res['data']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('getFatStatV1:'.$e->getMessage())->onQueue('health');
            return $this->failure('获取失败');
        }
    }

    /**
     * 获取图标数据
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getFatKindsV1(Request $request)
    {
        try {
            $user_id = $request->input('user_id');
            if(empty($user_id)){
                return $this->failure('用户id不为空');
            }
            $user = User::find($user_id);
            $fatService = new FatService();
            $res = $fatService->getFatKinds($user);

            if(!$res['status']){
                return $this->failure($res['msg']);
            }
            return $this->success('ok',$res['data']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('getFatKindsV1:'.$e->getMessage())->onQueue('health');
            return $this->failure('查询失败');
        }
    }

    /**
     * 获取称重记录
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getFatLogList(Request $request){
        try {
            $chat_id = $request->input('chat_id');
            $service_user_id = $request->input('service_user_id');
            if($service_user_id){
                $group = Group::with('order')->where('im_chat_id', $chat_id)->first();
            }else{
                $group = Group::with('order')->where('chat_id', $chat_id)->first();
            }
            if (empty($group) || empty($group->order)) return $this->failure("缺少群信息或者订单信息");

            if (empty($group->order->user_id)) return $this->failure("订单用户未完成小程序个人信息");
            $user = User::find($group->order->user_id);
            if(empty($user)) return $this->failure('用户不存在');
            $fatService = new FatService();
            $res = $fatService->getFatLogList($user,$service_user_id);

            if(!$res['status']){
                return $this->failure($res['msg']);
            }
            return $this->success('ok',$res['data']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('getFatLogList:'.$e->getMessage())->onQueue('health');
            return $this->failure('获取失败');
        }
    }

    /**
     * 获取体脂详情
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function getFatDetail(Request $request){
        try {
            $chat_id = $request->input('chat_id');
            $service_user_id = $request->input('service_user_id');
            if($service_user_id){
                $group = Group::with('order')->where('im_chat_id', $chat_id)->first();
            }else{
                $group = Group::with('order')->where('chat_id', $chat_id)->first();
            }
            if (empty($group) || empty($group->order)) return $this->failure("缺少群信息或者订单信息");

            $id = $request->get('id');
            if(empty($id)){
                return $this->failure('缺少参数id');
            }
            if (empty($group->order->user_id)) return $this->failure("订单用户未完成小程序个人信息");

            // $unit = $request->input('unit');
            $unit = "斤";
            $user_id = $request->input('user_id');

            $user = User::find($group->order->user_id);

            $fatService = new FatService();
            $res = $fatService->getFatDetail($id,$user_id,$unit,$user);

            if(!$res['status']){
                return $this->failure($res['msg']);
            }
            return $this->success('ok',$res['data']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('getFatDetail:'.$e->getMessage())->onQueue('health');
            return $this->failure('获取失败');
        }
    }

    public function comparefatLogs(Request $request) {
        $chat_id = $request->input('chat_id');
        $service_user_id = $request->input('service_user_id');
        if($service_user_id){
            $group = Group::with('order')->where('im_chat_id', $chat_id)->first();
        }else{
            $group = Group::with('order')->where('chat_id', $chat_id)->first();
        }
        if (empty($group) || empty($group->order)) return $this->failure("缺少群信息或者订单信息");

        if (empty($group->order->user_id)) return $this->failure("订单用户未完成小程序个人信息");
        $user = User::where("id", $group->order->user_id)->select("id", "name", "avatar")->first();
        if(empty($user)) return $this->failure('用户不存在');

        $start_id = $request->input('start_id');
        $end_id = $request->input('end_id');
        if (empty($start_id) || empty($end_id)) {
            return $this->failure('请选择对比时间');
        }

        $user->fat_device = User::FAT_DEVICE_YUNKANGBAO;

        $fatService = new FatService();
        $res = $fatService->getCompareFatData($user, $start_id, $end_id, "斤");

        if (!$res['status']) {
            return $this->failure($res['msg']);
        }
        return $this->success('ok', $res['data'] ?? []);
    }
}
