<?php
declare (strict_types = 1);

namespace app\model;

use think\Model;

class MedicalCalculator extends Model
{
    protected $name = 'medical_calculators';
    protected $autoWriteTimestamp = false;

    protected $schema = [
        'id'          => 'int',
        'name'        => 'string',
        'disease_name'=> 'string',
        'formula'     => 'string',
        'instructions'=> 'string',
        'results'     => 'string'
    ];

    protected $json = ['results'];

    public function questions()
    {
        return $this->hasMany(MedicalQuestion::class, 'medical_calculator_id', 'id');
    }

    public function calculateResult(array $inputs)
    {
        $formula = $this->formula;

        // 检查公式中 `=` 的数量
        $equalsCount = substr_count($formula, '=');

        if ($equalsCount > 0) {
            // 分割公式，使用换行符作为分隔符
            $formulas = preg_split('/\r\n|\r|\n/', $formula);
            foreach ($formulas as $f) {
                // 提取等号右边的表达式
                if (strpos($f, '=') !== false) {
                    list($label, $expr) = explode('=', $f);
                    // 检查公式中的变量是否都在输入中
                    preg_match_all('/\b([a-zA-Z_]\w*)\b/', $expr, $matches);
                    $formulaVariables = array_unique($matches[1]);

                    $allVariablesExist = true;
                    foreach ($formulaVariables as $variable) {
                        if (!isset($inputs[$variable])) {
                            $allVariablesExist = false;
                            break;
                        }
                    }

                    if ($allVariablesExist) {
                        $formula = $expr;
                        break;
                    }
                }
            }
        } else {
            // 如果没有等号，直接使用整个公式
            preg_match_all('/\b([a-zA-Z_]\w*)\b/', $formula, $matches);
            $formulaVariables = array_unique($matches[1]);
        }

        // 将百分比转换为小数
        $formula = str_replace('%', '/100', $formula);

        foreach ($formulaVariables as $variable) {
            if (!isset($inputs[$variable])) {
                throw new \Exception("缺少变量: {$variable}");
            }
            if (!is_numeric($inputs[$variable])) {
                throw new \Exception("变量不是数字: {$variable}");
            }
            // 使用正则表达式确保只替换完整的变量名，并用括号包裹数值避免运算优先级问题
            $formula = preg_replace('/\b' . preg_quote($variable, '/') . '\b/', 
                '(' . floatval($inputs[$variable]) . ')', 
                $formula
            );
        }

        // 输出替换后的公式以便调试
        trace('Processed formula: ' . $formula);

        try {
            // 计算结果
            $result = eval('return ' . $formula . ';');
            if ($result === false || !is_numeric($result)) {
                throw new \Exception("计算公式错误");
            }
            return floatval($result);
        } catch (\ParseError $e) {
            throw new \Exception("计算公式语法错误: " . $e->getMessage());
        }
    }

    public function getResultInterpretation($value)
    {
        $results = $this->results;
        if (!is_array($results)) {
            return null;
        }

        foreach ($results as $result) {
            if (isset($result['min']) && isset($result['max'])) {
                if ($value >= $result['min'] && $value <= $result['max']) {
                    return $result;
                }
            }
        }

        return null;
    }
}