import { shell } from 'electron'
import { existsSync, statSync } from 'fs'
import { extname, isAbsolute } from 'path'

/**
 * Open/reveal helpers used by the shell:* IPC handlers.
 *
 * The renderer supplies the path (it originates from yt-dlp's after-move print),
 * but the IPC boundary must not trust it blindly: a compromised renderer could
 * otherwise call openPath() on an arbitrary executable and have the OS run it.
 * So openPath is confined to existing files with a known media extension —
 * never .exe/.bat/.ps1/etc.
 */
const OPENABLE_EXTENSIONS = new Set([
  // video
  '.mp4',
  '.mkv',
  '.webm',
  '.mov',
  '.avi',
  '.flv',
  '.ts',
  '.m4v',
  '.3gp',
  '.ogv',
  // audio
  '.mp3',
  '.m4a',
  '.opus',
  '.ogg',
  '.oga',
  '.aac',
  '.flac',
  '.wav',
  '.wma',
  // subtitle sidecars (plain text — safe to open)
  '.vtt',
  '.srt'
])

/** Open a downloaded media file with its default app. Returns '' on success,
 *  or an error string (matching shell.openPath's contract). */
export async function safeOpenPath(p: unknown): Promise<string> {
  if (typeof p !== 'string' || !isAbsolute(p)) return 'Invalid path.'
  if (!OPENABLE_EXTENSIONS.has(extname(p).toLowerCase())) {
    return 'Refusing to open this file type.'
  }
  try {
    if (!statSync(p).isFile()) return 'Not a file.'
  } catch {
    return 'File not found.'
  }
  return shell.openPath(p)
}

/** Reveal a path in the OS file manager. Returns '' on success, or an error
 *  string (mirroring safeOpenPath) so the renderer can surface it (UX6). */
export function safeShowInFolder(p: unknown): string {
  if (typeof p !== 'string' || !isAbsolute(p)) return 'Invalid path.'
  if (!existsSync(p)) return 'File not found — it may have been moved or deleted.'
  shell.showItemInFolder(p)
  return ''
}
