using Nirvana.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using YBDevice.Entity;

namespace YBDevice.Api.DBServices
{
    /// <summary>
    /// 体脂计算算法
    /// </summary>
    public class BodyFatHelper
    {
        /// <summary>
        /// 计算体脂
        /// </summary>
        /// <param name="weight">体重,单位为kg</param>
        /// <param name="height">身高,单位为米</param>
        /// <param name="age">年龄</param>
        /// <param name="adc">阻抗</param>
        /// <param name="sex">性别,1-男，2-女,0-未知</param>
        /// <returns></returns>
        public static UserMeasureModel CalcBodyFat(double weight, int height, int age, int adc, int sex)
        {
            //算法使用的性别为0-女,1-男
            sex = sex == 2 ? 0 : 1;
            var result = GetBodyfatResults(weight, height / 100, age, adc, sex);

            var data = new UserMeasureModel
            {
                bmi = result.bmi.ToDecimal(),
                bmiLevel = bmi(result.bmi.ToFloat()),
                fat_r = result.bfr.ToDecimal(),
                fat_rLevel = Fat_r(result.bfr.ToFloat(), sex, age),
                bodyage = result.physicAge.ToInt(),
                bodyageLevel = bodyage(result.physicAge.ToInt(), age),
                fat_w = (result.bfr.ToDouble() * weight / 100).ToDecimal(2),
                fat_wLevel = Fat_r(result.bfr.ToFloat(), sex, age),
                bone = result.bm.ToDecimal(),
                boneLevel = bone(result.bm.ToFloat(), weight, sex),
                kcal = result.bmr.ToDecimal() < 0 ? 0 : result.bmr.ToDecimal(),
                kcalLevel = kcal(result.bmr.ToFloat(), weight, age, sex),
                muscle = result.rom.ToDecimal(),
                muscleLevel = muscle(result.rom.ToFloat(), weight, age, sex),
                protein = result.pp.ToDecimal(),
                proteinLevel = protein(result.pp.ToFloat(), weight, age, sex),
                visceral = result.uvi.ToDecimal(),
                visceralLevel = visceral(result.uvi.ToFloat(), weight, age, sex),
                water = result.moi.ToDecimal(),
                waterLevel = water(result.moi.ToFloat(), weight, age, sex),
                cmi = score(result.bmi.ToFloat()).ToDecimal(2),
                muscleval = (weight * (result.rom.ToDouble() / 100)).ToDecimal(2),
                proteinval = (weight * (result.pp.ToDouble() / 100)).ToDecimal(2),
                lbm = ((1 - result.bfr.ToDouble() / 100) * weight).ToDecimal(2),
                standardWeight = standweight(height.ToInt(), sex).ToString("f2"),
                sfr = result.sfr.ToDecimal(2),
                sfrLevel = sfr(result.sfr.ToFloat(), weight, age, sex, height.ToInt()),
                body = "0",
                standardfat_r = fa_r_value(sex, age).ToJson(),
                standardbmi = bmi_value(sex, age).ToJson(),
                standardmuscle = muscle_value(sex, age).ToJson(),
                standardwater = water_value(sex, age).ToJson(),
                standardbone = bone_value(sex, age, weight.ToDecimal()).ToJson(),
                standardkcal = kcal_value(sex, age, weight.ToDecimal()).ToJson(),
                standardfat_w = "",
                standardviscera = visceral_value(sex, age).ToJson(),
                standardprotein = protein_value(sex, age).ToJson(),
                standardbodyage = "",
                standardsfr = sfr_value(sex, age).ToJson(),

            };
            data.bodylevel = body(data.fat_rLevel, data.muscleLevel);
            data.musulevalLevel = data.muscleLevel;
            data.proteinvalLevel = data.proteinLevel;
            double level = (weight - data.standardWeight.ToDouble()) / data.standardWeight.ToDouble();
            data.fatLevel = fatlevel(level);
            data.fatlevel = level.ToDecimal();
            return data;
        }

        /// <summary>
        /// 身体得分
        /// </summary>
        /// <param name="bmi"></param>
        /// <returns></returns>
        public static double score(float bmi)
            => bmi switch
            {
                _ when bmi < 21.6 => bmi / 21.6 * 100,
                _ when bmi >= 21.6 => 21.6 / bmi * 100,
                _ => 60
            };


        /// <summary>
        /// 体型
        /// </summary>
        /// <param name="fat_r">体脂率</param>
        /// <param name="muscle">肌肉率</param>
        /// <returns></returns>
        public static string body(string fat_r, string muscle)
          => (fat_r, muscle) switch
          {
              _ when (fat_r == NewLevelModel.high || fat_r == NewLevelModel.mhigh) && muscle == NewLevelModel.notenu => NewLevelModel.hidefat,
              _ when (fat_r == NewLevelModel.high || fat_r == NewLevelModel.mhigh) && muscle == NewLevelModel.normal => NewLevelModel.fat,
              _ when (fat_r == NewLevelModel.high || fat_r == NewLevelModel.mhigh) && muscle == NewLevelModel.fine => NewLevelModel.strongfat,
              _ when (fat_r == NewLevelModel.normal) && muscle == NewLevelModel.notenu => NewLevelModel.notenumuscle,
              _ when (fat_r == NewLevelModel.normal) && muscle == NewLevelModel.normal => NewLevelModel.normalfat,
              _ when (fat_r == NewLevelModel.normal) && muscle == NewLevelModel.fine => NewLevelModel.normalmuscle,
              _ when (fat_r == NewLevelModel.flat) && muscle == NewLevelModel.notenu => NewLevelModel.thin,
              _ when (fat_r == NewLevelModel.flat) && muscle == NewLevelModel.normal => NewLevelModel.thinmuscle,
              _ when (fat_r == NewLevelModel.flat) && muscle == NewLevelModel.fine => NewLevelModel.perfetmuscle,
              _ => NewLevelModel.hidefat
          };

        /// <summary>
        /// 肥胖等级
        /// </summary>
        /// <param name="level">level=(体重-标准体重)/标准体重</param>
        /// <returns></returns>
        public static string fatlevel(double level)
            => level switch
            {
                _ when level < -0.2 => NewLevelModel.weightnotenu,
                _ when level >= -0.2 && level < -0.1 => NewLevelModel.thin,
                _ when level >= -0.1 && level <= 0.1 => NewLevelModel.normal,
                _ when level > 0.1 && level <= 0.2 => NewLevelModel.weight,
                _ when level > 0.2 => NewLevelModel.mweight,
                _ => NewLevelModel.weightnotenu
            };

        /// <summary>
        /// 皮下脂肪标准
        /// </summary>
        /// <param name="sfr"></param>
        /// <param name="weight"></param>
        /// <param name="age"></param>
        /// <param name="sex"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static string sfr(float sfr, double weight, int age, int sex, int height)
           => (weight, age, sex, height) switch
           {
               _ when sex == 1 && sfr < 7 => NewLevelModel.notenu,
               _ when sex == 0 && sfr < 11 => NewLevelModel.notenu,
               _ when sex == 1 && sfr >= 7 && sfr < 15 => NewLevelModel.normal,
               _ when sex == 0 && sfr >= 11 && sfr < 17 => NewLevelModel.normal,
               _ when sex == 1 && sfr >= 15 => NewLevelModel.high,
               _ when sex == 0 && sfr >= 17 => NewLevelModel.high,
               _ => NewLevelModel.notenu
           };

        /// <summary>
        /// 标准体重
        /// </summary>
        /// <param name="height"></param>
        /// <param name="sex"></param>
        /// <returns></returns>
        public static double standweight(int height, int sex)
            => (height, sex) switch
            {
                _ when sex == 1 => (height - 80) * 0.7,
                _ => (height - 70) * 0.6
            };


        /// <summary>
        /// 体重标准
        /// </summary>
        /// <param name="weight"></param>
        /// <param name="age"></param>
        /// <param name="sex"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static string weight(double weight, int age, int sex, int height)
         => (weight, age, sex, height) switch
         {
             _ when weight < 18.5 * Math.Pow(height / 100, 2) => NewLevelModel.thin,
             _ when weight >= 18.5 * Math.Pow(height / 100, 2) && weight < 25 * Math.Pow(height / 100, 2) => NewLevelModel.normal,
             _ when weight >= 25 * Math.Pow(height / 100, 2) && weight < 30 * Math.Pow(height / 100, 2) => NewLevelModel.fat,
             _ when weight >= 30 * Math.Pow(height / 100, 2) => NewLevelModel.mfat,
             _ => NewLevelModel.thin
         };

        /// <summary>
        /// bmi标准
        /// </summary>
        /// <param name="bmi"></param>
        /// <param name="weight"></param>
        /// <param name="age"></param>
        /// <param name="sex"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static string bmi(float bmi, double weight, int age, int sex, int height)
          => (weight, age, sex) switch
          {
              _ when bmi < 18.5 => NewLevelModel.thin,
              _ when bmi >= 18.5 && bmi < 25 => NewLevelModel.normal,
              _ when bmi >= 25 && bmi < 30 => NewLevelModel.fat,
              _ when bmi >= 30 => NewLevelModel.mfat,
              _ => NewLevelModel.thin
          };

        /// <summary>
        /// 水份标准
        /// </summary>
        /// <param name="water"></param>
        /// <param name="weight"></param>
        /// <param name="age"></param>
        /// <param name="sex"></param>
        /// <returns></returns>
        public static string water(float water, double weight, int age, int sex)
         => (water, weight, age, sex) switch
         {
             _ when sex == 1 && water < 55 => NewLevelModel.notenu,
             _ when sex == 0 && water < 45 => NewLevelModel.notenu,
             _ when sex == 1 && water < 65 && water >= 55 => NewLevelModel.normal,
             _ when sex == 0 && water < 60 && water >= 45 => NewLevelModel.normal,
             _ when sex == 1 && water >= 65 => NewLevelModel.fine,
             _ when sex == 0 && water >= 60 => NewLevelModel.fine,
             _ => NewLevelModel.notenu
         };


        /// <summary>
        /// 内脂标准
        /// </summary>
        /// <param name="visceral"></param>
        /// <param name="weight"></param>
        /// <param name="age"></param>
        /// <param name="sex"></param>
        /// <returns></returns>

        public static string visceral(float visceral, double weight, int age, int sex)
         => (visceral, weight, age, sex) switch
         {
             _ when visceral < 9 => NewLevelModel.normal,
             _ when visceral < 14 && visceral >= 9 => NewLevelModel.alert,
             _ when visceral >= 14 => NewLevelModel.danger,
             _ => NewLevelModel.normal
         };

        /// <summary>
        /// 蛋白质标准
        /// </summary>
        /// <param name="protein"></param>
        /// <param name="weight"></param>
        /// <param name="age"></param>
        /// <param name="sex"></param>
        /// <returns></returns>

        public static string protein(float protein, double weight, int age, int sex)
          => (protein, weight, age, sex) switch
          {
              _ when sex == 1 && protein < 16 => NewLevelModel.notenu,
              _ when sex == 0 && protein < 14 => NewLevelModel.notenu,
              _ when sex == 1 && protein >= 16 && protein < 18 => NewLevelModel.normal,
              _ when sex == 0 && protein >= 14 && protein < 16 => NewLevelModel.normal,
              _ when sex == 1 && protein >= 18 => NewLevelModel.fine,
              _ when sex == 0 && protein >= 16 => NewLevelModel.fine,
              _ => NewLevelModel.notenu
          };

        /// <summary>
        /// 肌肉率标准
        /// </summary>
        /// <param name="muscle"></param>
        /// <param name="weight"></param>
        /// <param name="age"></param>
        /// <param name="sex"></param>
        /// <returns></returns>
        public static string muscle(float muscle, double weight, int age, int sex)
           => (muscle, weight, age, sex) switch
           {
               _ when sex == 1 && muscle < 40 => NewLevelModel.notenu,
               _ when sex == 0 && muscle < 30 => NewLevelModel.notenu,
               _ when sex == 1 && muscle >= 40 && muscle < 60 => NewLevelModel.normal,
               _ when sex == 0 && muscle >= 30 && muscle < 50 => NewLevelModel.normal,
               _ when sex == 1 && muscle >= 60 => NewLevelModel.fine,
               _ when sex == 0 && muscle >= 50 => NewLevelModel.fine,
               _ => NewLevelModel.notenu
           };

        /// <summary>
        /// 基础代谢计算标准
        /// </summary>
        /// <param name="kcal"></param>
        /// <param name="weight"></param>
        /// <param name="age"></param>
        /// <param name="sex"></param>
        /// <returns></returns>
        public static string kcal(float kcal, double weight, int age, int sex)
            => (kcal, weight, age, sex) switch
            {
                _ when age > 0 && age < 3 && ((kcal < (60.9 * weight - 54) && sex == 1) || (kcal < (61.0 * weight - 51) && sex == 0)) => NewLevelModel.flat,
                _ when age > 0 && age < 3 && ((kcal >= (60.9 * weight - 54) && sex == 1) || (kcal >= (61.0 * weight - 51) && sex == 0)) => NewLevelModel.fine,
                _ when age >= 3 && age < 10 && ((kcal < (22.7 * weight + 495) && sex == 1) || (kcal < (22.5 * weight + 499) && sex == 0)) => NewLevelModel.flat,
                _ when age >= 3 && age < 10 && ((kcal >= (22.7 * weight + 495) && sex == 1) || (kcal >= (22.5 * weight + 499) && sex == 0)) => NewLevelModel.fine,
                _ when age >= 10 && age < 18 && ((kcal < (17.5 * weight + 651) && sex == 1) || (kcal < (12.2 * weight + 746) && sex == 0)) => NewLevelModel.flat,
                _ when age >= 10 && age < 18 && ((kcal >= (17.5 * weight + 651) && sex == 1) || (kcal >= (12.2 * weight + 746) && sex == 0)) => NewLevelModel.fine,
                _ when age >= 18 && age < 30 && ((kcal < (15.3 * weight + 679) && sex == 1) || (kcal < (14.7 * weight + 496) && sex == 0)) => NewLevelModel.flat,
                _ when age >= 18 && age < 30 && ((kcal >= (15.3 * weight + 679) && sex == 1) || (kcal >= (14.7 * weight + 496) && sex == 0)) => NewLevelModel.fine,
                _ when age >= 30 && ((kcal < (11.6 * weight + 879) && sex == 1) || (kcal < (8.7 * weight + 820) && sex == 0)) => NewLevelModel.flat,
                _ when age >= 30 && ((kcal >= (11.6 * weight + 879) && sex == 1) || (kcal >= (8.7 * weight + 820) && sex == 0)) => NewLevelModel.fine,
                _ => NewLevelModel.flat
            };

        /// <summary>
        /// 骨重标准
        /// </summary>
        /// <param name="bone">骨重</param>
        /// <param name="weight"></param>
        /// <param name="sex"></param>
        /// <returns></returns>
        public static string bone(float bone, double weight, int sex)
            => (bone, weight, sex) switch
            {
                _ when sex == 1 && ((weight < 60 && bone < 2.4) || (weight >= 60 && weight < 75 && bone < 2.8) || (weight >= 75 && bone < 3.1)) => NewLevelModel.notenu,
                _ when sex == 0 && ((weight < 45 && bone < 1.7) || (weight >= 45 && weight < 60 && bone < 2.1) || (weight >= 60 && bone < 2.4)) => NewLevelModel.notenu,
                _ when sex == 1 && ((weight < 60 && bone >= 2.4 && bone <= 2.6) || (weight >= 60 && weight < 75 && bone >= 2.8 && bone <= 30) || (weight >= 75 && bone >= 3.1 && bone <= 3.3)) => NewLevelModel.normal,
                _ when sex == 0 && ((weight < 45 && bone >= 1.7 && bone <= 1.9) || (weight >= 45 && weight < 60 && bone <= 2.3 && bone >= 2.1) || (weight >= 60 && bone <= 2.6 && bone >= 2.4)) => NewLevelModel.normal,
                _ when sex == 1 && ((weight < 60 && bone > 2.6) || (weight >= 60 && weight < 75 && bone > 3.0) || (weight >= 75 && bone > 3.3)) => NewLevelModel.fine,
                _ when sex == 0 && ((weight < 45 && bone > 1.9) || (weight >= 45 && weight < 60 && bone > 2.3) || (weight >= 60 && bone > 2.6)) => NewLevelModel.fine,
                _ => NewLevelModel.notenu
            };

        /// <summary>
        /// 体龄计算方法
        /// </summary>
        /// <param name="bodyage"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public static string bodyage(int bodyage, int age)
            => (bodyage, age) switch
            {
                _ when bodyage > age => NewLevelModel.big,
                _ when bodyage == age => NewLevelModel.normal,
                _ => NewLevelModel.fine
            };

        /// <summary>
        /// bmi 计算标准
        /// </summary>
        /// <param name="bmi">BMI</param>
        /// <returns></returns>
        public static string bmi(float bmi)
            => bmi switch
            {
                _ when bmi < 18.5 => NewLevelModel.thin,
                _ when bmi >= 18.5 && bmi < 25 => NewLevelModel.normal,
                _ when bmi >= 25 && bmi < 30 => NewLevelModel.fat,
                _ when bmi >= 30 => NewLevelModel.mfat,
                _ => NewLevelModel.thin
            };

        /// <summary>
        /// 脂肪率标准计算
        /// </summary>
        /// <param name="fat_r">脂肪率</param>
        /// <param name="sex">0-女,1-男</param>
        /// <param name="age">年龄</param>
        /// <returns></returns>
        public static string Fat_r(float fat_r, int sex, int age)
            => (fat_r, sex, age) switch
            {
                _ when sex == 1 && age < 30 && fat_r < 10 => NewLevelModel.flat,
                _ when sex == 1 && age >= 30 && fat_r < 11 => NewLevelModel.flat,
                _ when sex == 0 && age < 30 && fat_r < 20 => NewLevelModel.flat,
                _ when sex == 0 && age >= 30 && fat_r < 21 => NewLevelModel.flat,
                _ when sex == 1 && age < 30 && fat_r >= 10 && fat_r < 21 => NewLevelModel.normal,
                _ when sex == 1 && age >= 30 && fat_r >= 11 && fat_r < 22 => NewLevelModel.normal,
                _ when sex == 0 && age < 30 && fat_r >= 20 && fat_r < 31 => NewLevelModel.normal,
                _ when sex == 0 && age >= 30 && fat_r >= 21 && fat_r < 32 => NewLevelModel.normal,
                _ when sex == 1 && age < 30 && fat_r > 21 && fat_r < 26 => NewLevelModel.high,
                _ when sex == 1 && age >= 30 && fat_r >= 22 && fat_r < 27 => NewLevelModel.high,
                _ when sex == 0 && age < 30 && fat_r >= 31 && fat_r < 38 => NewLevelModel.high,
                _ when sex == 0 && age >= 30 && fat_r >= 32 && fat_r < 39 => NewLevelModel.high,
                _ when sex == 1 && age < 30 && fat_r >= 26 => NewLevelModel.mhigh,
                _ when sex == 1 && age >= 30 && fat_r >= 27 => NewLevelModel.mhigh,
                _ when sex == 0 && age < 30 && fat_r >= 38 => NewLevelModel.mhigh,
                _ when sex == 0 && age >= 30 && fat_r >= 39 => NewLevelModel.mhigh,
                _ => NewLevelModel.flat
            };

        /// <summary>
        /// 新的指标标准
        /// </summary>
        public class NewLevelModel
        {
            /// <summary>
            /// 偏大
            /// </summary>
            public static string big = "偏大";

            /// <summary>
            /// 偏瘦
            /// </summary>
            public static string thin = "偏瘦";
            /// <summary>
            /// 标准
            /// </summary>
            public static string normal = "标准";
            /// <summary>
            /// 偏胖
            /// </summary>
            public static string fat = "偏胖";
            /// <summary>
            /// 肥胖
            /// </summary>
            public static string mfat = "肥胖";
            /// <summary>
            /// 偏重
            /// </summary>
            public static string weight = "偏重";
            /// <summary>
            /// 超重
            /// </summary>
            public static string mweight = "超重";
            /// <summary>
            /// 不足
            /// </summary>
            public static string notenu = "不足";
            /// <summary>
            /// 体重不足
            /// </summary>
            public static string weightnotenu = "体重不足";
            /// <summary>
            /// 偏高
            /// </summary>
            public static string high = "偏高";
            /// <summary>
            /// 高
            /// </summary>
            public static string mhigh = "超高";

            /// <summary>
            /// 警惕
            /// </summary>
            public static string alert = "警惕";
            /// <summary>
            /// 危险
            /// </summary>
            public static string danger = "危险";
            /// <summary>
            /// 偏低
            /// </summary>
            public static string flat = "偏低";
            /// <summary>
            /// 优
            /// </summary>
            public static string fine = "优秀";
            /// <summary>
            /// 隐形肥胖
            /// </summary>
            public static string hidefat = "隐形肥胖";
            /// <summary>
            /// 结实型偏胖
            /// </summary>
            public static string strongfat = "结实型偏胖";
            /// <summary>
            /// 缺乏肌肉型
            /// </summary>
            public static string notenumuscle = "缺乏肌肉型";
            /// <summary>
            /// 标准型
            /// </summary>
            public static string normalfat = "标准型";
            /// <summary>
            /// 标准肌肉型
            /// </summary>
            public static string normalmuscle = "标准肌肉型";
            /// <summary>
            /// 偏瘦肌肉型
            /// </summary>
            public static string thinmuscle = "偏瘦肌肉型";
            /// <summary>
            /// 健美肌肉型
            /// </summary>
            public static string perfetmuscle = "健美肌肉型";
        }

        /// <summary>
        /// 算法返回结果定义
        /// </summary>
        public class BodyfatItem
        {
            /// <summary>
            /// bmi
            /// </summary>
            public string bmi;
            /// <summary>
            /// 骨量
            /// </summary>
            public string bm;
            /// <summary>
            /// 肌肉率
            /// </summary>
            public string rom;
            /// <summary>
            /// 水分
            /// </summary>
            public string moi;
            /// <summary>
            /// 脂肪率
            /// </summary>
            public string bfr;
            /// <summary>
            /// 皮下脂肪率
            /// </summary>
            public string sfr;
            /// <summary>
            /// 骨骼肌率
            /// </summary>
            public string rosm;
            /// <summary>
            /// 蛋白率
            /// </summary>
            public string pp;
            /// <summary>
            /// 内脏脂肪指数
            /// </summary>
            public string uvi;
            /// <summary>
            /// 基础代谢率
            /// </summary>
            public string bmr;
            /// <summary>
            /// 身体年龄
            /// </summary>
            public string physicAge;
            /// <summary>
            /// 体重
            /// </summary>
            public double weight;
            /// <summary>
            /// 身高
            /// </summary>
            public double height;
            /// <summary>
            /// 年龄
            /// </summary>
            public int age;
            /// <summary>
            /// 阻抗
            /// </summary>
            public int adc;
            /// <summary>
            /// 性别,0-女,1-男
            /// </summary>
            public int sex;
        }
        /// <summary>
        /// 计算算法
        /// </summary>
        /// <param name="weight"></param>
        /// <param name="height"></param>
        /// <param name="age"></param>
        /// <param name="adc"></param>
        /// <param name="sex"></param>
        /// <returns></returns>
        public static BodyfatItem GetBodyfatResults(double weight, double height, int age, int adc, int sex)
        {
            BodyfatItem item = new BodyfatItem();
            if ((weight <= 0.0) || ((weight > 220.0) || ((height <= 0.0) || ((height > 270.0) || ((age <= 0) || ((age > 120) || ((adc <= 0) || ((adc > 0x3e8) || ((sex < 0) || (sex > 1))))))))))
            {
                object[] arg = new object[] { weight, height, age, adc, sex };
                Console.WriteLine("[input params invalid] weight:{0} height:{1} age:{2} adc:{3} sex:{4}", arg);
                if (weight != 0 && height != 0)
                    item.bmi = (((double)((int)((weight / (height * height)) * 10.0))) / 10.0).ToString("0.0");
                return item;
            }
            double num = ((double)((int)((weight / (height * height)) * 10.0))) / 10.0;
            double num2 = 0.0;
            double num3 = 0.0;
            double num4 = 0.0;
            double num5 = 0.0;
            double num6 = 0.0;
            double num7 = 0.0;
            double num8 = 0.0;
            double num9 = 0.0;
            double num10 = 0.0;
            double num11 = 0.0;
            if (sex == 1)
            {
                num2 = ((0.015 * weight) + (((2.0 - (0.00055 * adc)) * height) / 100.0)) + 1.15;
                num3 = ((((-((0.00115 * adc) + 0.01) * weight) + (((49.64 - (0.031 * adc)) * height) / 100.0)) + (adc * 0.08)) + (age * 0.04)) + 15.4;
                num4 = (((0xf_4240 / (num * ((2.688 * adc) - 78.28))) - (0x274a / adc)) - (0.22 * age)) + 52.6;
                num5 = ((((-930_000.0 / num) / ((1.966 * adc) - 58.46)) + (0x3378 / adc)) - (0.06 * age)) + 40.0;
                num6 = 0.898 * num5;
                num7 = 0.895 * num4;
                num8 = 0.8 * (((100.0 - num5) - num4) - (num2 / weight));
                num9 = ((((0.304 * weight) + ((25.58 * height) / 100.0)) + (0.131 * age)) + (0.005 * adc)) - 0x16;
                //num10 = (((((9.0 + (0.0015 * adc)) * weight) + (((0x546 - (0.88 * adc)) * height) / 100.0)) + (0xbc / age)) + (0.748 * adc)) - 0x41d;
                num10 = 370 + 21.6 * weight * (1 - num5 / 100);
                num11 = ((((age * (1.0 + (0.012 * (num - 1.0)))) - 0x15) + ((30 - age) * 0.35)) + ((adc - 450) * 0.02)) + 11.0;
            }
            else
            {
                num2 = ((((2.2E-05 * adc) * weight) + (((4.99 - (0.00284 * adc)) * height) / 100.0)) + (0.0012 * adc)) + 1.15;
                num3 = ((((-((0.00115 * adc) + 0.01) * weight) + (((49.64 - (0.031 * adc)) * height) / 100.0)) + (adc * 0.08)) + (age * 0.04)) + 6.0;
                num4 = (((0xf_4240 / (num * ((2.467 * adc) - 75.37))) - (0x3787 / adc)) - (0.034 * age)) + 43.2;
                num5 = ((((-3_030_000.0 / (num + 20.0)) / ((1.966 * adc) - 58.46)) + (0x6e10 / adc)) - (0.06 * age)) + 0x33;
                num6 = (0.876 * num5) + 1.66;
                num7 = (0.857 * num4) - 0.36;
                num8 = 0.75 * (((100.0 - num5) - num4) - (num2 / weight));
                num9 = ((((0.304 * weight) + ((25.58 * height) / 100.0)) + (0.131 * age)) + (0.005 * adc)) - 0x16;
                num10 = 370 + 21.6 * weight * (1 - num5 / 100);
                //num10 = ((((((0.00307 * adc) + 1.5) * weight) + (((0x5b3 - (0.989 * adc)) * height) / 100.0)) + (age * 0.9)) + (0.923 * adc)) - 950.0;
                num11 = (age * (0.95 + (0.02 * (num - 21.2)))) + ((adc - 500) * 0.02);
            }
            item.bmi = num.ToString("0.0");
            num2 = (num2 > (weight * 0.15)) ? (weight * 0.15) : num2;
            item.bm = ((num2 < (weight * 0.02)) ? (weight * 0.02) : num2).ToString("0.0");
            num3 = (num3 > 0x4b) ? 0x4b : num3;
            item.rom = ((num3 < 15.0) ? 15.0 : num3).ToString("0.0");
            num4 = (num4 > 70.0) ? 70.0 : num4;
            item.moi = ((num4 < 20.0) ? 20.0 : num4).ToString("0.0");
            num5 = (num5 > 50.0) ? 50.0 : num5;
            item.bfr = ((num5 < 5.0) ? 5.0 : num5).ToString("0.0");
            item.sfr = num6.ToString("0.0");
            item.rosm = num7.ToString("0.0");
            num8 = (num8 > 50.0) ? 50.0 : num8;
            item.pp = ((num8 < 10.0) ? 10.0 : num8).ToString("0.0");
            num9 = (num9 > 20.0) ? 20.0 : num9;
            item.uvi = ((num9 < 1.0) ? 1.0 : num9).ToString("0");
            item.bmr = num10.ToString("0.0");
            if (age < 0x12)
            {
                num11 = age;
            }
            else
            {
                num11 = (num11 > (age + 10)) ? ((double)(age + 10)) : num11;
                num11 = (num11 < (age - 10)) ? ((double)(age - 10)) : num11;
            }
            item.physicAge = num11.ToString("0");
            item.weight = weight;
            item.height = height;
            item.age = age;
            item.adc = adc;
            item.sex = sex;
            return item;
        }

        /// <summary>
        /// bmi范围标准
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> bmi_value(int sex, int age)
        {
            var list = new List<MeasureInfoItemValue>();
            list.Add(new MeasureInfoItemValue
            {
                maxvalue = 18.5m,
                minvalue = 0
            });
            list.Add(new MeasureInfoItemValue
            {
                maxvalue = 25,
                minvalue = 18.5m
            });
            list.Add(new MeasureInfoItemValue
            {
                maxvalue = 30,
                minvalue = 25
            });
            list.Add(new MeasureInfoItemValue
            {
                maxvalue = 50,
                minvalue = 30
            });
            return list;
        }

        /// <summary>
        /// 脂肪率/体脂率范围标准
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> fa_r_value(int sex, int age)
            => (sex, age) switch
            {
                _ when sex == 1 && age < 30 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=10,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=21,
                        minvalue=10
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=26,
                        minvalue=21
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=50,
                        minvalue=26
                    }
                },
                _ when sex == 1 && age >= 30 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=11,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=22,
                        minvalue=11
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=27,
                        minvalue=22
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=50,
                        minvalue=27
                    }
                },
                _ when sex == 0 && age < 30 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=20,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=31,
                        minvalue=20
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=38,
                        minvalue=31
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=50,
                        minvalue=38
                    }
                },
                _ when sex == 0 && age >= 30 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=21,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=32,
                        minvalue=21
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=39,
                        minvalue=32
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=50,
                        minvalue=39
                    }
                },
                _ => new List<MeasureInfoItemValue>()
            };
        /// <summary>
        /// 肌肉率范围
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> muscle_value(int sex, int age)
            => (sex, age) switch
            {
                _ when sex == 1 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=40,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=60,
                        minvalue=40
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=80,
                        minvalue=60
                    }
                },
                _ when sex == 0 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=30,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=50,
                        minvalue=30
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=80,
                        minvalue=50
                    }
                },
                _ => new List<MeasureInfoItemValue>()
            };
        /// <summary>
        /// 水份范围
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> water_value(int sex, int age)
          => (sex, age) switch
          {
              _ when sex == 1 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=55,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=65,
                        minvalue=55
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=80,
                        minvalue=65
                    }
              },
              _ when sex == 0 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=45,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=60,
                        minvalue=45
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=80,
                        minvalue=60
                    }
              },
              _ => new List<MeasureInfoItemValue>()
          };

        /// <summary>
        /// 骨量范围
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <param name="weight">体重</param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> bone_value(int sex, int age, decimal weight)
          => (sex, age, weight) switch
          {
              _ when sex == 1 && weight < 60 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=2.4m,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=2.6m,
                        minvalue=2.4m
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=5,
                        minvalue=2.6m
                    }
              },
              _ when sex == 1 && weight < 75 && weight >= 60 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=2.8m,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=3.0m,
                        minvalue=2.8m
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=5,
                        minvalue=3.0m
                    }
              },
              _ when sex == 1 && weight >= 75 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=3.1m,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=3.3m,
                        minvalue=3.1m
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=5,
                        minvalue=3.3m
                    }
              },
              _ when sex == 0 && weight < 45 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=1.7m,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=1.9m,
                        minvalue=1.7m
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=5,
                        minvalue=1.9m
                    }
              },
              _ when sex == 0 && weight < 60 && weight >= 45 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=2.1m,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=2.3m,
                        minvalue=2.1m
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=5,
                        minvalue=2.3m
                    }
              },
              _ when sex == 0 && weight >= 60 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        maxvalue=2.4m,
                        minvalue=0
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=2.6m,
                        minvalue=2.4m
                    },
                    new MeasureInfoItemValue
                    {
                        maxvalue=5,
                        minvalue=2.6m
                    }
              },
              _ => new List<MeasureInfoItemValue>()
          };
        /// <summary>
        /// 基础代谢范围
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <param name="weight"></param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> kcal_value(int sex, int age, decimal weight)
            => (sex, age, weight) switch
            {
                _ when sex == 1 && age < 3 && age > 0 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (60.9*weight.ToDouble()-54).ToDecimal(2),
                        maxvalue = (60.9*weight.ToDouble()-54).ToDecimal(2)
                    }
                },
                _ when sex == 1 && age < 10 && age >= 3 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (22.7*weight.ToDouble()+495).ToDecimal(2),
                        maxvalue = (22.7*weight.ToDouble()+495).ToDecimal(2),
                    }
                },
                _ when sex == 1 && age < 18 && age >= 10 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (17.5*weight.ToDouble()+651).ToDecimal(2),
                        maxvalue = (17.5*weight.ToDouble()+651).ToDecimal(2)
                    }
                },
                _ when sex == 1 && age < 30 && age >= 18 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (15.3*weight.ToDouble()+679).ToDecimal(2),
                        maxvalue = (15.3*weight.ToDouble()+679).ToDecimal(2)
                    }
                },
                _ when sex == 1 && age >= 30 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (11.6*weight.ToDouble()+879).ToDecimal(2),
                        maxvalue = (11.6*weight.ToDouble()+879).ToDecimal(2)
                    }
                },
                _ when sex == 0 && age < 3 && age > 0 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (61.0*weight.ToDouble()-51).ToDecimal(2),
                        maxvalue = (61.0*weight.ToDouble()-51).ToDecimal(2)
                    }
                },
                _ when sex == 0 && age < 10 && age >= 3 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (22.5*weight.ToDouble()+499).ToDecimal(2),
                        maxvalue = (22.5*weight.ToDouble()+499).ToDecimal(2),
                    }
                },
                _ when sex == 0 && age < 18 && age >= 10 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (12.2*weight.ToDouble()+746).ToDecimal(2),
                        maxvalue = (12.2*weight.ToDouble()+746).ToDecimal(2)
                    }
                },
                _ when sex == 0 && age < 30 && age >= 18 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (14.7*weight.ToDouble()+496).ToDecimal(2),
                        maxvalue = (14.7*weight.ToDouble()+496).ToDecimal(2)
                    }
                },
                _ when sex == 0 && age >= 30 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue = (8.7*weight.ToDouble()+820).ToDecimal(2),
                        maxvalue = (8.7*weight.ToDouble()+820).ToDecimal(2)
                    }
                },
                _ => new List<MeasureInfoItemValue>()
            };
        /// <summary>
        /// 内脂范围
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> visceral_value(int sex, int age)
            => (sex, age) switch
            {
                _ => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue=0,
                        maxvalue=9
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=9,
                        maxvalue=14
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=14,
                        maxvalue=20
                    }
                }
            };
        /// <summary>
        /// 蛋白质范围
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> protein_value(int sex, int age)
           => (sex, age) switch
           {
               _ when sex == 1 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue=0,
                        maxvalue=16
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=16,
                        maxvalue=18
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=18,
                        maxvalue=25
                    }
               },
               _ when sex == 0 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue=0,
                        maxvalue=14
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=14,
                        maxvalue=16
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=16,
                        maxvalue=25
                    }
               },
               _ => new List<MeasureInfoItemValue>()
           };
        /// <summary>
        /// 皮下脂肪范围
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        /// <returns></returns>
        public static List<MeasureInfoItemValue> sfr_value(int sex, int age)
           => (sex, age) switch
           {
               _ when sex == 1 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue=0,
                        maxvalue=7
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=7,
                        maxvalue=15
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=15,
                        maxvalue=25
                    }
               },
               _ when sex == 0 => new List<MeasureInfoItemValue> {
                    new MeasureInfoItemValue
                    {
                        minvalue=0,
                        maxvalue=11
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=11,
                        maxvalue=17
                    },
                    new MeasureInfoItemValue
                    {
                        minvalue=17,
                        maxvalue=25
                    }
               },
               _ => new List<MeasureInfoItemValue>()
           };
    }
}
