import fs from 'node:fs';
import path from 'node:path';

export const WINDOWS_MPV_SHORTCUT_NAME = 'SubMiner mpv.lnk';

export interface WindowsMpvShortcutPaths {
  startMenuPath: string;
  desktopPath: string;
}

export interface WindowsShortcutLinkDetails {
  target: string;
  args?: string;
  cwd?: string;
  description?: string;
  icon?: string;
  iconIndex?: number;
}

export interface WindowsMpvShortcutInstallResult {
  ok: boolean;
  status: 'installed' | 'skipped' | 'failed';
  message: string;
}

export function resolveWindowsStartMenuProgramsDir(appDataDir: string): string {
  return path.win32.join(appDataDir, 'Microsoft', 'Windows', 'Start Menu', 'Programs');
}

export function resolveWindowsMpvShortcutPaths(options: {
  appDataDir: string;
  desktopDir: string;
}): WindowsMpvShortcutPaths {
  return {
    startMenuPath: path.win32.join(
      resolveWindowsStartMenuProgramsDir(options.appDataDir),
      WINDOWS_MPV_SHORTCUT_NAME,
    ),
    desktopPath: path.win32.join(options.desktopDir, WINDOWS_MPV_SHORTCUT_NAME),
  };
}

export function detectWindowsMpvShortcuts(
  paths: WindowsMpvShortcutPaths,
  existsSync: (candidate: string) => boolean = fs.existsSync,
): { startMenuInstalled: boolean; desktopInstalled: boolean } {
  return {
    startMenuInstalled: existsSync(paths.startMenuPath),
    desktopInstalled: existsSync(paths.desktopPath),
  };
}

export function buildWindowsMpvShortcutDetails(exePath: string): WindowsShortcutLinkDetails {
  return {
    target: exePath,
    args: '--launch-mpv',
    cwd: path.win32.dirname(exePath),
    description: 'Launch mpv with SubMiner defaults',
    icon: exePath,
    iconIndex: 0,
  };
}

export function applyWindowsMpvShortcuts(options: {
  preferences: { startMenuEnabled: boolean; desktopEnabled: boolean };
  paths: WindowsMpvShortcutPaths;
  exePath: string;
  writeShortcutLink: (
    shortcutPath: string,
    operation: 'create' | 'update' | 'replace',
    details: WindowsShortcutLinkDetails,
  ) => boolean;
  rmSync?: (candidate: string, options: { force: true }) => void;
  mkdirSync?: (candidate: string, options: { recursive: true }) => void;
}): WindowsMpvShortcutInstallResult {
  const rmSync = options.rmSync ?? fs.rmSync;
  const mkdirSync = options.mkdirSync ?? fs.mkdirSync;
  const details = buildWindowsMpvShortcutDetails(options.exePath);
  const failures: string[] = [];

  const ensureShortcut = (shortcutPath: string): void => {
    mkdirSync(path.win32.dirname(shortcutPath), { recursive: true });
    const ok = options.writeShortcutLink(shortcutPath, 'replace', details);
    if (!ok) {
      failures.push(shortcutPath);
    }
  };

  const removeShortcut = (shortcutPath: string): void => {
    rmSync(shortcutPath, { force: true });
  };

  if (options.preferences.startMenuEnabled) ensureShortcut(options.paths.startMenuPath);
  else removeShortcut(options.paths.startMenuPath);

  if (options.preferences.desktopEnabled) ensureShortcut(options.paths.desktopPath);
  else removeShortcut(options.paths.desktopPath);

  if (failures.length > 0) {
    return {
      ok: false,
      status: 'failed',
      message: `Failed to create Windows mpv shortcuts: ${failures.join(', ')}`,
    };
  }

  if (!options.preferences.startMenuEnabled && !options.preferences.desktopEnabled) {
    return {
      ok: true,
      status: 'skipped',
      message: 'Disabled Windows mpv shortcuts.',
    };
  }

  return {
    ok: true,
    status: 'installed',
    message: 'Updated Windows mpv shortcuts.',
  };
}
