/**
 * @module utils/zip
 * @description Utilities for working with zip files
 */

import AdmZip from "adm-zip";
import fs from "fs";
import path from "path";
import { createLogger } from "./logger.js";

const logger = createLogger("zip");

/**
 * Extracts a zip file to a specified directory
 *
 * @param zipBuffer - The zip file as a buffer
 * @param targetDir - The directory to extract to
 * @param stripFirstDir - Whether to strip the first directory level from the zip
 *
 * @example
 * ```typescript
 * // Extract a zip file
 * const zipData = await downloadFile('https://example.com/file.zip');
 * extractZip(Buffer.from(zipData), './target-dir');
 *
 * // Extract a zip file and strip the first directory level
 * extractZip(Buffer.from(zipData), './target-dir', true);
 * ```
 *
 * @throws Will throw an error if the extraction fails
 */
export function extractZip(
  zipBuffer: Buffer,
  targetDir: string,
  stripFirstDir = false
): void {
  try {
    logger.info(`Extracting zip to ${targetDir}`);
    const zip = new AdmZip(zipBuffer);

    // Create target directory if it doesn't exist
    if (!fs.existsSync(targetDir)) {
      fs.mkdirSync(targetDir, { recursive: true });
    }

    if (stripFirstDir) {
      // Get zip entries and filter out directories
      const entries = zip.getEntries().filter((entry) => !entry.isDirectory);

      // Get the first directory name to strip
      const firstDirName =
        entries.length > 0 ? entries[0].entryName.split("/")[0] + "/" : null;

      if (firstDirName) {
        logger.info(`Stripping first directory: ${firstDirName}`);

        for (const entry of entries) {
          if (entry.entryName.startsWith(firstDirName)) {
            const newEntryName = entry.entryName.substring(firstDirName.length);
            if (newEntryName.length > 0) {
              const filePath = path.join(targetDir, newEntryName);
              const fileDir = path.dirname(filePath);

              // Create directory structure if it doesn't exist
              if (!fs.existsSync(fileDir)) {
                fs.mkdirSync(fileDir, { recursive: true });
              }

              fs.writeFileSync(filePath, entry.getData());
            }
          }
        }
      } else {
        logger.warn("No first directory found to strip, extracting as-is");
        zip.extractAllTo(targetDir, true);
      }
    } else {
      // Extract without stripping
      zip.extractAllTo(targetDir, true);
    }

    logger.success(`Extraction complete to ${targetDir}`);
  } catch (error) {
    logger.error(`Extraction failed: ${(error as Error).message}`);
    throw error;
  }
}
