<?php

namespace App\Services;
use App\Facades\CommonService;
use App\Jobs\AddErrorLog;
use App\Models\FatKind;
use App\Models\FatMaxMin;
use App\Models\HealthKind;
use App\Models\HealthLevel;
use App\Models\NewFatLog;
use App\Models\User;
use App\Models\Version;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class FatService
{

    public function getHomeData($user, $id = null)
    {
        try {
            $user_id = $user->id;
            $score = [
                'weight' => 0,
                'weight_unit' => 'kg',
                'bodyfat' => 0,
                'bodyfat_unit' => '%',
                'bmi' => 0,
                'tested_at' => '',
                'metabolism' => 0,
                'metabolism_unit' => '',
                'score' => 0,
                'id' => '',
            ];
            //判断用户信息
            $user->unit = get_user_unit($user->language, $user->unit);
            $unit = $user->unit ?? 'kg';

            $logs = [];
            $fat_log = NewFatLog::where('user_id', $user_id)->where('type', $user->fat_device)->orderByDesc('id')->first();
            if (!empty($id)) {
                $fat_log = NewFatLog::where('id', $id)->where('type', $user->fat_device)->orderByDesc('id')->first();
            }
            if (!empty($fat_log)) {
                $fat_log = $fat_log->toArray();

                $score['tested_at'] = $fat_log['created_at'] ?? '';
                $logs = json_decode($fat_log['data'], true);
                foreach ($logs as &$item) {
                    $item = change_user_unit($item, $unit, $user->language, $user->fat_device);
                    $item['boundaries'] = json_decode($item['boundaries'], true);
                    if ($user->fat_device == User::FAT_DEVICE_YUNKANGBAO) {
                        if (in_array($item['e_name'], ['Weight', 'Sinew', 'Bone'])) {
                            $item['boundaries'] = change_boundaries($item['boundaries'], $unit, $user->language);
                        }
                    }

                    if ($item['fat_name'] == '体重') {
                        $score['weight'] = $item['fat_data'];
                        $score['weight_unit'] = $unit;
                    }
                    if ($item['fat_name'] == 'BMI') {
                        $score['bmi'] = $item['fat_data'];
                    }
                    if (in_array($item['fat_name'], ['脂肪占比', '脂肪率', '体脂率'])) {
                        $score['bodyfat'] = $item['fat_data'];
                        $score['bodyfat_unit'] = $item['unit'];
                    }
                    if (in_array($item['fat_name'], ['肌肉占比', '肌肉率', '肌肉量'])) {
                        $score['sinew'] = $item['fat_data'];
                        $score['sinew_unit'] = $item['unit'];
                    }
                    if (in_array($item['fat_name'], ['基础代谢'])) {
                        $score['metabolism'] = $item['fat_data'];
                        $score['metabolism_unit'] = $item['unit'];
                    }
                }

                $score['id'] = $fat_log['id'];
            }
            //处理不返回的数据
            foreach ($logs as $key => $value) {
                if (in_array($value['fat_name'], ['体重控制', '脂肪控制', '肌肉控制', '脂肪重量', '健康评分']) && $user->fat_device == User::FAT_DEVICE_YUNKANGBAO) {
                    unset($logs[$key]);
                }
            }
            $data['logs'] = array_values($logs);
            $data['user'] = $user;
            $data['score'] = $score;

            return service_success($data);
        } catch (\Exception $e) {
            AddErrorLog::dispatch('getHomeData:' . $e->getMessage())->onQueue('health');
            return service_fail($e->getMessage());
        }
    }

    /**
     * 保存体脂记录
     * @param $user
     * @param $params
     * @return array|bool[]|void
     */
    public function saveFatLog($user, $params, $version_type = Version::TYPE_H5, $save_weak = false)
    {
        Log::info("saveFatLog");
        $user_id = $user->id;
        $data = $params['data'];
        $init_data = $params['init_data'] ?? '';
        $device_model = $params['device_model'] ?? '';
        $type = $params['type'] ?? '';
        $flag = $params['flag'] ?? false;

        $user->fat_device = $params['fat_device'] ?? $user->fat_device;

        $map['user_id'] = $user_id;
        $map['init_data'] = $init_data;
        $map['device_model'] = $device_model;
        $map['old_data'] = json_encode($data);
        $map['resistance'] = $params['resistance'] ?? '';
        $map['type'] = $user->fat_device;
        $content = [];
        $weight = $last_weight = 0;
        $fat_names = [];

        $fat_config = [
            '脂肪率' => '脂肪占比',
            '水分率' => '体内水分',
            '肌肉率' => '肌肉占比',
            '脂肪重量' => '体脂重量',
            '蛋白质重量' => '蛋白质',
            '体重控制量' => '脂肪控制',
        ];
        foreach ($data as $index => $item) {
            //云康宝体脂秤
            if ($user->fat_device == User::FAT_DEVICE_YUNKANGBAO) {
                if (!isset($item['e_name'])) {
                    continue;
                }
                $fat_kinds = HealthKind::where('e_name', $item['e_name'])->select('e_name', 'name', 'icon', 'h_icon', 'unit')->first();
                if (empty($fat_kinds)) {
                    continue;
                }
                $fat_kinds = $fat_kinds->toArray();
                //获取测量名
                $fat_names[] = $item['e_name'];
                if ($item['e_name'] == 'Weight') {
                    $weight = $item['score'];
                }
                //之前的逻辑
                if (isset($item['desc_key']) && $item['desc_key'] == 'BMI.1004') {
                    $item['desc_key'] = 'BMI.1003';
                }
                //                    if (in_array($item['e_name'], ['Score', 'LBM', 'BMR', 'BodyAge', 'BodyShape'])) {
//                        $item['desc_key'] = $this->calDescKey($item);
//                    }
                $item['boundaries'] = $item['boundaries'] ?? $this->getBoundaries($item, $weight, $user);
                if (isset($item['display_progress'])) {
                    $item['display_progress'] = $this->handleDisplayProgress($item['display_progress']);
                }
                $item['display_progress'] = $item['display_progress'] ?? $this->getDisplayProgress($item, $weight);
                $item['desc_key'] = "";
                if ($version_type == Version::TYPE_APP || in_array($item['e_name'], ["BodyShape", "BMR", "LBM", "Score"])) {
                    $item['desc_key'] = $this->calDescKey($item, $weight, $version_type, $user);
                }
                //获取当前处于哪个等级
                $level = HealthLevel::where('desc_key', $item['desc_key'])->select('name', 'e_name', 'color', 'desc', 'desc_key')->first();
                //计算基础代谢标准
                if ($item['e_name'] == "BMR") {
                    // $standard = $this->calculateBmrStandard($data, $user);
                    // $level['desc'] = str_replace("xxx", $standard, $level['desc']);
                    $standard = $this->calculateBmrStandard($data, $user);
                    if ($item["score"] >= $standard) {
                        $desc_key = "BMR.1002";
                    } else {
                        $desc_key = "BMR.1003";
                    }
                    $level = HealthLevel::where('desc_key', $desc_key)->select('name', 'e_name', 'color', 'desc', 'desc_key')->first();
                    $level["desc"] = str_replace("xxx", $standard, $level['desc']);
                }
                //这里把需要的数据处理成一样的,后续取就可以了,不分什么类型的体脂秤
                $content[$index]['e_name'] = $item['e_name'];
                $content[$index]['fat_name'] = $fat_kinds['name'];
                $content[$index]['fat_data'] = $item['score'];
                if ($version_type == Version::TYPE_APP && $item['e_name'] == "BodyShape") {
                    $content[$index]['fat_data'] = $level['name'];
                }
                $content[$index]['unit'] = $fat_kinds['unit'];
                $content[$index]['fat_state'] = $level->name ?? '';
                $content[$index]['icon'] = $fat_kinds['icon'];
                $content[$index]['h_icon'] = $fat_kinds['h_icon'];
                //获取分组数据
                $fat_level = HealthLevel::where('e_name', $item['e_name'])->select('name', 'e_name', 'color', 'desc', 'desc_key')->get();
                $content[$index]['levels'] = $fat_level;
                $content[$index]['level'] = $level;
            } else {
                //天晟体脂秤
                if ($item['fat_name'] == "腰臀比") {
                    continue;
                }
                if ($item['fat_name'] == '体重') {
                    $weight = $item['fat_data'];
                }
                $fat_name = $item['fat_name'];
                if (isset($fat_config[$item['fat_name']])) {
                    $fat_name = $fat_config[$item['fat_name']];
                }
                $fat_kinds = FatKind::where('fat_name', $fat_name)->select('fat_name as name', 'icon', 'h_icon', 'unit')->first();
                if (empty($fat_kinds)) {
                    continue;
                }
                $fat_kinds = $fat_kinds->toArray();
                $item['unit'] = strtolower($item['unit']);
                if ($type == 'lb') {
                    $item['unit'] = 'lb';
                }
                //这里把需要的数据处理成一样的,后续取就可以了,不分什么类型的体脂秤
                $content[$index]['e_name'] = $item['e_name'] ?? '';
                $content[$index]['fat_name'] = $item['fat_name'];
                $content[$index]['fat_data'] = $item['fat_data'];
                $content[$index]['unit'] = $item['unit'];
                $content[$index]['fat_state'] = $item['fat_state'] ?? '';
                $content[$index]['icon'] = $fat_kinds['icon'];
                $content[$index]['h_icon'] = $fat_kinds['h_icon'];

                $content[$index]['levels'] = [];
                $content[$index]['level'] = [];
            }
            $content[$index]['display_progress'] = $item['display_progress'] ?? 0;
            $content[$index]['max_boundary'] = $item['max_boundary'] ?? 0;
            $content[$index]['boundaries'] = json_encode($item['boundaries'] ?? "[]");
            //存储每次测量记录的最高值与最低值,供图表统计获取
            $this->setMaxMinData($user_id, $user->fat_device, $content[$index]['fat_name'], ['fat_data' => $content[$index]['fat_data'], 'unit' => $content[$index]['unit']]);
        }
        $map['data'] = json_encode(array_values($content));

        //查询最近一次称重记录
        $last_data = NewFatLog::where('user_id', $user_id)->where('type', $user->fat_device)->orderBydesc('created_at')->first();
        if (!empty($last_data)) {
            $last_data = $last_data->toArray();
            $weight_data = json_decode($last_data['data'], true);
            foreach ($weight_data as $value) {
                if ($value['fat_name'] != '体重') {
                    continue;
                }
                $last_weight = $value['fat_data'];
                break;
            }
            //如果本次测量记录和上次测量记录对比超过了10%,则返回提示
            if (!empty($weight) && !empty($last_weight) && !$flag) {
                $weight_rate = $weight * 0.1;
                $weight_differ = $last_weight - $weight;
                if (abs($weight_differ) >= $weight_rate) {
                    return service_success(['flag' => true]);
                }
            }
        }
        // 旧数据id
        $map["old_id"] = $params["old_id"] ?? null;
        if ($save_weak) {
            $map['created_at'] = $params['time'] ?? date('Y-m-d H:i:s');
            $map['updated_at'] = $params['time'] ?? date('Y-m-d H:i:s');
            $model = NewFatLog::insert($map);
        } else {
            $model = NewFatLog::create($map);
        }
        return service_success($model);

    }

    /**
     * 计算基础代谢标准值
     * @param $fat_data
     * @param $user
     * @return float
     */
    public function calculateBmrStandard($fat_data, $user)
    {
        $lbm = 0;
        foreach ($fat_data as $v) {
            if ($v['e_name'] != "LBM") {
                continue;
            }
            $lbm = $v["score"];
        }
        $age = CommonService::getAge($user->birthday);
        if ($user->sex == 1) {
            $standard = 88.362 + (13.397 * $lbm) + (4.799 * $user->stature) - (5.667 * $age);
            Log::info("88.362 + (13.397 * " . $lbm . ") + (4.799 * " . $user->stature . ") - (5.667 * " . $age . ") = " . $standard);
        } else {
            $standard = 447.593 + (9.247 * $lbm) + (3.098 * $user->stature) - (4.330 * $age);
            Log::info("447.593 + (9.247 * " . $lbm . ") + (3.098 * " . $user->stature . ") - (4.330 * " . $age . ") = " . $standard);
        }
        return get_two_float($standard, 2);
    }
    /**
     * 更新体脂记录
     * @param $user
     * @param $params
     * @return array|bool[]|void
     */
    public function updateFatLog($user, $params, $version_type = Version::TYPE_H5, $save_weak = false)
    {
        try {
            $user_id = $user->id;
            $data = $params['data'];
            $init_data = $params['init_data'] ?? '';
            $device_model = $params['device_model'] ?? '';
            $type = $params['type'] ?? '';
            $flag = $params['flag'] ?? false;

            $user->fat_device = $params['fat_device'] ?? $user->fat_device;

            $map['user_id'] = $user_id;
            $map['init_data'] = $init_data;
            $map['device_model'] = $device_model;
            $map['old_data'] = json_encode($data);
            $map['type'] = $user->fat_device;
            $content = [];
            $weight = $last_weight = 0;
            $fat_names = [];

            $fat_config = [
                '脂肪率' => '脂肪占比',
                '水分率' => '体内水分',
                '肌肉率' => '肌肉占比',
                '脂肪重量' => '体脂重量',
                '蛋白质重量' => '蛋白质',
                '体重控制量' => '脂肪控制',
            ];
            foreach ($data as $index => $item) {
                //云康宝体脂秤
                if ($user->fat_device == User::FAT_DEVICE_YUNKANGBAO) {
                    $fat_kinds = HealthKind::where('e_name', $item['e_name'])->select('e_name', 'name', 'icon', 'h_icon', 'unit')->first();
                    if (empty($fat_kinds)) {
                        continue;
                    }
                    $fat_kinds = $fat_kinds->toArray();
                    //获取测量名
                    $fat_names[] = $item['e_name'];
                    if ($item['e_name'] == 'Weight') {
                        $weight = $item['score'];
                    }
                    //之前的逻辑
                    if (isset($item['desc_key']) && $item['desc_key'] == 'BMI.1004') {
                        $item['desc_key'] = 'BMI.1003';
                    }
                    //                    if (in_array($item['e_name'], ['Score', 'LBM', 'BMR', 'BodyAge', 'BodyShape'])) {
//                        $item['desc_key'] = $this->calDescKey($item);
//                    }
                    $item['boundaries'] = $item['boundaries'] ?? $this->getBoundaries($item, $weight, $user);
                    if (isset($item['display_progress'])) {
                        $item['display_progress'] = $this->handleDisplayProgress($item['display_progress']);
                    }
                    $item['display_progress'] = $item['display_progress'] ?? $this->getDisplayProgress($item, $weight);
                    if ($version_type == Version::TYPE_APP || in_array($item['e_name'], ["BodyShape", "BMR", "LBM", "Score"])) {
                        $item['desc_key'] = $this->calDescKey($item, $weight, $version_type, $user);
                    }
                    //获取当前处于哪个等级
                    $level = HealthLevel::where('desc_key', $item['desc_key'])->select('name', 'e_name', 'color', 'desc', 'desc_key')->first();
                    //这里把需要的数据处理成一样的,后续取就可以了,不分什么类型的体脂秤
                    $content[$index]['e_name'] = $item['e_name'];
                    $content[$index]['fat_name'] = $fat_kinds['name'];
                    $content[$index]['fat_data'] = $item['score'];
                    if ($version_type == Version::TYPE_APP && $item['e_name'] == "BodyShape") {
                        $content[$index]['fat_data'] = $level['name'];
                    }
                    $content[$index]['unit'] = $fat_kinds['unit'];
                    $content[$index]['fat_state'] = $level->name ?? '';
                    $content[$index]['icon'] = $fat_kinds['icon'];
                    $content[$index]['h_icon'] = $fat_kinds['h_icon'];
                    //获取分组数据
                    $fat_level = HealthLevel::where('e_name', $item['e_name'])->select('name', 'e_name', 'color', 'desc', 'desc_key')->get();
                    $content[$index]['levels'] = $fat_level;
                    $content[$index]['level'] = $level;
                } else {
                    //天晟体脂秤
                    if ($item['fat_name'] == "腰臀比") {
                        continue;
                    }
                    if ($item['fat_name'] == '体重') {
                        $weight = $item['fat_data'];
                    }
                    $fat_name = $item['fat_name'];
                    if (isset($fat_config[$item['fat_name']])) {
                        $fat_name = $fat_config[$item['fat_name']];
                    }
                    $fat_kinds = FatKind::where('fat_name', $fat_name)->select('fat_name as name', 'icon', 'h_icon', 'unit')->first();
                    if (empty($fat_kinds)) {
                        continue;
                    }
                    $fat_kinds = $fat_kinds->toArray();
                    $item['unit'] = strtolower($item['unit']);
                    if ($type == 'lb') {
                        $item['unit'] = 'lb';
                    }
                    //这里把需要的数据处理成一样的,后续取就可以了,不分什么类型的体脂秤
                    $content[$index]['e_name'] = $item['e_name'] ?? '';
                    $content[$index]['fat_name'] = $item['fat_name'];
                    $content[$index]['fat_data'] = $item['fat_data'];
                    $content[$index]['unit'] = $item['unit'];
                    $content[$index]['fat_state'] = $item['fat_state'] ?? '';
                    $content[$index]['icon'] = $fat_kinds['icon'];
                    $content[$index]['h_icon'] = $fat_kinds['h_icon'];

                    $content[$index]['levels'] = [];
                    $content[$index]['level'] = [];
                }
                $content[$index]['display_progress'] = $item['display_progress'] ?? 0;
                $content[$index]['max_boundary'] = $item['max_boundary'] ?? 0;
                $content[$index]['boundaries'] = json_encode($item['boundaries'] ?? "[]");
                //存储每次测量记录的最高值与最低值,供图表统计获取
                $this->setMaxMinData($user_id, $user->fat_device, $content[$index]['fat_name'], ['fat_data' => $content[$index]['fat_data'], 'unit' => $content[$index]['unit']]);
            }
            $map['data'] = json_encode(array_values($content));

            return service_success($map['data']);
        } catch (\Exception $e) {
            AddErrorLog::dispatch('saveFatLog:' . $e->getMessage())->onQueue('health');
            return service_fail($e->getMessage());
        }
    }

    public function handleDisplayProgress($display_progress)
    {
        if ($display_progress < 5) {
            $display_progress = 5;
        }
        if ($display_progress >= 90) {
            $display_progress = 90;
        }
        return $display_progress;
    }

    public function getDisplayProgress($da, $weight)
    {
        $display_progress = 0;
        if ($weight == 0) {
            return $display_progress;
        }
        $boundaries = $da['boundaries'];
        $score = $da['score'];

        $max_config_value = $boundaries[1] ?? 1;
        if (in_array($da['e_name'], ["Bone", "Protein", "Subfat", "Water"])) {
            $max_config_value = $max_config_value * 2;
        }
        $max_config = [
            "Weight" => 100,
            "BMI" => 50,
            "Bodyfat" => 70,
            "Bone" => $max_config_value,
            "Protein" => $max_config_value,
            "Muscle" => 70,
            "Subfat" => $max_config_value,
            "Visfat" => 20,
            "Water" => $max_config_value,
            "Sinew" => $weight,
            "HeartRate" => 200,
            "HeartIndex" => 6,
        ];
        if (isset($max_config[$da['e_name']])) {
            $max = $max_config[$da['e_name']];
            array_push($boundaries, (string) $max);
        }
        $n = count($boundaries);
        $m = 0;
        // 判断所属的段
        for ($i = 0; $i < count($boundaries); $i++) {
            if ($score <= $boundaries[$i]) {
                $m = $i;
                break;
            }
        }
        if ($n == 0) {
            return $display_progress;
        }

        $min = isset($boundaries[$m - 1]) ? $boundaries[$m - 1] : 0;
        $max = isset($boundaries[$m]) ? $boundaries[$m] : 0;
        if ($max - $min == 0) {
            return $display_progress;
        }
        $display_progress = ((100 / $n) * ($m)) + ((($score - $min) / ($max - $min)) * (100 / $n));

        //        if($da['e_name'] == 'Weight'){
//            $display_progress = get_two_float($da['score']/100*100,2);
//        }elseif ($da['e_name'] == 'BMI'){
//            $display_progress = get_two_float($da['score']/50*100,2);
//        }elseif ($da['e_name'] == 'Bodyfat'){
//            $display_progress = get_two_float($da['score']/70*100,2);
//        }elseif ($da['e_name'] == 'Bone'){
//            $max = $da['boundaries'][1]??1 * 2;
//            $display_progress = get_two_float($da['score']/$max*100,2);
//        }elseif ($da['e_name'] == 'Protein'){
//            $max = $da['boundaries'][1]??1 * 2;
//            $display_progress = get_two_float($da['score']/$max*100,2);
//        }elseif ($da['e_name'] == 'Muscle'){
//            $display_progress = get_two_float($da['score']/70*100,2);
//        }elseif ($da['e_name'] == 'Subfat'){
//            $max = $da['boundaries'][1]??1 * 2;
//            $display_progress = get_two_float($da['score']/$max*100,2);
//        }elseif ($da['e_name'] == 'Visfat'){
//            $display_progress = get_two_float($da['score']/20*100,2);
//        }elseif ($da['e_name'] == 'Water'){
//            $max = $da['boundaries'][1]??1 * 2;
//            $display_progress = get_two_float($da['score']/$max*100,2);
//        }elseif ($da['e_name'] == 'Sinew'){
//            $display_progress = get_two_float($da['score']/$weight*100,2);
//        }elseif ($da['e_name'] == 'HeartRate'){
//            $display_progress = get_two_float($da['score']/200*100,2);
//        }elseif ($da['e_name'] == 'HeartIndex'){
//            $display_progress = get_two_float($da['score']/6*100,2);
//        }
        $display_progress = $this->handleDisplayProgress($display_progress);

        return get_two_float($display_progress, 2);
    }

    //    /**
//     * 预先存储每天测量的最大值,最小值,供图表统计查询
//     * @param $user_id
//     * @param $name
//     * @param $value
//     * @return bool
//     */
//    public  function setMaxMinData($user_id,$type,$name,$value,$date=null){
//        if(empty($user_id) || empty($name)){
//            return false;
//        }
//        //按日期将每个项的最大值最小值预先缓存,这样后续只需要获取缓存就可以,减少查库
//        if(empty($date)){
//            $date = date('Ymd');
//        }
//        $max_key = NewFatLog::REDIS_MAX_MIN_KEY.$user_id.':'.$date.'_'.$type.'_'.$name.'_max';
//        $min_key = NewFatLog::REDIS_MAX_MIN_KEY.$user_id.':'.$date.'_'.$type.'_'.$name.'_min';
//
//        $redis = Redis::client();
//        $max = $redis->get($max_key);
//        $fat_max = json_decode($max,true);
//        $fat_max_data = $fat_max['fat_data']??0;
//
//        $min = $redis->get($min_key);
//        $fat_min = json_decode($min,true);
//        $fat_min_data = $fat_min['fat_data']??0;
//        $expire = 180*24*60*60;
//        if(!$fat_max_data || $value['fat_data'] > $fat_max_data){
//            $redis->set($max_key,json_encode($value),$expire);
//        }
//        if(!$fat_min_data ||$value < $fat_min_data){
//            $redis->set($min_key,json_encode($value),$expire);
//        }
//        return true;
//    }

    public function setMaxMinData($user_id, $type, $name, $value, $date = null)
    {
        if (empty($user_id) || empty($name)) {
            return false;
        }
        //按日期将每个项的最大值最小值预先缓存,这样后续只需要获取缓存就可以,减少查库
        if (empty($date)) {
            $date = date('Ymd');
        }
        $max = FatMaxMin::where('user_id', $user_id)->where('date', $date)
            ->where('name', $name)
            ->where('type', $type)
            ->where('value_type', FatMaxMin::TYPE_MAX)
            ->first();

        $min = FatMaxMin::where('user_id', $user_id)->where('date', $date)
            ->where('name', $name)
            ->where('type', $type)
            ->where('value_type', FatMaxMin::TYPE_MIN)
            ->first();

        $map = [];
        $map['date'] = $date;
        $map['user_id'] = $user_id;
        $map['type'] = $type;
        $map['name'] = $name;
        $map['unit'] = $value['unit'];

        //最大值
        if (!$max) {
            $map['fat_data'] = $value['fat_data'];
            $map['value_type'] = FatMaxMin::TYPE_MAX;
            FatMaxMin::create($map);
        } else {
            if ($value['fat_data'] > $max->value) {
                $max->fat_data = $value['fat_data'];
                $max->save();
            }
        }
        //最小值
        if (!$min) {
            $map['fat_data'] = $value['fat_data'];
            $map['value_type'] = FatMaxMin::TYPE_MIN;
            FatMaxMin::create($map);
        } else {
            if ($value['fat_data'] < $min->value) {
                $min->fat_data = $value['fat_data'];
                $min->save();
            }
        }

        return true;
    }

    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;
    }

    public function getBoundaries($da, $weight = 0, $user)
    {
        $boundaries = array();
        $stature = $user->stature;
        $sex = $user->sex;
        if ($da['e_name'] == 'Sinew') {
            if ($sex == 1) {
                if ($stature < 160) {
                    $boundaries = ["38.5", "46.5"];
                } elseif ($stature >= 160 && $stature <= 170) {
                    $boundaries = ["44", "52.4"];
                } elseif ($stature > 170) {
                    $boundaries = ["49.4", "59.4"];
                }
            } else {
                if ($stature < 150) {
                    $boundaries = ["29.1", "34.7"];
                } elseif ($stature >= 150 && $stature <= 160) {
                    $boundaries = ["32.9", "37.5"];
                } elseif ($stature > 160) {
                    $boundaries = ["36.5", "42.5"];
                }
            }
        } elseif ($da['e_name'] == 'Visfat') {
            $boundaries = ["9", "14"];
        } elseif ($da['e_name'] == 'Protein') {
            if ($sex == 1) {
                $boundaries = ["16", "18"];
            } else {
                $boundaries = ["14", "16"];
            }
        } elseif ($da['e_name'] == 'Bone') {
            if ($sex == 1) {
                if ($weight <= 60) {
                    $boundaries = ["2.3", "2.7"];
                } elseif ($weight > 60 && $weight < 75) {
                    $boundaries = ["2.7", "3.1"];
                } elseif ($weight >= 75) {
                    $boundaries = ["3", "3.4"];
                }
            } else {
                if ($weight <= 45) {
                    $boundaries = ["1.6", "2"];
                } elseif ($weight > 45 && $weight < 60) {
                    $boundaries = ["2", "2.4"];
                } elseif ($weight >= 60) {
                    $boundaries = ["2.3", "2.7"];
                }
            }
        } elseif ($da['e_name'] == 'Water') {
            if ($sex == 1) {
                $boundaries = ["55", "65"];
            } else {
                $boundaries = ["45", "60"];
            }
        } elseif ($da['e_name'] == 'Score') {
            $boundaries = ["60", "80", "95"];
        } elseif ($da['e_name'] == 'Subfat') {
            if ($sex == 1) {
                $boundaries = ["8.6", "16.7"];
            } else {
                $boundaries = ["18.5", "26.7"];
            }
        } elseif ($da['e_name'] == 'Muscle') {
            if ($sex == 1) {
                $boundaries = ["49", "59"];
            } else {
                $boundaries = ["40", "50"];
            }
        } elseif ($da['e_name'] == 'Weight') {
            if ($sex == 1) {
                $sw = get_two_float(($stature - 80) * 0.7, 2);
                $boundaries = [(string) get_two_float(0.8 * $sw, 2), (string) get_two_float(0.9 * $sw, 2), (string) get_two_float(1.1 * $sw, 2), (string) get_two_float(1.2 * $sw, 2)];
            } elseif ($sex == 2) {
                $sw = get_two_float(($stature * 1.37 - 110) * 0.45, 2);
                $boundaries = [(string) get_two_float(0.8 * $sw, 2), (string) get_two_float(0.9 * $sw, 2), (string) get_two_float(1.1 * $sw, 2), (string) get_two_float(1.2 * $sw, 2)];
            }
        } elseif ($da['e_name'] == 'Bodyfat') {
            if ($sex == 1) {
                $boundaries = ["11", "21", "26"];
            } else {
                $boundaries = ["21", "31", "36"];
            }
        } elseif ($da['e_name'] == 'BMI') {
            $boundaries = ["18.5", "25"];
        } elseif ($da['e_name'] == 'HeartRate') {
            $boundaries = ["40", "60", "100", "160"];
        } elseif ($da['e_name'] == 'HeartIndex') {
            $boundaries = ["2.5", "4.2"];
        }
        return $boundaries;
    }

    public function calDescKey($da, $weight = 0, $version_type = Version::TYPE_MP, $user)
    {
        $desc_key = '';
        if ($da['e_name'] == 'Score') {
            $score = $da['score'];
            //            $boundaries = json_decode($da['boundaries'], true);
            if ($score < 60) {
                $desc_key = 'Score.1002';
            } elseif ($score < 80 && $score >= 60) {
                $desc_key = 'Score.1003';
            } elseif ($score < 95 && $score >= 80) {
                $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($user->birthday);
            if ($da['score'] <= $age) {
                $desc_key = "BodyAge.1002";
            } else {
                $desc_key = "BodyAge.1003";
            }
        } elseif ($da['e_name'] == 'BMR') {
            $age = CommonService::getAge($user->birthday);
            $value = $this->getBMRValue($user->sex, $age);
            if ($da['score'] >= $value * 60) {
                $desc_key = "BMR.1002";
            } else {
                $desc_key = "BMR.1003";
            }
        } elseif ($da['e_name'] == 'BodyShape') {
            if ($version_type == Version::TYPE_APP) {
                switch ($da['score']) {
                    case 2:
                        $desc_key = "BodyShape.1002";
                        break;
                    case 5:
                        $desc_key = 'BodyShape.1003';
                        break;
                    case 3:
                        $desc_key = 'BodyShape.1004';
                        break;
                    case 9:
                        $desc_key = 'BodyShape.1005';
                        break;
                    case 8:
                        $desc_key = 'BodyShape.1006';
                        break;
                    case 4:
                        $desc_key = 'BodyShape.1007';
                        break;
                    case 1:
                        $desc_key = 'BodyShape.1008';
                        break;
                    case 7:
                        $desc_key = 'BodyShape.1009';
                        break;
                    case 6:
                        $desc_key = 'BodyShape.1010';
                        break;
                    default:
                        $desc_key = 'BodyShape.1007';
                        break;
                }
            } else {
                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;
                }
            }
        } elseif ($da['e_name'] == 'Sinew') {
            if ($user->sex == 1) {
                if ($user->stature < 160) {
                    if ($da['score'] < 38.5) {
                        $desc_key = 'Sinew.1002';
                    } elseif ($da['score'] >= 38.5 && $da['score'] <= 46.5) {
                        $desc_key = 'Sinew.1003';
                    } elseif ($da['score'] > 46.5) {
                        $desc_key = 'Sinew.1004';
                    }
                } elseif ($user->stature >= 160 && $user->stature <= 170) {
                    if ($da['score'] < 44) {
                        $desc_key = 'Sinew.1002';
                    } elseif ($da['score'] >= 44 && $da['score'] <= 52.4) {
                        $desc_key = 'Sinew.1003';
                    } elseif ($da['score'] > 52.4) {
                        $desc_key = 'Sinew.1004';
                    }
                } elseif ($user->stature > 170) {
                    if ($da['score'] < 49.4) {
                        $desc_key = 'Sinew.1002';
                    } elseif ($da['score'] >= 49.4 && $da['score'] <= 59.4) {
                        $desc_key = 'Sinew.1003';
                    } elseif ($da['score'] > 59.4) {
                        $desc_key = 'Sinew.1004';
                    }
                }
            } elseif ($user->sex == 2) {
                if ($user->stature < 150) {
                    if ($da['score'] < 29.1) {
                        $desc_key = 'Sinew.1002';
                    } elseif ($da['score'] >= 29.1 && $da['score'] <= 34.7) {
                        $desc_key = 'Sinew.1003';
                    } elseif ($da['score'] > 34.7) {
                        $desc_key = 'Sinew.1004';
                    }
                } elseif ($user->stature >= 150 && $user->stature <= 160) {
                    if ($da['score'] < 32.9) {
                        $desc_key = 'Sinew.1002';
                    } elseif ($da['score'] >= 32.9 && $da['score'] <= 37.5) {
                        $desc_key = 'Sinew.1003';
                    } elseif ($da['score'] > 52.4) {
                        $desc_key = 'Sinew.1004';
                    }
                } elseif ($user->stature > 160) {
                    if ($da['score'] < 36.5) {
                        $desc_key = 'Sinew.1002';
                    } elseif ($da['score'] >= 36.5 && $da['score'] <= 42.5) {
                        $desc_key = 'Sinew.1003';
                    } elseif ($da['score'] > 42.5) {
                        $desc_key = 'Sinew.1004';
                    }
                }
            }
        } elseif ($da['e_name'] == 'Visfat') {
            if ($da['score'] <= 9) {
                $desc_key = 'Visfat.1002';
            } elseif ($da['score'] > 9 && $da['score'] <= 14) {
                $desc_key = 'Visfat.1003';
            } elseif ($da['score'] > 14) {
                $desc_key = 'Visfat.1004';
            }
        } elseif ($da['e_name'] == 'Protein') {
            if ($user->sex == 1) {
                if ($da['score'] <= 16) {
                    $desc_key = 'Protein.1002';
                } elseif ($da['score'] >= 16 && $da['score'] <= 18) {
                    $desc_key = 'Protein.1003';
                } elseif ($da['score'] > 18) {
                    $desc_key = 'Protein.1004';
                }
            } elseif ($user->sex == 2) {
                if ($da['score'] <= 14) {
                    $desc_key = 'Protein.1002';
                } elseif ($da['score'] >= 14 && $da['score'] <= 16) {
                    $desc_key = 'Protein.1003';
                } elseif ($da['score'] > 16) {
                    $desc_key = 'Protein.1004';
                }
            }
        } elseif ($da['e_name'] == 'Bone') {
            if ($user->sex == 1) {
                if ($weight <= 60) {
                    if ($da['score'] <= 2.3) {
                        $desc_key = 'Bone.1002';
                    } elseif ($da['score'] >= 2.3 && $da['score'] <= 2.7) {
                        $desc_key = 'Bone.1003';
                    } elseif ($da['score'] > 2.7) {
                        $desc_key = 'Bone.1004';
                    }
                } elseif ($weight > 60 && $weight < 75) {
                    if ($da['score'] <= 2.7) {
                        $desc_key = 'Bone.1002';
                    } elseif ($da['score'] >= 2.7 && $da['score'] <= 3.1) {
                        $desc_key = 'Bone.1003';
                    } elseif ($da['score'] > 3.1) {
                        $desc_key = 'Bone.1004';
                    }
                } elseif ($weight >= 75) {
                    if ($da['score'] <= 3) {
                        $desc_key = 'Bone.1002';
                    } elseif ($da['score'] >= 3 && $da['score'] <= 3.4) {
                        $desc_key = 'Bone.1003';
                    } elseif ($da['score'] > 3.4) {
                        $desc_key = 'Bone.1004';
                    }
                }
            } elseif ($user->sex == 2) {
                if ($weight <= 45) {
                    if ($da['score'] <= 1.6) {
                        $desc_key = 'Bone.1002';
                    } elseif ($da['score'] >= 1.6 && $da['score'] <= 2) {
                        $desc_key = 'Bone.1003';
                    } elseif ($da['score'] > 2) {
                        $desc_key = 'Bone.1004';
                    }
                } elseif ($weight > 45 && $weight < 60) {
                    if ($da['score'] <= 2) {
                        $desc_key = 'Bone.1002';
                    } elseif ($da['score'] >= 2 && $da['score'] <= 2.4) {
                        $desc_key = 'Bone.1003';
                    } elseif ($da['score'] > 2.4) {
                        $desc_key = 'Bone.1004';
                    }
                } elseif ($weight >= 60) {
                    if ($da['score'] <= 2.3) {
                        $desc_key = 'Bone.1002';
                    } elseif ($da['score'] >= 2.3 && $da['score'] <= 2.7) {
                        $desc_key = 'Bone.1003';
                    } elseif ($da['score'] > 2.7) {
                        $desc_key = 'Bone.1004';
                    }
                }
            }
        } elseif ($da['e_name'] == 'Water') {
            if ($user->sex == 1) {
                if ($da['score'] <= 55) {
                    $desc_key = 'Water.1002';
                } elseif ($da['score'] >= 55 && $da['score'] <= 65) {
                    $desc_key = 'Water.1003';
                } elseif ($da['score'] > 65) {
                    $desc_key = 'Water.1004';
                }
            } elseif ($user->sex == 2) {
                if ($da['score'] <= 45) {
                    $desc_key = 'Water.1002';
                } elseif ($da['score'] >= 45 && $da['score'] <= 60) {
                    $desc_key = 'Water.1003';
                } elseif ($da['score'] > 60) {
                    $desc_key = 'Water.1004';
                }
            }
        } elseif ($da['e_name'] == 'Subfat') {
            if ($user->sex == 1) {
                if ($da['score'] <= 8.6) {
                    $desc_key = 'Subfat.1002';
                } elseif ($da['score'] >= 8.6 && $da['score'] <= 16.7) {
                    $desc_key = 'Subfat.1003';
                } elseif ($da['score'] > 16.7) {
                    $desc_key = 'Subfat.1004';
                }
            } elseif ($user->sex == 2) {
                if ($da['score'] <= 18.5) {
                    $desc_key = 'Subfat.1002';
                } elseif ($da['score'] >= 18.5 && $da['score'] <= 26.7) {
                    $desc_key = 'Subfat.1003';
                } elseif ($da['score'] > 26.7) {
                    $desc_key = 'Subfat.1004';
                }
            }
        } elseif ($da['e_name'] == 'Muscle') {
            if ($user->sex == 1) {
                if ($da['score'] <= 49) {
                    $desc_key = 'Muscle.1002';
                } elseif ($da['score'] >= 49 && $da['score'] <= 59) {
                    $desc_key = 'Muscle.1003';
                } elseif ($da['score'] > 59) {
                    $desc_key = 'Muscle.1004';
                }
            } elseif ($user->sex == 2) {
                if ($da['score'] <= 40) {
                    $desc_key = 'Muscle.1002';
                } elseif ($da['score'] >= 40 && $da['score'] <= 50) {
                    $desc_key = 'Muscle.1003';
                } elseif ($da['score'] > 50) {
                    $desc_key = 'Muscle.1004';
                }
            }
        } elseif ($da['e_name'] == 'Bodyfat') {
            if ($user->sex == 1) {
                if ($da['score'] < 11) {
                    $desc_key = 'Bodyfat.1002';
                } elseif ($da['score'] >= 11 && $da['score'] <= 21) {
                    $desc_key = 'Bodyfat.1003';
                } elseif ($da['score'] > 21 && $da['score'] <= 26) {
                    $desc_key = 'Bodyfat.1004';
                } elseif ($da['score'] > 26) {
                    $desc_key = 'Bodyfat.1005';
                }
            } elseif ($user->sex == 2) {
                if ($da['score'] <= 21) {
                    $desc_key = 'Bodyfat.1002';
                } elseif ($da['score'] >= 21 && $da['score'] <= 31) {
                    $desc_key = 'Bodyfat.1003';
                } elseif ($da['score'] >= 31 && $da['score'] <= 36) {
                    $desc_key = 'Bodyfat.1004';
                } elseif ($da['score'] > 36) {
                    $desc_key = 'Bodyfat.1005';
                }
            }
        } elseif ($da['e_name'] == 'BMI') {
            if ($da['score'] < 18.5) {
                $desc_key = 'BMI.1002';
            } elseif ($da['score'] >= 18.5 && $da['score'] <= 25) {
                $desc_key = 'BMI.1003';
            } elseif ($da['score'] > 25) {
                $desc_key = 'BMI.1005';
            }
        } elseif ($da['e_name'] == 'HeartRate') {
            if ($da['score'] < 40) {
                $desc_key = 'HeartRate.1002';
            } elseif ($da['score'] >= 40 && $da['score'] <= 60) {
                $desc_key = 'HeartRate.1003';
            } elseif ($da['score'] >= 60 && $da['score'] <= 100) {
                $desc_key = 'HeartRate.1004';
            } elseif ($da['score'] >= 100 && $da['score'] <= 160) {
                $desc_key = 'HeartRate.1005';
            } elseif ($da['score'] > 160) {
                $desc_key = 'HeartRate.1006';
            }
        } elseif ($da['e_name'] == 'HeartIndex') {
            if ($da['score'] <= 2.5) {
                $desc_key = 'HeartIndex.1002';
            } elseif ($da['score'] >= 2.5 && $da['score'] <= 4.2) {
                $desc_key = 'HeartIndex.1003';
            } elseif ($da['score'] > 4.2) {
                $desc_key = 'HeartIndex.1004';
            }
        } elseif ($da['e_name'] == 'Weight') {
            if ($user->sex == 1) {
                $sw = get_two_float(($user->stature - 80) * 0.7, 2);
                if ($da['score'] <= 0.8 * $sw) {
                    $desc_key = 'Weight.1002';
                } elseif ($da['score'] > 0.8 * $sw && $da['score'] < 0.9 * $sw) {
                    $desc_key = 'Weight.1003';
                } elseif ($da['score'] >= 0.9 * $sw && $da['score'] <= 1.1 * $sw) {
                    $desc_key = 'Weight.1004';
                } elseif ($da['score'] > 1.1 * $sw && $da['score'] <= 1.2 * $sw) {
                    $desc_key = 'Weight.1005';
                } elseif ($da['score'] > 1.2 * $sw) {
                    $desc_key = 'Weight.1006';
                }
            } elseif ($user->sex == 2) {
                $sw = get_two_float(($user->stature * 1.37 - 110) * 0.45, 2);
                if ($da['score'] <= 0.8 * $sw) {
                    $desc_key = 'Weight.1002';
                } elseif ($da['score'] > 0.8 * $sw && $da['score'] < 0.9 * $sw) {
                    $desc_key = 'Weight.1003';
                } elseif ($da['score'] >= 0.9 * $sw && $da['score'] <= 1.1 * $sw) {
                    $desc_key = 'Weight.1004';
                } elseif ($da['score'] > 1.1 * $sw && $da['score'] <= 1.2 * $sw) {
                    $desc_key = 'Weight.1005';
                } elseif ($da['score'] > 1.2 * $sw) {
                    $desc_key = 'Weight.1006';
                }
            }
        }
        return $desc_key;
    }


    /**
     * 获取称重记录
     * @param $user
     * @return array
     */
    public function getFatLogList($user, $service_user_id = "")
    {
        try {
            // $unit = $user->unit;
            $unit = "斤";
            $language = $user->language;
            $fat_device = $user->fat_device;
            //如果存在服务人员,说明是app过来的,默认获取新称数据
            if (!empty($service_user_id)) {
                $fat_device = User::FAT_DEVICE_YUNKANGBAO;
            }
            $logs = NewFatLog::where('user_id', $user->id)
                ->where('type', $fat_device)
                ->orderByDesc('created_at')
                ->select('id', 'data', 'type', 'created_at')
                ->paginate();
            foreach ($logs as $index => $log) {
                $data = json_decode($log->data, true);
                foreach ($data as $item) {
                    if ($item['fat_name'] != '体重') {
                        continue;
                    }
                    $logs[$index]['fat_name'] = $item['fat_name'];
                    $logs[$index]['yearMonth'] = date('Y年m月', strtotime($log->created_at));
                    $logs[$index]['dayHour'] = date('d日 H:i', strtotime($log->created_at));
                    $logs[$index]['unit'] = get_user_unit($language, $unit);
                    $logs[$index]['fat_data'] = $item['fat_data'];
                    if ($unit != 'kg') {
                        if (($unit == 'lb' || $unit == '斤') && $language == User::LANGUAGE_EN) {
                            $logs[$index]['fat_data'] = get_unit_rate($item['fat_data'], $fat_device);
                        } else {
                            $logs[$index]['fat_data'] = $item['fat_data'] * NewFatLog::WEIGHT_JIN_KG_RATE;
                        }
                    }
                    $logs[$index]['fat_data'] = (string) get_two_float($logs[$index]['fat_data'], 2);
                    unset($logs[$index]['data']);
                    break;
                }
            }
            return service_success($logs);
        } catch (\Exception $e) {
            AddErrorLog::dispatch('getFatLogList:' . $e->getMessage())->onQueue('health');
            return service_fail($e->getMessage());
        }
    }

    /**
     * 获取图表统计数据
     * @param $name
     * @param $start_date
     * @param $end_date
     * @return array
     */
    public function getFatStat($name, $start_date, $end_date, $user, $unit = "")
    {
        if ($start_date && $end_date) {
            // 将日期时间字符串转换为 Carbon 实例
            $startDateTime = Carbon::parse($start_date);
            $endDateTime = Carbon::parse($end_date);
            // 计算两个日期之间的间隔
            $interval = $endDateTime->diff($startDateTime);
            // 获取间隔中的天数
            $days = $interval->days;
            if ($days >= 180) {
                return service_fail("天数相隔过大");
            }
            $day_arr = CommonService::daliy($start_date, $end_date);
        } else {
            $day_arr = CommonService::daliy(date('Y-m-d', strtotime('-180 days')), date('Y-m-d'));
        }
        $user_id = $user->id;
        $type = $user->fat_device;
        if (empty($unit)) {
            $unit = $user->unit;
        }
        $language = $user->language;
        $x_arr = [];
        $y_arr = [];
        $z_arr = [];

        foreach ($day_arr as $day) {
            $date = date('Ymd', strtotime($day));
            $max_fat = FatMaxMin::where('date', $date)
                ->where('user_id', $user_id)
                ->where('name', $name)
                ->where('type', $type)
                ->where('value_type', FatMaxMin::TYPE_MAX)
                ->first();

            $min_fat = FatMaxMin::where('date', $date)
                ->where('user_id', $user_id)
                ->where('name', $name)
                ->where('type', $type)
                ->where('value_type', FatMaxMin::TYPE_MIN)
                ->first();
            if ($max_fat && $min_fat) {
                $max_fat = change_user_unit($max_fat->toArray(), $unit, $language, $user->fat_device);
                $min_fat = change_user_unit($min_fat->toArray(), $unit, $language, $user->fat_device);

                $x_arr[] = date('m/d', strtotime($day));
                $y_arr[] = $max_fat['fat_data'] ?? 0;
                $z_arr[] = $min_fat['fat_data'] ?? 0;
            }
        }

        //如果没有数据,则默认5天的0数据
        if (empty($x_arr)) {
            $init_dates = CommonService::daliy(date('Y-m-d', strtotime('-4 days')), date('Y-m-d'));
            foreach ($init_dates as $init_date) {
                $x_arr[] = date('m/d', strtotime($init_date));
            }
            $y_arr = [0, 0, 0, 0, 0];
            $z_arr = [0, 0, 0, 0, 0];
        }
        $data['x_arr'] = $x_arr;
        $data['y_arr'] = $y_arr;
        $data['z_arr'] = $z_arr;
        $data['fat_device'] = $user->fat_device ?? User::FAT_DEVICE_TIANCHENG;
        return service_success($data);

    }

    /**
     * 对比两个数据
     * @param $user
     * @param $start_id
     * @param $end_id
     * @return array
     */
    public function getCompareFatData($user, $start_id, $end_id, $unit = "")
    {
        try {
            //判断两个时间大小
            if ($start_id > $end_id) {
                $temp_id = $start_id;
                $start_id = $end_id;
                $end_id = $temp_id;
            }
            $start_data = NewFatLog::where('id', $start_id)->first();
            $end_data = NewFatLog::where('id', $end_id)->first();

            if (empty($start_data) || empty($end_data)) {
                return service_fail('查询失败');
            }

            $start_logs = json_decode($start_data->data, true);
            $end_logs = json_decode($end_data->data, true);

            $start_date = new \DateTime($start_data->created_at);
            $end_date = new \DateTime($end_data->created_at);

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

            //判断用户信息
            if (empty($unit)) {
                $user->unit = get_user_unit($user->language, $user->unit);
                $unit = $user->unit ?? 'kg';
            }
            foreach ($start_logs as &$start_log) {
                $start_log = change_user_unit($start_log, $unit, $user->language, $user->fat_device);
            }
            foreach ($end_logs as &$end_log) {
                $end_log = change_user_unit($end_log, $unit, $user->language, $user->fat_device);
            }
            //对比两个数组的差值
            $merge_logs = [];
            foreach ($start_logs as $start) {
                foreach ($end_logs as $end) {
                    if (!isset($start['fat_name']) || !isset($end['fat_name'])) {
                        continue;
                    }
                    if ($start['fat_name'] != $end['fat_name']) {
                        continue;
                    }
                    if (in_array($start['fat_name'], ['体重控制', '脂肪控制', '肌肉控制', '脂肪重量', '健康评分']) && $user->fat_device == User::FAT_DEVICE_YUNKANGBAO) {
                        continue;
                    }
                    $status = 0;
                    $differ = '-';
                    $start['fat_data'] = floatval(str_replace(',', '', $start['fat_data']));
                    $end['fat_data'] = floatval(str_replace(',', '', $end['fat_data']));
                    if ($start['fat_data'] < $end['fat_data']) {
                        $status = 1;
                        $differ = get_two_float(abs($end['fat_data'] - $start['fat_data']), 2);
                    }
                    if ($start['fat_data'] > $end['fat_data']) {
                        $status = 2;
                        $differ = get_two_float(abs($end['fat_data'] - $start['fat_data']), 2);
                    }
                    $merge_logs[] = [
                        'fat_name' => $start['fat_name'],
                        'status' => $status,
                        'differ' => $differ,
                        'unit' => $start['unit']
                    ];
                }
            }
            // 创建一个集合来跟踪唯一的 fat_name
            $unique_fat_names = $filtered_merge_logs = [];
            foreach ($merge_logs as $item) {
                $fat_name = $item['fat_name'];
                if (!in_array($fat_name, $unique_fat_names)) {
                    $unique_fat_names[] = $fat_name; // 添加到集合
                    $filtered_merge_logs[] = $item; // 添加到结果数组
                }
            }
            $unique_start_logs = []; // 存储唯一 'fat_name' 的日志
            $seen_fat_names = []; // 存储已经遇到的 'fat_name'
            foreach ($start_logs as $log) {
                if (!in_array($log['fat_name'], $seen_fat_names) && in_array($log['fat_name'], $unique_fat_names)) {
                    $seen_fat_names[] = $log['fat_name']; // 标记 'fat_name' 已遇到
                    $unique_start_logs[] = $log; // 将此日志加入结果数组
                }
            }
            // 去重 end_logs
            $unique_end_logs = []; // 存储唯一 'fat_name' 的日志
            $seen_fat_names = []; // 重置集合

            foreach ($end_logs as $log) {
                if (!in_array($log['fat_name'], $seen_fat_names) && in_array($log['fat_name'], $unique_fat_names)) {
                    $seen_fat_names[] = $log['fat_name']; // 标记 'fat_name' 已遇到
                    $unique_end_logs[] = $log; // 将此日志加入结果数组
                }
            }

            // 对 $unique_start_logs 和 $unique_end_logs 按 'fat_name' 排序
            array_multisort(array_column($filtered_merge_logs, 'fat_name'), SORT_ASC, $filtered_merge_logs);
            array_multisort(array_column($unique_start_logs, 'fat_name'), SORT_ASC, $unique_start_logs);
            array_multisort(array_column($unique_end_logs, 'fat_name'), SORT_ASC, $unique_end_logs);

            $unique_start_logs = array_values($unique_start_logs);
            $unique_end_logs = array_values($unique_end_logs);

            $data = [];
            $data['start_logs'] = $unique_start_logs;
            $data['end_logs'] = $unique_end_logs;
            $data['merge_logs'] = $filtered_merge_logs;
            $data['user'] = $user;
            $data['differ_day'] = $differ_day;
            $data['start_time'] = $start_data->toArray()['created_at'];
            $data['end_time'] = $end_data->toArray()['created_at'];
            return service_success($data);
        } catch (\Exception $e) {
            AddErrorLog::dispatch('getCompareFatData:' . $e->getMessage())->onQueue('health');
            return service_fail($e->getMessage());
        }
    }

    /**
     * 获取图表数据
     * @param $user
     * @return array
     */
    public function getFatKinds($user)
    {
        try {
            //这里本来还可以将图标的数据处理到一个表数据里面的,用类型来区分,但是migrate删除和新增表都麻烦,没有加数据的权限,需要写接口,先这样
            if ($user->fat_device == User::FAT_DEVICE_YUNKANGBAO) {
                $kinds = HealthKind::where(function ($sql) {
                    $sql->where('icon', '!=', '')->where('e_name', '!=', 'BodyShape');
                })->select('name as fat_name', 'e_name', 'icon', 'h_icon', 'unit')->get();
                foreach ($kinds as $kind) {
                    if ($kind->unit == 'kg' && $user->unit != $kind->unit) {
                        $kind->unit = '斤';
                    }
                }
            } else {
                $kinds = FatKind::where(function ($sql) {
                    $sql->where('icon', '!=', '');
                })->select('fat_name', 'icon', 'h_icon', 'unit')->get();
                $fat_names = [
                    '脂肪占比' => '脂肪率',
                    '体内水分' => '水分率',
                    '肌肉占比' => '肌肉率',
                    '卡路里' => '基础代谢',
                    '体脂重量' => '脂肪重量',
                    '蛋白质' => '蛋白质重量',
                    '脂肪控制' => '体重控制量',
                ];
                foreach ($kinds as $kind) {
                    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 service_success($kinds);
        } catch (\Exception $e) {
            AddErrorLog::dispatch('getFatKinds:' . $e->getMessage())->onQueue('health');
            return service_fail($e->getMessage());
        }
    }

    /**
     * 计算各体脂增减量（用于体脂详情）
     * @param $log
     * @return string
     */
    public function calHealth($log, $user_unit, $language)
    {
        $boundaries = $log['boundaries'];
        if (empty($boundaries)) {
            return '';
        }
        $unit = "kg";
        if (in_array($log['e_name'], ['Weight', 'Sinew', 'Bone'])) {
            $unit = get_user_unit($language, $user_unit);
            if (in_array($log['e_name'], ['Weight', 'Sinew', 'Bone'])) {
                $boundaries = change_boundaries($boundaries, $unit, $language);
            }

        }
        switch ($log['e_name']) {
            case "Weight":
                $control = $this->healthDiffValue($log['fat_data'], $boundaries[2], $boundaries[1], $unit);
                break;
            case "HeartRate":
                $control = $this->healthDiffValue($log['fat_data'], $boundaries[2], $boundaries[1], 'bmp');
                break;
            case "HeartIndex":
                $control = $this->healthDiffValue($log['fat_data'], $boundaries[1], $boundaries[0], 'L/min/m^2');
                break;
            case "Bodyfat":
            case "Water":
            case "Muscle":
            case "Protein":
            case "Subfat":

                $control = $this->healthDiffValue($log['fat_data'], $boundaries[1], $boundaries[0], '%');
                break;
            case "Bone":
            case "Sinew":
                $control = $this->healthDiffValue($log['fat_data'], $boundaries[1], $boundaries[0], $unit);
                break;
            case "Visfat":
                $control = $this->healthDiffValue($log['fat_data'], $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 $id
     * @param $user_id
     * @param $unit
     * @return array
     */
    public function getFatDetail($id, $user_id, $unit, $user)
    {
        try {

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

            $fat_device = $user->fat_device;
            $detail = NewFatLog::where('id', $id)->where('type', $fat_device)->select('id', 'data', 'created_at')->first();
            if (empty($detail)) {
                return service_fail('数据不存在');
            }
            $logs = json_decode($detail->data, true);
            foreach ($logs as &$log) {
                $boundaries = json_decode($log['boundaries'], true);
                $log['boundaries'] = is_array($boundaries) ? $boundaries : [];
                $log = change_user_unit($log, $unit, $user->language, $user->fat_device);
                if ($fat_device == User::FAT_DEVICE_YUNKANGBAO) {
                    $log['control'] = $this->calHealth($log, $unit, $user->language);

                    if (in_array($log['e_name'], ['Weight', 'Sinew', 'Bone'])) {
                        $log['boundaries'] = change_boundaries($log['boundaries'], $unit, $user->language);
                    }
                }
            }
            //处理数组
            foreach ($logs as $key => $value) {
                if (in_array($value['fat_name'], ['体重控制', '脂肪控制', '肌肉控制', '脂肪重量', '健康评分']) && $user->fat_device == User::FAT_DEVICE_YUNKANGBAO) {
                    unset($logs[$key]);
                    continue;
                }
                foreach ($value['boundaries'] as $index => $val) {
                    $logs[$key]['boundaries'][$index] = (string) $val;
                }
            }
            $logs = array_values($logs);
            return service_success($logs);
        } catch (\Exception $e) {
            AddErrorLog::dispatch('getFatDetail:' . $e->getMessage() . ", line: " . $e->getLine())->onQueue('health');
            return service_fail($e->getMessage() . " line: " . $e->getLine());
        }
    }
}
