import { afterEach, describe, expect, it, vi } from 'vitest';
import { isIosSafari, isStandalone, resolveInstallMode } from './pwa';

describe('resolveInstallMode', () => {
  const base = { deferredAvailable: false, standalone: false, iosSafari: false, inMiniApp: false };

  it('hides inside a Mini App even with a captured prompt', () => {
    expect(resolveInstallMode({ ...base, inMiniApp: true, deferredAvailable: true })).toBe('hidden');
  });

  it('hides once the app is installed (standalone)', () => {
    expect(resolveInstallMode({ ...base, standalone: true, deferredAvailable: true })).toBe('hidden');
  });

  it('offers one-tap when a Chromium prompt was captured', () => {
    expect(resolveInstallMode({ ...base, deferredAvailable: true })).toBe('oneTap');
  });

  it('offers iOS instructions on iOS Safari without a prompt', () => {
    expect(resolveInstallMode({ ...base, iosSafari: true })).toBe('iosInstructions');
  });

  it('prefers one-tap over iOS instructions when both apply', () => {
    expect(resolveInstallMode({ ...base, deferredAvailable: true, iosSafari: true })).toBe('oneTap');
  });

  it('hides on an unsupported browser (no prompt, not iOS)', () => {
    expect(resolveInstallMode(base)).toBe('hidden');
  });
});

describe('isStandalone', () => {
  afterEach(() => vi.unstubAllGlobals());

  it('is true when the display-mode media query matches', () => {
    vi.stubGlobal('window', {
      matchMedia: (q: string) => ({ matches: q.includes('standalone') }),
      navigator: {},
    });
    expect(isStandalone()).toBe(true);
  });

  it('is true for the iOS navigator.standalone flag', () => {
    vi.stubGlobal('window', {
      matchMedia: () => ({ matches: false }),
      navigator: { standalone: true },
    });
    expect(isStandalone()).toBe(true);
  });

  it('is false in an ordinary browser tab', () => {
    vi.stubGlobal('window', {
      matchMedia: () => ({ matches: false }),
      navigator: { standalone: false },
    });
    expect(isStandalone()).toBe(false);
  });
});

describe('isIosSafari', () => {
  afterEach(() => vi.unstubAllGlobals());

  const IPHONE_SAFARI =
    'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1';
  const IPHONE_CHROME =
    'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/120.0 Mobile/15E148 Safari/604.1';
  const ANDROID_CHROME =
    'Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Mobile Safari/537.36';
  const IPAD_SAFARI =
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15';

  it('is true for Safari on iPhone', () => {
    vi.stubGlobal('navigator', { userAgent: IPHONE_SAFARI, maxTouchPoints: 5 });
    expect(isIosSafari()).toBe(true);
  });

  it('is true for Safari on iPadOS (Mac UA + touch points)', () => {
    vi.stubGlobal('navigator', { userAgent: IPAD_SAFARI, maxTouchPoints: 5 });
    expect(isIosSafari()).toBe(true);
  });

  it('is false for a desktop Mac (no touch points)', () => {
    vi.stubGlobal('navigator', { userAgent: IPAD_SAFARI, maxTouchPoints: 0 });
    expect(isIosSafari()).toBe(false);
  });

  it('is false for Chrome on iOS (CriOS)', () => {
    vi.stubGlobal('navigator', { userAgent: IPHONE_CHROME, maxTouchPoints: 5 });
    expect(isIosSafari()).toBe(false);
  });

  it('is false for Android Chrome', () => {
    vi.stubGlobal('navigator', { userAgent: ANDROID_CHROME, maxTouchPoints: 5 });
    expect(isIosSafari()).toBe(false);
  });
});
