function export_ab_matrix(solver, outDir)
%EXPORT_AB_MATRIX  Export assembled A and B (COO) for 3D eigen FEM.
%
%   export_ab_matrix(solver)
%   export_ab_matrix(solver, outDir)
%
% Compatible with OpticsFEM3D FemType=5 Test_OutputMatrix format:
%   Ai.txt, Aj.txt, Av.txt, Bi.txt, Bj.txt, Bv.txt
% Row/column indices are 0-based (MATLAB edge IDs minus 1).
% One value per line; real matrices use Av.txt / Bv.txt.

if nargin < 2 || isempty(outDir)
    outDir = fullfile(fileparts(mfilename('fullpath')), 'OutFile');
end
if ~exist(outDir, 'dir')
    mkdir(outDir);
end

required = {'Ai','Aj','Av','Bi','Bj','Bv'};
for k = 1:numel(required)
    if ~isfield(solver, required{k})
        error('export_ab_matrix:MissingField', ...
            'solver.%s is missing. Run assembly_equ first.', required{k});
    end
end

Ai = solver.Ai(:) - 1;
Aj = solver.Aj(:) - 1;
Av = complex(solver.Av(:));
Bi = solver.Bi(:) - 1;
Bj = solver.Bj(:) - 1;
Bv = complex(solver.Bv(:));

isReal = all(abs(imag(Av)) < 1e-15) && all(abs(imag(Bv)) < 1e-15);

fidAi = fopen(fullfile(outDir, 'Ai.txt'), 'w');
fidAj = fopen(fullfile(outDir, 'Aj.txt'), 'w');
fidBi = fopen(fullfile(outDir, 'Bi.txt'), 'w');
fidBj = fopen(fullfile(outDir, 'Bj.txt'), 'w');

if isReal
    fidAv = fopen(fullfile(outDir, 'Av.txt'), 'w');
    fidBv = fopen(fullfile(outDir, 'Bv.txt'), 'w');
    cleanup = onCleanup(@() closeOpenFiles({fidAi, fidAj, fidAv, fidBi, fidBj, fidBv}));

    fprintf(fidAi, '%d\n', Ai);
    fprintf(fidAj, '%d\n', Aj);
    fprintf(fidAv, '%.12g\n', real(Av));
    fprintf(fidBi, '%d\n', Bi);
    fprintf(fidBj, '%d\n', Bj);
    fprintf(fidBv, '%.12g\n', real(Bv));
else
    fidAvR = fopen(fullfile(outDir, 'Av_real.txt'), 'w');
    fidAvI = fopen(fullfile(outDir, 'Av_imag.txt'), 'w');
    fidBvR = fopen(fullfile(outDir, 'Bv_real.txt'), 'w');
    fidBvI = fopen(fullfile(outDir, 'Bv_imag.txt'), 'w');
    cleanup = onCleanup(@() closeOpenFiles( ...
        {fidAi, fidAj, fidAvR, fidAvI, fidBi, fidBj, fidBvR, fidBvI}));

    fprintf(fidAi, '%d\n', Ai);
    fprintf(fidAj, '%d\n', Aj);
    fprintf(fidAvR, '%.12g\n', real(Av));
    fprintf(fidAvI, '%.12g\n', imag(Av));
    fprintf(fidBi, '%d\n', Bi);
    fprintf(fidBj, '%d\n', Bj);
    fprintf(fidBvR, '%.12g\n', real(Bv));
    fprintf(fidBvI, '%.12g\n', imag(Bv));
end

fprintf('Exported A/B to %s\n', outDir);
fprintf('  nnz(A)=%d, nnz(B)=%d, 0-based COO\n', numel(Ai), numel(Bi));
if isReal
    fprintf('  format: Av.txt, Bv.txt (real)\n');
else
    fprintf('  format: Av_real/imag, Bv_real/imag\n');
end
end

function closeOpenFiles(fids)
for k = 1:numel(fids)
    if fids{k} > 0
        fclose(fids{k});
    end
end
end
