import fs__default, { promises } from 'node:fs';
import path__default from 'node:path';
import process__default from 'node:process';
import { globby } from 'globby';

function isPathInside(childPath, parentPath) {
	const relation = path__default.relative(parentPath, childPath);

	return Boolean(
		relation &&
		relation !== '..' &&
		!relation.startsWith(`..${path__default.sep}`) &&
		relation !== path__default.resolve(childPath)
	);
}

async function trash(paths, options = {}) {
	paths = [paths].flat().map(String);

	const {glob = true} = options;

	if (glob) {
		// Normalize '/**' patterns to their base directory
		const patterns = paths.map(pattern => {
			const isNegated = pattern.startsWith('!');
			const body = isNegated ? pattern.slice(1) : pattern;
			const normalized = body.endsWith('/**') ? path__default.dirname(body) : body;
			return isNegated ? '!' + normalized : normalized;
		});

		const matches = await globby(patterns, {
			expandDirectories: false,
			onlyFiles: false,
			followSymbolicLinks: false,
		});

		// Include literal paths that exist
		const literals = await Promise.all(paths.map(async p => {
			try {
				await fs__default.promises.lstat(p);
				return p;
			} catch {
				return null;
			}
		}));

		paths = [...new Set([...matches, ...literals.filter(Boolean)])];
	}

	// Filter out nested paths and resolve
	const pathChecks = await Promise.all(paths.map(async filePath => {
		// Skip if nested in another path
		if (paths.some(p => p !== filePath && isPathInside(filePath, p))) {
			return;
		}

		try {
			await fs__default.promises.lstat(filePath);
			return path__default.resolve(filePath);
		} catch (error) {
			// Ignore non-existent paths
			if (error.code !== 'ENOENT') {
				throw error;
			}
		}
	}));

	const resolvedPaths = pathChecks.filter(Boolean);

	if (resolvedPaths.length === 0) {
		return;
	}

	const {default: trashFunction} = await platformSpecificImplementation();
	return trashFunction(resolvedPaths);
}

// We use static imports so it can be statically analyzed.
async function platformSpecificImplementation() {
	switch (process__default.platform) {
		case 'darwin': {
			return import('../chunks/macos.mjs');
		}

		case 'win32': {
			return import('../chunks/windows.mjs');
		}

		case 'linux': {
			const {isWsl} = await import('../chunks/index12.mjs');
			if (isWsl) {
				return import('../chunks/wsl.mjs');
			}

			return import('../chunks/linux.mjs');
		}

		default: {
			return import('../chunks/linux.mjs');
		}
	}
}

async function pathExists(p) {
  try {
    await promises.access(p);
    return true;
  } catch {
    return false;
  }
}
async function moveToTrash(paths) {
  const pathArray = Array.isArray(paths) ? paths : [paths];
  const results = [];
  for (const path of pathArray) {
    try {
      const exists = await pathExists(path);
      if (!exists) {
        results.push({
          success: false,
          path,
          error: "Path does not exist"
        });
        continue;
      }
      await trash(path);
      results.push({
        success: true,
        path
      });
    } catch (error) {
      results.push({
        success: false,
        path,
        error: error.message || "Unknown error occurred"
      });
    }
  }
  return results;
}

export { moveToTrash as m };
