<?php

namespace App\Http\Controllers;

use App\Facades\CommonService;
use App\Facades\WechatService;
use App\Http\Response\ResponseJson;
use App\Jobs\AddErrorLog;
use App\Models\FatKind;
use App\Models\FatLog;
use App\Models\HealthKind;
use App\Models\HealthLevel;
use App\Models\HealthLog;
use App\Models\NewFatLog;
use App\Models\User;
use App\Models\Version;
use App\Services\FatService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class HealthController 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 home(Request $request, $user_id = null)
    {
        if (empty($user_id)) {
            $user = auth()->user();
            $user_id = $user->id;
        } else {
            $user = User::find($user_id);
        }
        $tested_at = $request->input('tested_at');
        if (empty($tested_at)) {
            //最近一次测量日期
            $tested_at = HealthLog::where('user_id', $user_id)->groupBy('tested_at')->orderBy('tested_at', 'desc')->limit(1)->value('tested_at');
        }
        $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', 'max_boundary', 'boundaries', 'desc_key', 'tested_at', 'display_progress')
            ->get()->toArray();
        $logs = [];
        $score = [
            'weight' => 0,
            'weight_unit' => 'kg',
            'bodyfat' => 0,
            'bodyfat_unit' => '%',
            'bmi' => 0,
            'tested_at' => '',
            'score' => 0,
        ];
        //判断用户信息
        $user->unit = get_user_unit($user->language, $user->unit);
        $unit = $user->unit ?? 'kg';

        if (count($logs_arr)) {
            foreach ($logs_arr as &$log) {
                if ($log['e_name'] == 'Score') {
                    $score['score'] = $log['score'];
                } else {
                    if(!empty($log['health_kind'])){
                        $log = $this->changeUnit($log, $unit, $user->language);
                    }
                    $log['boundaries'] = json_decode($log['boundaries'], true);
                    $logs[$log['e_name']] = $log;
                }
            }
            if (isset($logs['Weight'])) {
                $score['weight'] = $logs['Weight']['score'];
                $score['weight_unit'] = $logs['Weight']['health_kind']['unit'];
            }
            if (isset($logs['Bodyfat'])) {
                $score['bodyfat'] = $logs['Bodyfat']['score'];
                $score['bodyfat_unit'] = $logs['Bodyfat']['health_kind']['unit'];
            }
            if (isset($logs['BMI'])) {
                $score['bmi'] = $logs['BMI']['score'];
                $score['tested_at'] = $logs['BMI']['tested_at'];
            }
            if (isset($logs['BMR'])) {
                $score['metabolism'] = $logs['BMR']['score'];
                $score['metabolism_unit'] = $logs['BMR']['health_kind']['unit'];
            }
        }
        return $this->success('ok', compact('logs', 'score', 'user'));

    }

    public function changeUnit($log, $unit, $language = 0)
    {
//        if ($log['health_kind']['unit'] == 'kg' && $unit == '斤') {
//            $log['score'] = number_format($log['score'] * self::WEIGHT_JIN_KG_RATE, 2);
//            $log['health_kind']['unit'] = '斤';
//            $arr = json_decode($log['boundaries']);
//            if(count($arr)) {
//                foreach ($arr as $key => $boundary) {
//                    $arr[$key] = $boundary * self::WEIGHT_JIN_KG_RATE;
//                }
//            }
//            $log['boundaries'] = json_encode($arr);
//        }
        if(empty($log['health_kind'])){
            return $log;
        }
        $score = $new_unit = '';
        if ($log['health_kind']['unit'] == 'kg' && $unit == '斤' && $language == User::LANGUAGE_CH) {
            $rate = self::WEIGHT_JIN_KG_RATE;
            $score = $log['score'] * $rate;
            $new_unit = '斤';
        }
        if ($log['health_kind']['unit'] == 'kg' && $unit == '斤' && $language == User::LANGUAGE_EN) {
            $rate = self::WEIGHT_RATE;
            $score = $log['score'] * $rate;
            $new_unit = 'lb';
        }
        if ($log['health_kind']['unit'] == 'kg' && $unit == 'lb' && $language == User::LANGUAGE_EN) {
            $rate = self::WEIGHT_RATE;
            $score = $log['score'] * $rate;
            $new_unit = 'lb';
        }
        if ($log['health_kind']['unit'] == 'kg' && $unit == 'lb' && $language == User::LANGUAGE_CH) {
            $rate = self::WEIGHT_JIN_KG_RATE;
            $score = $log['score'] * $rate;
            $new_unit = '斤';
        }
        if ($log['health_kind']['unit'] == 'lb' && $unit == 'kg') {
            $rate = self::WEIGHT_RATE;
            $score = $log['score'] / $rate;
            $new_unit = 'kg';
        }
        if ($log['health_kind']['unit'] == 'lb' && $unit == '斤') {
            $rate = self::WEIGHT_JIN_LB_RATE;
            $score = $log['score'] / $rate;
            $new_unit = '斤';
        }

        if ($score && $new_unit) {
            $log['score'] = get_two_float($score, 2);
            $log['health_kind']['unit'] = $new_unit;
            $arr = json_decode($log['boundaries']);
            if (count($arr)) {
                foreach ($arr as $key => $boundary) {
                    $arr[$key] = str(get_two_float($boundary * $rate,2));
                }
            }
            $log['boundaries'] = json_encode($arr);
        }

        return $log;
    }

    /**
     * 保存体脂信息
     * @param Request $request
     */
    public function storeHealthLog(Request $request)
    {
        $user = auth()->user();
        $user_id = $user->id;
        $tested_at = date('Y-m-d H:i:s');
        $data = $request->input('data');
        $init_data = $request->input('init_data');
        $device_model = $request->input('device_model');
        $flag = $request->input('flag',false);

        //是否完整资料
        $is_complete_info = $user->baseUserInfo();
        if (empty($is_complete_info)) return $this->failure("请先完善基本信息");
        //数据是否完善
//        if (empty($data) || count($data) < 17) return $this->failure("数据存储失败");
        $weight_score = 0;
        foreach ($data as &$da) {
            $da['user_id'] = $user_id;
            $da["boundaries"] = json_encode($da["boundaries"]);
            $da['tested_at'] = $da['created_at'] = $da['updated_at'] = $tested_at;
            $da['desc_key'] = in_array($da['desc_key'], HealthLog::DESC_KET) ? $da['desc_key'] : null;
            if ($da['desc_key'] == 'BMI.1004') {
                $da['desc_key'] = 'BMI.1003';
            }
            if (in_array($da['e_name'], ['Score', 'LBM', 'BMR', 'BodyAge', 'BodyShape'])) {
                $da['desc_key'] = $this->calDescKey($da);
            }
            if($da['e_name'] == 'Weight'){
                $weight_score = $da['score'];
            }
        }
        //查询最近一次称重记录
        $weight = HealthLog::where('user_id',$user_id)->where('e_name','Weight')->orderBydesc('id')->value('score');
        if(!empty($weight) && !empty($weight_score) && !$flag){
            $weight_rate = $weight*0.1;
            $weight_differ = $weight_score - $weight;
            //弹出提示
            if(abs($weight_differ) >= $weight_rate){
                return $this->success('ok',['flag'=>true]);
            }
        }
        //增加原始数值
        foreach ($data as $index => $item) {
            $data[$index]['init_data'] = $init_data;
            $data[$index]['device_model'] = $device_model;
        }
        HealthLog::insert($data);
        return $this->success('ok');
    }

    public function calDescKey($da)
    {
        if ($da['e_name'] == 'Score') {
            $score = $da['score'];
            $boundaries = json_decode($da['boundaries'], true);
            if ($score < $boundaries[0]) {
                $desc_key = 'Score.1002';
            } elseif ($score < $boundaries[1]) {
                $desc_key = 'Score.1003';
            } elseif ($score < $boundaries[2]) {
                $desc_key = 'Score.1004';
            } else {
                $desc_key = 'Score.1005';
            }
        } elseif ($da['e_name'] == 'LBM') {
            $desc_key = 'LBM.1002';
        } elseif ($da['e_name'] == 'BodyAge') {
            $age = CommonService::getAge(auth()->user()->birthday);
            if ($da['score'] <= $age) {
                $desc_key = "BodyAge.1002";
            } else {
                $desc_key = "BodyAge.1003";
            }
        } elseif ($da['e_name'] == 'BMR') {
            $age = CommonService::getAge(auth()->user()->birthday);
            $value = $this->getBMRValue(auth()->user()->sex, $age);
            if ($da['score'] >= $value * 60) {
                $desc_key = "BMR.1002";
            } else {
                $desc_key = "BMR.1003";
            }
        } elseif ($da['e_name'] == 'BodyShape') {
            switch ($da['score']) {
                case "运动不足型":
                    $desc_key = "BodyShape.1002";
                    break;
                case "偏瘦肌肉型":
                    $desc_key = 'BodyShape.1003';
                    break;
                case "偏瘦型":
                    $desc_key = 'BodyShape.1004';
                    break;
                case "非常肌肉型":
                    $desc_key = 'BodyShape.1005';
                    break;
                case "标准肌肉型":
                    $desc_key = 'BodyShape.1006';
                    break;
                case "标准型":
                    $desc_key = 'BodyShape.1007';
                    break;
                case "隐形肥胖型":
                    $desc_key = 'BodyShape.1008';
                    break;
                case "偏胖型":
                    $desc_key = 'BodyShape.1009';
                    break;
                default:
                    $desc_key = 'BodyShape.1010';
                    break;
            }
        }
        return $desc_key;
    }

    public function getBMRValue($sex, $age)
    {
        if ($sex == 1) {
            if ($age <= 20) {
                $value = 24;
            } elseif ($age <= 49) {
                $value = 22.3;
            } else {
                $value = 21.5;
            }
        } else {
            if ($age <= 20) {
                $value = 23.6;
            } elseif ($age <= 49) {
                $value = 21.7;
            } else {
                $value = 20.7;
            }
        }
        return $value;
    }

    /**
     * 深度报告
     * @param Request $request
     */
    public function deepReport(Request $request, $user_id = null)
    {
        $user_id = $user_id ?: auth()->id();
        //最近一次测量日期
        $tested_at = $request->input('tested_at');
        if (empty($tested_at)) {
            $tested_at = HealthLog::where('user_id', $user_id)->groupBy('tested_at')->orderBy('tested_at', 'desc')->limit(1)->value('tested_at');
        }
        $unit = auth()->user() ? auth()->user()->unit : $request->input("unit", 'kg');

        $logs_arr = HealthLog::with('healthKind:name,e_name,unit,icon,h_icon', 'healthLevel:desc_key,name,color')->where(['user_id' => $user_id, 'tested_at' => $tested_at])->select('e_name', 'score', 'desc', 'desc_key', 'tested_at', 'boundaries')->get()->toArray();
        $logs = [];
        if (count($logs_arr)) {
            foreach ($logs_arr as &$log) {
//                dd($log);
                if (isset($log['health_kind']) && $log['health_kind']['unit'] == 'kg' && $unit == '斤') {
                    $log['score'] = number_format($log['score'] * 2, 2);
                    $log['health_kind']['unit'] = '斤';
                }
                $logs[$log['e_name']] = $log;
            }
        }
        return $this->success('ok', $logs);

    }

    /**
     * 体脂记录
     * @param Request $request
     */
    public function healthLogs(Request $request)
    {
        $unit = auth()->user()->unit;
        $language = auth()->user()->language;
        $logs = HealthLog::where(['user_id' => auth()->id(), 'e_name' => "Weight"])->orderBy('id', 'desc')->select('id', 'e_name', 'score', '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($language, $unit);
            if ($unit != 'kg') {
//                $log->score = number_format($log->score * 2, 2);
                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);
    }

    /**
     * 体脂详情
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function healthLog(Request $request)
    {
        Log::info("healthLog");
        $tested_at = $request->input('tested_at');
        if (empty($tested_at)) throw new \Exception("缺少参数.tested_at");
        $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' => auth()->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 = [];
        if (count($logs_arr)) {
            $unit = auth()->user()->unit;
            foreach ($logs_arr as $log) {
                if ($log['e_name'] != 'Score') {
                    $log = $this->changeUnit($log, $unit, auth()->user()->language);
                    $log['boundaries'] = json_decode($log['boundaries'], true);
                    $log['control'] = $this->calHealth($log);
                    $logs[$log['e_name']] = $log;
                }
            }
        }
        return $this->success('ok', $logs);
    }

    public function healthLogV2(Request $request)
    {
        $tested_at = $request->input('tested_at');
        if (empty($tested_at)) throw new \Exception("缺少参数.tested_at");

        $unit = $request->input('unit');
        $user_id = $request->input('user_id');
        if (empty($user_id)) {
            $user = auth()->user();
            $user_id = $user->id;
            $unit = $user->unit;
            $language = $user->language;
        } else {
            $user = User::where('id', $user_id)->first();
            $language = $user->language;
        }

        if (empty($unit)) {
            $unit = $user->unit;
        }


        $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 = [];
        if (count($logs_arr)) {
            foreach ($logs_arr as $log) {
//                $log['boundaries'] = json_decode($log['boundaries'], true);
                if ($log['e_name'] != 'Score') {
                    $log = $this->changeUnit($log, $unit, $language);
                    $log['boundaries'] = json_decode($log['boundaries'], true);
                    $log['control'] = $this->calHealth($log);
                    $logs[$log['e_name']] = $log;
                }
            }
        }
        return $this->success('ok', $logs);
    }

    /**
     * 计算各体脂增减量（用于体脂详情）
     * @param $log
     * @return string
     */
    public function calHealth($log)
    {
        $boundaries = $log['boundaries'];
        switch ($log['e_name']) {
            case "Weight":
                $control = $this->healthDiffValue($log['score'], $boundaries[2], $boundaries[1], 'kg');
                break;
            case "HeartRate":
                $control = $this->healthDiffValue($log['score'], $boundaries[2], $boundaries[1], 'bmp');
                break;
            case "HeartIndex":
                $control = $this->healthDiffValue($log['score'], $boundaries[1], $boundaries[0], 'L/min/m^2');
                break;
            case "Bodyfat":
            case "Water":
            case "Muscle":
            case "Protein":
            case "Subfat":

                $control = $this->healthDiffValue($log['score'], $boundaries[1], $boundaries[0], '%');
                break;
            case "Bone":
            case "Sinew":
                $control = $this->healthDiffValue($log['score'], $boundaries[1], $boundaries[0], 'kg');
                break;
            case "Visfat":
                $control = $this->healthDiffValue($log['score'], $boundaries[0]);
                break;
            default:
                $control = '';
                break;
        }
        return $control;
    }

    /**
     * 计算各体脂的增减量
     * @param $current_score
     * @param $max_value
     * @param string $min_value
     * @param string $unit
     * @return string
     */
    public function healthDiffValue($current_score, $max_value, $min_value = '', $unit = '')
    {
        $control = '';
        if ($current_score > $max_value) {
            $value = number_format($current_score - $max_value, 2, '.', '');
            $control = "比标准值多" . $value . $unit;
        } elseif ($min_value && $current_score < $min_value) {
            $value = number_format($min_value - $current_score, 2, '.', '');
            $control = "比标准值少" . $value . $unit;
        }
        return $control;
    }

    /**
     * 获取数据对比
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse
     */
    public function compareHealthLogs(Request $request)
    {
        try {
            if (empty($user_id)) {
                $user = auth()->user();
                $user_id = $user->id;
            } else {
                $user = User::find($user_id);
            }
            $start_tested_at = $request->input('start_tested_at');
            $end_tested_at = $request->input('end_tested_at');
            if (empty($start_tested_at) || empty($end_tested_at)) {
                return $this->failure('请选择对比时间');
            }
            //判断两个时间大小
            if ($start_tested_at > $end_tested_at) {
                $temp_tested_at = $start_tested_at;
                $start_tested_at = $end_tested_at;
                $end_tested_at = $temp_tested_at;
            }

            $start_date = new \DateTime($start_tested_at);
            $end_date = new \DateTime($end_tested_at);

            $interval = $start_date->diff($end_date);
            $differ_day = $interval->days;

            $init_start_logs = HealthLog::with('healthKind')->with('healthLevel')
                ->where(['user_id' => $user_id, 'tested_at' => $start_tested_at])
                ->orderBy('id', 'asc')
                ->whereNotIn('e_name', ['WeightControl', 'FatControl', 'SinewControl', 'BodyfatMass','Score'])
                ->get()
                ->toArray();

            $init_end_logs = HealthLog::with('healthKind')->with('healthLevel')
                ->where(['user_id' => $user_id, 'tested_at' => $end_tested_at])
                ->orderBy('id', 'asc')
                ->whereNotIn('e_name', ['WeightControl', 'FatControl', 'SinewControl', 'BodyfatMass','Score'])
                ->get()
                ->toArray();

            if (empty($init_start_logs) || empty($init_end_logs)) {
                return $this->failure('查询失败');
            }
            //判断用户信息
            $user->unit = get_user_unit($user->language, $user->unit);
            $unit = $user->unit ?? 'kg';
            foreach ($init_start_logs as &$init_start_log) {
                if (empty($init_start_log['health_kind'])) {
                    continue;
                }
                $init_start_log = $this->changeUnit($init_start_log, $unit, $user->language);
            }
            foreach ($init_end_logs as &$init_end_log) {
                if (empty($init_end_log['health_kind'])) {
                    continue;
                }
                $init_end_log = $this->changeUnit($init_end_log, $unit, $user->language);
            }
            //获取需要处理的参数
            $start_logs = $end_logs = [];
            foreach ($init_start_logs as $start_key => $start_value) {
                $start_logs[$start_key]['e_name'] = $start_value['e_name'];
                $start_logs[$start_key]['score'] = $start_value['score'];
                $start_logs[$start_key]['desc_key'] = $start_value['desc_key'];
                $start_logs[$start_key]['name'] = $start_value['health_kind']['name'] ?? null;
                $start_logs[$start_key]['unit'] = $start_value['health_kind']['unit'] ?? null;
                $start_logs[$start_key]['level_name'] = $start_value['health_level']['name'] ?? null;
                $start_logs[$start_key]['color'] = $start_value['health_level']['color'] ?? null;
            }

            foreach ($init_end_logs as $end_key => $end_value) {
                $end_logs[$end_key]['e_name'] = $end_value['e_name'];
                $end_logs[$end_key]['score'] = $end_value['score'];
                $end_logs[$end_key]['desc_key'] = $end_value['desc_key'];
                $end_logs[$end_key]['name'] = $end_value['health_kind']['name'] ?? null;
                $end_logs[$end_key]['unit'] = $end_value['health_kind']['unit'] ?? null;
                $end_logs[$end_key]['level_name'] = $end_value['health_level']['name'] ?? null;
                $end_logs[$end_key]['color'] = $end_value['health_level']['color'] ?? null;
            }

            //对比两个数组的差值
            $merge_logs = [];
            foreach ($start_logs as $start){
                foreach ($end_logs as $end){
                    if(!isset($start['name']) || !isset($end['name'])){
                        continue;
                    }
                    if($start['name'] != $end['name']){
                        continue;
                    }
                    $status = 0;
                    $differ = '-';
                    $start['score'] = floatval(str_replace(',', '', $start['score']));
                    $end['score'] = floatval(str_replace(',', '', $end['score']));
                    if($start['score'] < $end['score']){
                        $status = 1;
                        $differ = get_two_float(abs($end['score'] - $start['score']),2);
                    }
                    if($start['score'] > $end['score']){
                        $status = 2;
                        $differ = get_two_float(abs($end['score'] - $start['score']),2);
                    }
                    $merge_logs[] = [
                        'name' => $start['name'],
                        'status' => $status,
                        'differ' => $differ,
                        'unit' => $start['unit']
                    ];
                }
            }
            //处理数组
            $fat_names = [];
            foreach ($merge_logs as $item) {
                if (isset($item['name'])) {
                    $fat_names[] = $item['name'];
                }
            }
            foreach ($start_logs as $sk=> $sv){
                if(!in_array($sv['name'],$fat_names)){
                    unset($start_logs[$sk]);
                }
            }
            foreach ($end_logs as $ek=> $ev){
                if(!in_array($ev['name'],$fat_names)){
                    unset($end_logs[$ek]);
                }
            }
            $start_logs = array_values($start_logs);
            $end_logs = array_values($end_logs);
            $data = [];
            $data['start_logs'] = $start_logs;
            $data['end_logs'] = $end_logs;
            $data['merge_logs'] = $merge_logs;
            $data['user'] = $user;
            $data['differ_day'] = $differ_day;
            return $this->success('ok',$data);
        } catch (\Exception $e) {
            Log::error('compareHealthLogs:' . $e->getMessage());
            return $this->failure('查询失败');
        }
    }

    /**
     * 对比体脂信息
     * @param Request $request
     */
    public function compareHealthLogs1(Request $request)
    {
        $first_tested_at = $request->input('start_tested_at');
        $second_tested_at = $request->input("end_tested_at");
        if (empty($first_tested_at) || empty($second_tested_at)) throw new \Exception("未获取到对比测量时间");

        $day = number_format((strtotime($first_tested_at) - strtotime($second_tested_at)) / (24 * 3600), '0');

        $logs = DB::table('health_logs as fl')
            ->leftJoin('health_logs as sl', 'fl.e_name', '=', 'sl.e_name')
            ->leftJoin("health_kinds as k", 'k.e_name', '=', 'fl.e_name')
            ->leftJoin("health_levels as fle", 'fle.desc_key', '=', 'fl.desc_key')
            ->leftJoin("health_levels as sle", 'sle.desc_key', '=', 'sl.desc_key')
            ->where('fl.tested_at', $first_tested_at)
            ->where('sl.tested_at', $second_tested_at)
            ->selectRaw('ufutx_fl.e_name, ufutx_fl.score, ufutx_k.name, ufutx_fl.desc_key, ufutx_sl.score as s_score, ufutx_sl.desc_key as s_desc_key, ufutx_k.unit, ufutx_fle.name as level_name, ufutx_sle.name as s_level_name')->get();

        $weight_diff = $f_weight = $s_weight = $f_bodyfat = $s_bodyfat = '';
        foreach ($logs as $log) {
            $log->diff = '';
            if ($log->e_name == 'BodyShape') continue;
            $f_score = number_format($log->score, 2, '.', '');
            $s_score = number_format($log->s_score, 2, '.', '');
            if (in_array($log->e_name, ['Weight'])) {
                $log->diff = number_format($f_score - $s_score, '2', '.', '');
                $f_weight = $log->score;
                $s_weight = $log->s_score;
                $weight_diff = $log->diff;
            } elseif (in_array($log->e_name, ['Visfat', 'BMR', 'BodyAge'])) {
                $log->diff = number_format($f_score - $s_score, '0', '.', '');
            } else {
                $log->diff = number_format($f_score - $s_score, '1', '.', '');
            }
            if ($log->e_name = 'Bodyfat') {
                $f_bodyfat = $log->score;
                $s_bodyfat = $log->s_score;
            }
        }
        $f_fat = number_format($f_weight * ($f_bodyfat / 100));
        $s_fat = number_format($s_weight * ($s_bodyfat / 100));
        $score = [
            'weight' => $weight_diff,
            'weight_unit' => 'kg',
            'fat' => number_format($f_fat - $s_fat, '1', '', '.'),
            'fat_unit' => 'kg',
            'day' => $day
        ];

        return $this->success('ok', compact('logs', 'score'));
    }

    /**
     * 删除体脂信息
     * @param Request $request
     */
    public function deleteHealthLog(Request $request)
    {
        $tested_at = $request->input("tested_at");
        if (empty($tested_at)) throw new \Exception("未获取到测量时间信息");
        HealthLog::where(['user_id' => auth()->id(), 'tested_at' => $tested_at])->delete();
        return $this->success('ok');
    }

    public function healthStat(Request $request)
    {
        $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 = auth()->user()->unit;
        $x_arr = [];
        $y_arr = [];
        $z_arr = [];
        foreach ($day_arr as $day) {
            $x_arr[] = date('m/d', strtotime($day));
            $day_end = date('Y-m-d', strtotime($day) + 24 * 3600);
            $log = HealthLog::with('healthKind:name,e_name,unit,icon,h_icon', 'healthLevel:desc_key,name,color', 'healthLevels:name,e_name,color')
                ->where('user_id', auth()->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', auth()->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();
            $score = $mix_score =0;
            if ($log) {
                $log = $log->toArray();
                if ($log['health_kind']['unit'] == 'kg') {
                    $log = $this->changeUnit($log, $unit, auth()->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 = $this->changeUnit($mix_log, $unit, auth()->user()->language);
                }
                $mix_score = $mix_log['score'];
            }
            $z_arr[] = $mix_score;
        }
        return $this->success('ok', compact('x_arr', 'y_arr','z_arr'));
    }

    public function healthKinds(Request $request)
    {
        $kinds = HealthKind::where(function ($sql) {
            $sql->where('icon', '!=', '')->where('e_name', '!=', 'BodyShape');
        })->get();
        foreach ($kinds as $kind) {
            if ($kind->unit == 'kg' && auth()->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 saveFatLog(Request $request){
        try {
            $user = auth()->user();
            $params = $request->all();
            //是否完整资料
            $is_complete_info = $user->baseUserInfo();
            if (empty($is_complete_info)) return $this->failure("请先完善基本信息");

            $fatService = new FatService();
            $res = $fatService->saveFatLog($user,$params);

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

    /**
     * 获取最近一次体脂信息
     * @param Request $request
     */
    public function getHomeData(Request $request)
    {
        try {
            $user_id = $request->get('user_id');
            if (empty($user_id)) {
                $user = auth()->user();
            } else {
                $user = User::find($user_id);
            }
            $id = $request->get('id');
            $fatService = new FatService();
            $res = $fatService->getHomeData($user,$id);

            if(!$res['status']){
                return $this->failure($res['msg']);
            }
            return $this->success('ok',$res['data']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('getHomeData:'.$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 {
            Log::info("getFatLogList");
            $user = auth()->user();

            $fatService = new FatService();
            $res = $fatService->getFatLogList($user);

            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 {
            Log::info("getFatDetail");
            $id = $request->get('id');
            if(empty($id)){
                return $this->failure('缺少参数id');
            }
            $unit = $request->input('unit');
            $user_id = $request->input('user_id');

            $user = auth()->user();

            $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('获取失败');
        }
    }

    /**
     * 获取图表统计
     * @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 = auth()->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\Http\JsonResponse|void
     */
    public function getCompareFatData(Request $request){
        try {
            $user_id = $request->get('user_id');
            if (empty($user_id)) {
                $user = auth()->user();
            }else {
                $user = User::find($user_id);
            }
            $start_id = $request->input('start_id');
            $end_id = $request->input('end_id');
            if(empty($start_id) || empty($end_id)){
                return $this->failure('请选择对比时间');
            }

            $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']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('getCompareFatData:'.$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 = auth()->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 saveWeakNetworkFat(Request $request){
        try {
            $user = auth()->user();
            $data = $request->all();
            //是否完整资料
            $is_complete_info = $user->baseUserInfo();
            if (empty($is_complete_info)) return $this->failure("请先完善基本信息");

            $fatService = new FatService();

            //相同时间的数据去除,只保留一条数据
            $unique_array = array();
            foreach ($data['data'] as $item) {
                $item['flag'] = true;
                $key = $item['time']; // 使用唯一标识作为 key
                if (!isset($unique_array[$key])) {
                    $unique_array[$key] = $item;
                }
            }
            $result = array_values($unique_array); // 重新索引数组键值

            foreach ($result as $value){
                $res = $fatService->saveFatLog($user,$value,Version::TYPE_MP,true);
            }

            if(!$res['status']){
                return $this->failure($res['msg']);
            }
            return $this->success('ok',$res['data']??[]);
        }catch (\Exception $e){
            AddErrorLog::dispatch('saveWeakNetworkFat file:'.$e->getFile().' line:'.$e->getLine().' message:'.$e->getMessage())->onQueue('health');
            return $this->failure('保存失败');
        }
    }
}
