function info = resolve_comsol_e_field(model, coordProbe)
%RESOLVE_COMSOL_E_FIELD  自动探测 COMSOL 模型中可用的 Ex/Ey/Ez 表达式
%
%   info = resolve_comsol_e_field(model)
%   info = resolve_comsol_e_field(model, coordProbe)  % 3×1 或 1×3
%
% 返回 info.tag, info.exExpr, info.eyExpr, info.ezExpr, info.normExpr

if nargin < 2 || isempty(coordProbe)
    coordProbe = [0; 0; 0];
end
coordProbe = coordProbe(:);
if numel(coordProbe) ~= 3
    error('coordProbe 必须是 3 元坐标');
end

physicsTags = listPhysicsTags(model);
if isempty(physicsTags)
    physicsTags = {'emw', 'ewfd', 'emw2', 'ewfd2', 'wfd'};
end

componentNames = {'Ex', 'Ey', 'Ez'; ...
                  'Efieldx', 'Efieldy', 'Efieldz'; ...
                  'Ex_i', 'Ey_i', 'Ez_i'};

failMsgs = strings(0, 1);

for t = 1:numel(physicsTags)
    tag = physicsTags{t};
    for r = 1:size(componentNames, 1)
        ex = sprintf('%s.%s', tag, componentNames{r, 1});
        ey = sprintf('%s.%s', tag, componentNames{r, 2});
        ez = sprintf('%s.%s', tag, componentNames{r, 3});
        [ok, msg] = tryFieldTriplet(model, coordProbe, ex, ey, ez);
        if ok
            info.tag = tag;
            info.exExpr = ex;
            info.eyExpr = ey;
            info.ezExpr = ez;
            info.normExpr = buildNormExpr(ex, ey, ez);
            info.probeCoord = coordProbe;
            fprintf('已识别电场变量: %s / %s / %s\n', ex, ey, ez);
            return;
        end
        failMsgs(end + 1, 1) = string(msg); %#ok<AGROW>
    end
end

% 尝试不依赖 physics tag 的全局变量
globalCandidates = {
    'Ex', 'Ey', 'Ez'
    'E_x', 'E_y', 'E_z'
    };
for r = 1:size(globalCandidates, 1)
    ex = globalCandidates{r, 1};
    ey = globalCandidates{r, 2};
    ez = globalCandidates{r, 3};
    [ok, msg] = tryFieldTriplet(model, coordProbe, ex, ey, ez);
    if ok
        info.tag = '';
        info.exExpr = ex;
        info.eyExpr = ey;
        info.ezExpr = ez;
        info.normExpr = buildNormExpr(ex, ey, ez);
        info.probeCoord = coordProbe;
        fprintf('已识别电场变量: %s / %s / %s\n', ex, ey, ez);
        return;
    end
    failMsgs(end + 1, 1) = string(msg); %#ok<AGROW>
end

fprintf('\n未能自动识别 Ex/Ey/Ez。已尝试的 physics 标签:\n');
disp(physicsTags');
fprintf('\n请在 COMSOL 结果浏览器中查看变量名，然后手动指定，例如:\n');
fprintf('  export_comsol_normE_from_dat(''normExpr'', ''ewfd.Ex*conj(ewfd.Ex)+...'')\n');
fprintf('  export_comsol_normE_from_dat(''exExpr'', ''ewfd.Ex'', ''eyExpr'', ''ewfd.Ey'', ''ezExpr'', ''ewfd.Ez'')\n\n');

error('resolve_comsol_e_field:NotFound', ...
    '无法自动识别电场表达式。请用 probe_comsol_fields 查看可用变量。');
end

function tags = listPhysicsTags(model)
tags = {};
compTags = {'comp1', 'comp2', 'comp3'};
for c = 1:numel(compTags)
    try
        comp = model.java.component(compTags{c});
        pt = comp.physics.tags;
        for i = 1:pt.length
            tags{end + 1} = char(pt(i)); %#ok<AGROW>
        end
    catch
    end
end
tags = unique(tags, 'stable');
end

function [ok, msg] = tryFieldTriplet(model, coordProbe, ex, ey, ez)
ok = false;
msg = '';
try
    vx = mphinterp(model, ex, 'coord', coordProbe);
    vy = mphinterp(model, ey, 'coord', coordProbe);
    vz = mphinterp(model, ez, 'coord', coordProbe);
    if isempty(vx) || isnan(vx) || isnan(vy) || isnan(vz)
        msg = sprintf('%s/%s/%s -> NaN', ex, ey, ez);
        return;
    end
    ok = true;
catch ME
    msg = sprintf('%s/%s/%s -> %s', ex, ey, ez, ME.message);
end
end

function expr = buildNormExpr(ex, ey, ez)
expr = sprintf('sqrt(%s*conj(%s)+%s*conj(%s)+%s*conj(%s))', ...
    ex, ex, ey, ey, ez, ez);
end
