import { unzipSync } from 'fflate';
import { parse as parseTOML } from 'smol-toml';

/** Metadata extracted from a webxdc `.xdc` ZIP archive. */
export interface WebxdcMeta {
  /** App name from manifest.toml, or undefined if missing. */
  name?: string;
  /** Icon as a File ready for upload, or undefined if missing. */
  iconFile?: File;
}

/**
 * Extract the name and icon from a `.xdc` (ZIP) file.
 *
 * - Reads `manifest.toml` for the `name` field.
 * - Reads `icon.png` or `icon.jpg` and returns it as a `File`.
 */
export async function extractWebxdcMeta(file: File): Promise<WebxdcMeta> {
  const buf = await file.arrayBuffer();
  const unzipped = unzipSync(new Uint8Array(buf));

  const meta: WebxdcMeta = {};

  // --- Parse manifest.toml for the name ---
  const manifestBytes = unzipped['manifest.toml'];
  if (manifestBytes) {
    const text = new TextDecoder().decode(manifestBytes);
    try {
      const manifest = parseTOML(text);
      if (typeof manifest.name === 'string') {
        meta.name = manifest.name;
      }
    } catch {
      // Silently ignore malformed TOML
    }
  }

  // --- Extract icon (prefer png, fall back to jpg) ---
  const iconPng = unzipped['icon.png'];
  const iconJpg = unzipped['icon.jpg'];
  const iconBytes = iconPng ?? iconJpg;

  if (iconBytes && iconBytes.length > 0) {
    const isPng = !!iconPng;
    const mime = isPng ? 'image/png' : 'image/jpeg';
    const ext = isPng ? '.png' : '.jpg';
    meta.iconFile = new File([iconBytes], `icon${ext}`, { type: mime });
  }

  return meta;
}
