function [fn, zeta, A] = trans_extract_40(THM, ndof, nt, iat, t_string, imiss, ibh, ichannel, varargin)
% trans_extract_40  (stable, mdof_frf_main-first)
% - Prefer mdof_frf_main(THM, ndof, iat, imiss, ...) exactly.
% - If mdof_frf_main is absent, fall back to estimate_modes_halfpower_40 with FRF/Model.
% - Filters varargin so only mdof_frf_main-recognized options are passed to it.

ndof
imiss

% -------- Preferred path: mdof_frf_main --------
if exist('mdof_frf_main','file') == 2
    % Keep only options mdof_frf_main knows about


    % Keep only options mdof_frf_main_SISO knows about
    mdofOpts = {'Plot','Verbose','ForceAreal','EstimateDelay','DelayRange','DelayGrid', ...
                'FitBaseline','UseJitterBoost','JB_Rounds','JB_Starts','JB_FnPct', ...
                'JB_ZetaPct','JB_LineGrid','MinSepPct','ShowProgress','PrimaryChan'};
    v_mdof = filterNameValues(varargin, mdofOpts);
    
    % Map iat strings (if any) to the numeric codes expected by mdof_frf_main_SISO
    % 1=''(transmissibility, multiplicative), 2='acc/force', 3='vel/force', 4='disp/force'
    if ischar(iat) || (isstring(iat) && isscalar(iat))
        key = lower(strtrim(char(iat)));
        switch key
            case {'','trans','transmissibility'}, iat_num = 1;
            case {'acc/force','accelerance'},     iat_num = 2;
            case {'vel/force','mobility'},        iat_num = 3;
            case {'disp/force','receptance'},     iat_num = 4;
            otherwise,                             iat_num = 4; % default to receptance
        end
    else
        iat_num = iat;
    end


     % Call with positional (THM, ndof, iat, imiss).
     % THM may be [f, H1, H2, ...] with complex columns for multiple response locations.    
     % Hhat is the complex FRF evaluated on the THM frequency grid (primary channel)

    fprintf('\n\n @@@ iat=%d \n\n',iat); 

    if(iat==1)
        [fn, zeta, A, Hhat, info] = mdof_trans_main(THM, ndof, iat_num, imiss, ibh, ...
        'PrimaryChan', ichannel, 'Plot', false, 'Verbose', true);
    else
        [fn, zeta, A, Hhat, info] = mdof_frf_main(THM, ndof, iat_num, imiss, ibh, ...
        'PrimaryChan', ichannel, 'Plot', false, 'Verbose', true);
    end

    
    fmin=THM(1,1);
    fmax=THM(end,1);

    tss=sprintf('%s Channel = %d ',t_string,ichannel);

    plot_complex(THM(:,1),Hhat,THM(:,ichannel+1),fmin,fmax,tss);


    A=fix_size(A);
    fn=fix_size(fn);
    zeta=fix_size(zeta);

    nm = min([ndof length(A) length(fn) length(zeta)]);

    A_modes = A(1:nm);
    fn_modes = fn(1:nm);
    zeta_modes = zeta(1:nm);
    
    q = [A_modes(:) fn_modes(:) zeta_modes(:)];
        

    q=sortrows(q,2);

    ndof=length(A);

    q
    ndof

    fprintf('\n\n  A   fn(Hz)   damp \n');
    for i=1:ndof
        fprintf(' %5.3f  %5.1f  %5.3f \n',q(i,1),q(i,2),q(i,3));
    end

    
    return




end

% -------- Fallback path: half-power estimate only --------
[FRF, Model] = frfModelFromIAT(iat);
estArgs = [{'FRF', FRF, 'Model', Model}, varargin];
[fnr, dampr, ~, Ar] = estimate_modes_halfpower_40(THM, ndof, estArgs{:});
end

% ================= helpers =================
function vout = filterNameValues(vin, allowedNames)
% Keep only name-value pairs whose names are in allowedNames (case-insensitive)
vout = {};
if isempty(vin), return; end
if mod(numel(vin),2)~=0, warning('trans_extract_40: Odd varargin length; ignoring trailing value.'); end
N = floor(numel(vin)/2);
al = lower(string(allowedNames));
for k = 1:N
    name = vin{2*k-1};
    if isstring(name) || ischar(name)
        if any(lower(string(name)) == al)
            vout(end+1:end+2) = {vin{2*k-1}, vin{2*k}}; %#ok<AGROW>
        end
    end
end
end

function [FRF, Model] = frfModelFromIAT(iat)
switch iat
    case 1, FRF = '';            Model = 'multiplicative'; % legacy transmissibility
    case 2, FRF = 'acc/force';   Model = 'additive';       % accelerance
    case 3, FRF = 'vel/force';   Model = 'additive';       % mobility
    case 4, FRF = 'disp/force';  Model = 'additive';       % receptance
    otherwise, FRF = '';         Model = 'multiplicative';
end
end
