// GCG export delivery: share on mobile (Web Share API with a file) where supported,
// otherwise download via a Blob + <a download> on desktop. The Capacitor-native file
// save lands with the native wrapper; the Web Share path already covers mobile
// browsers. pickGcgDelivery is the pure decision, unit-tested with a mock navigator.

import type { GcgExport } from './model';

type ShareNav = Pick<Navigator, 'canShare' | 'share'>;

/** pickGcgDelivery decides between the Web Share API and a Blob download for a file. */
export function pickGcgDelivery(nav: ShareNav | undefined, file: File): 'share' | 'download' {
  if (
    nav &&
    typeof nav.canShare === 'function' &&
    typeof nav.share === 'function' &&
    nav.canShare({ files: [file] })
  ) {
    return 'share';
  }
  return 'download';
}

/** shareOrDownloadGcg shares the GCG file where supported, else triggers a download. */
export async function shareOrDownloadGcg(gcg: GcgExport): Promise<void> {
  const file = new File([gcg.content], gcg.filename, { type: 'application/x-gcg' });
  const nav = typeof navigator !== 'undefined' ? navigator : undefined;
  if (pickGcgDelivery(nav, file) === 'share' && nav) {
    // Web Share is available (mobile, including the iOS Telegram Mini App): use it and stop here
    // whatever the outcome. Do NOT fall back to the Blob download — on iOS WKWebView an
    // <a download> navigates the webview to the blob: URL, replacing the SPA with the raw file
    // and stranding the app, so a cancelled or failed share must simply do nothing (the user can
    // retry). The download path is only for desktop browsers without Web Share.
    try {
      await nav.share({ files: [file], title: gcg.filename });
    } catch {
      /* cancelled or failed — intentionally a no-op (see above) */
    }
    return;
  }
  downloadFile(gcg.content, gcg.filename);
}

function downloadFile(content: string, filename: string): void {
  if (typeof document === 'undefined') return;
  const url = URL.createObjectURL(new Blob([content], { type: 'application/x-gcg' }));
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  a.remove();
  URL.revokeObjectURL(url);
}

type TextShareNav = Pick<Navigator, 'share'> & { canShare?: Navigator['canShare'] };

/**
 * pickTextShare decides how to deliver a plain-text payload: through the OS share sheet (Web Share,
 * available on mobile including the Telegram Mini App) or, on a desktop browser without it, a
 * clipboard copy. Pure, so it is unit-tested with a mock navigator.
 */
export function pickTextShare(nav: TextShareNav | undefined): 'share' | 'copy' {
  if (nav && typeof nav.share === 'function' && (typeof nav.canShare !== 'function' || nav.canShare({ text: 'x' }))) {
    return 'share';
  }
  return 'copy';
}

/**
 * shareText delivers text through the OS share sheet where supported, else copies it to the
 * clipboard. It reports the path taken — 'shared', 'copied', or 'failed' (a cancelled share or an
 * unavailable clipboard) — so the caller can confirm a silent copy to the user. Like
 * shareOrDownloadGcg it never strands the webview: a cancelled share simply does nothing.
 */
export async function shareText(text: string, title: string): Promise<'shared' | 'copied' | 'failed'> {
  const nav = typeof navigator !== 'undefined' ? navigator : undefined;
  if (!nav) return 'failed';
  if (pickTextShare(nav) === 'share') {
    try {
      await nav.share({ title, text });
      return 'shared';
    } catch {
      return 'failed';
    }
  }
  try {
    await nav.clipboard.writeText(text);
    return 'copied';
  } catch {
    return 'failed';
  }
}
