import * as plugins from './plugins.js';
import type { CompilerOptions, ScriptTarget, ModuleKind } from 'typescript';
import { compiler, mergeCompilerOptions } from './tsbuild.classes.compiler.js';

export type { CompilerOptions, ScriptTarget, ModuleKind };

export * from './tsbuild.classes.compiler.js';

/**
 * compile am array of absolute file paths
 */
export let compileFileArray = (
  fileStringArrayArg: string[],
  compilerOptionsArg: CompilerOptions = {},
  argvArg?: any
): Promise<any[]> => {
  return compiler(fileStringArrayArg, mergeCompilerOptions(compilerOptionsArg, argvArg), argvArg);
};

/**
 * compile advanced glob configurations
 * @param globStringArrayArg a array of glob strings
 * {
 *     './some/origin/folder/**\/*.ts': './some/destination/folder'
 * }
 */
export let compileGlobStringObject = async (
  globStringObjectArg: Record<string, string>,
  tsOptionsArg: CompilerOptions = {},
  cwdArg: string = process.cwd(),
  argvArg?: any
) => {
  let compiledFiles: any[] = [];
  
  for (const keyArg in globStringObjectArg) {
    // Type safety check for key
    if (keyArg && typeof keyArg === 'string' && globStringObjectArg[keyArg]) {
      console.log(
        `TypeScript assignment: transpile from ${keyArg} to ${globStringObjectArg[keyArg]}`
      );
      
      // Get files matching the glob pattern
      const fileTreeArray = await plugins.smartfile.fs.listFileTree(cwdArg, keyArg);
      
      // Ensure fileTreeArray contains only strings before transforming
      const stringFileTreeArray = Array.isArray(fileTreeArray) 
        ? fileTreeArray.filter((item): item is string => typeof item === 'string')
        : [];
      
      // Transform to absolute paths
      const absoluteFilePathArray = plugins.smartpath.transform.toAbsolute(
        stringFileTreeArray,
        cwdArg
      ) as string[];
      
      // Get destination directory as absolute path
      const destDir: string = plugins.smartpath.transform.toAbsolute(
        globStringObjectArg[keyArg],
        cwdArg
      ) as string;
      
      // Update compiler options with the output directory
      const updatedTsOptions: CompilerOptions = {
        ...tsOptionsArg,
        outDir: destDir,
      };
      
      // Compile the files and correctly concat the results
      // Fixed: removed duplicating compiledFiles in the concat operation
      const newlyCompiledFiles = await compileFileArray(absoluteFilePathArray, updatedTsOptions, argvArg);
      compiledFiles = compiledFiles.concat(newlyCompiledFiles);
    }
  }
  
  return compiledFiles;
};