type InstallManifestOptions = {
  backgroundColor?: string;
  description: string;
  name: string;
  scope?: string;
  shortName?: string;
  startPath: string;
  themeColor: string;
};

type SwapInstallDocumentMetadataOptions = {
  manifestHref: string;
  title: string;
  themeColor?: string;
};

function resolveInstallScope(startPath: string, explicitScope?: string) {
  if (typeof window === 'undefined') {
    return explicitScope ?? '/';
  }

  if (explicitScope) {
    const resolvedScopeUrl = new URL(explicitScope, window.location.origin);
    resolvedScopeUrl.search = '';
    resolvedScopeUrl.hash = '';
    return resolvedScopeUrl.toString();
  }

  const resolvedStartUrl = new URL(startPath, window.location.origin);
  resolvedStartUrl.search = '';
  resolvedStartUrl.hash = '';
  return resolvedStartUrl.toString();
}

function resolveInstallStartUrl(startPath: string) {
  if (typeof window === 'undefined') {
    return startPath;
  }

  return new URL(startPath, window.location.origin).toString();
}

function resolveInstallIconUrl(path: string) {
  if (typeof window === 'undefined') {
    return path;
  }

  return new URL(path, window.location.origin).toString();
}

export function createInstallManifestObjectUrl(options: InstallManifestOptions) {
  if (typeof window === 'undefined') {
    return '';
  }

  const resolvedStartUrl = resolveInstallStartUrl(options.startPath);
  const manifest = {
    id: resolvedStartUrl,
    name: options.name,
    short_name: options.shortName ?? options.name,
    description: options.description,
    theme_color: options.themeColor,
    background_color: options.backgroundColor ?? '#eff5ff',
    display: 'standalone',
    lang: 'ko',
    scope: resolveInstallScope(options.startPath, options.scope),
    start_url: resolvedStartUrl,
    icons: [
      {
        src: resolveInstallIconUrl('/pwa-192x192.svg'),
        sizes: '192x192',
        type: 'image/svg+xml',
      },
      {
        src: resolveInstallIconUrl('/pwa-512x512.svg'),
        sizes: '512x512',
        type: 'image/svg+xml',
        purpose: 'any maskable',
      },
    ],
  };

  return window.URL.createObjectURL(
    new Blob([JSON.stringify(manifest, null, 2)], {
      type: 'application/manifest+json',
    }),
  );
}

export function swapInstallDocumentMetadata(options: SwapInstallDocumentMetadataOptions) {
  if (typeof document === 'undefined') {
    return () => undefined;
  }

  const head = document.head;
  let manifestLink = document.querySelector<HTMLLinkElement>('link[rel="manifest"]');
  const createdManifestLink = !manifestLink;

  if (!manifestLink) {
    manifestLink = document.createElement('link');
    manifestLink.rel = 'manifest';
    head.appendChild(manifestLink);
  }

  const previousManifestHref = manifestLink.href;
  manifestLink.href = options.manifestHref;

  let appleTitleMeta = document.querySelector<HTMLMetaElement>('meta[name="apple-mobile-web-app-title"]');
  const createdAppleTitleMeta = !appleTitleMeta;
  const previousAppleTitle = appleTitleMeta?.content ?? null;

  if (!appleTitleMeta) {
    appleTitleMeta = document.createElement('meta');
    appleTitleMeta.name = 'apple-mobile-web-app-title';
    head.appendChild(appleTitleMeta);
  }

  appleTitleMeta.content = options.title;

  let themeColorMeta = document.querySelector<HTMLMetaElement>('meta[name="theme-color"]');
  const createdThemeColorMeta = !themeColorMeta;
  const previousThemeColor = themeColorMeta?.content ?? null;

  if (options.themeColor && !themeColorMeta) {
    themeColorMeta = document.createElement('meta');
    themeColorMeta.name = 'theme-color';
    head.appendChild(themeColorMeta);
  }

  if (options.themeColor && themeColorMeta) {
    themeColorMeta.content = options.themeColor;
  }

  return () => {
    if (createdManifestLink) {
      manifestLink?.remove();
    } else if (manifestLink) {
      manifestLink.href = previousManifestHref;
    }

    if (createdAppleTitleMeta) {
      appleTitleMeta?.remove();
    } else if (appleTitleMeta) {
      appleTitleMeta.content = previousAppleTitle ?? '';
    }

    if (createdThemeColorMeta) {
      themeColorMeta?.remove();
    } else if (themeColorMeta && options.themeColor) {
      themeColorMeta.content = previousThemeColor ?? '';
    }
  };
}


type BootstrapInstallMetadataResult = {
  manifestObjectUrl: string;
  title: string;
  themeColor: string;
} | null;

type BootstrapInstallMetadataDefinition = {
  description: string;
  scope?: string;
  shortName?: string;
  themeColor: string;
  title: string;
} | null;

const PLAY_APP_INSTALL_METADATA: Record<string, { title: string; themeColor: string }> = {
  'baseball-ticket-bay': { title: 'Baseball Ticket Bay', themeColor: '#1b3f91' },
  'photoprism': { title: 'PhotoPrism', themeColor: '#0f766e' },
  'photo-puzzle': { title: 'Photo Puzzle', themeColor: '#d97706' },
  'the-quest': { title: 'The Quest', themeColor: '#7c3aed' },
  'tetris': { title: 'Tetris', themeColor: '#0f172a' },
  'e-reader': { title: 'E-Reader', themeColor: '#165dff' },
};

function createCurrentRouteInstallManifestObjectUrl(options: {
  title: string;
  themeColor: string;
  scope?: string;
  shortName?: string;
  description: string;
}) {
  if (typeof window === 'undefined') {
    return '';
  }

  const startPath = `${window.location.pathname}${window.location.search}${window.location.hash}`;
  return createInstallManifestObjectUrl({
    startPath,
    scope: options.scope,
    name: options.title,
    shortName: options.shortName,
    description: options.description,
    themeColor: options.themeColor,
  });
}

function resolveBootstrapInstallMetadataDefinition(pathname: string, search: string): BootstrapInstallMetadataDefinition {
  const searchParams = new URLSearchParams(search);

  if (pathname === '/play/apps') {
    const appId = searchParams.get('app')?.trim() ?? '';
    const metadata = PLAY_APP_INSTALL_METADATA[appId];

    if (!metadata) {
      return null;
    }

    return {
      title: metadata.title,
      shortName: metadata.title,
      description: `${metadata.title} 앱을 홈 화면에서 바로 엽니다.`,
      themeColor: metadata.themeColor,
      scope: pathname,
    };
  }

  if (pathname === '/plans/shared-resource') {
    return {
      title: '공유 리소스 관리',
      shortName: '공유 리소스',
      description: '공유 리소스 관리 화면을 홈 화면 앱으로 바로 엽니다.',
      themeColor: '#0f766e',
      scope: pathname,
    };
  }

  if (pathname.startsWith('/chat/share/') || pathname.startsWith('/shares/')) {
    return {
      title: '리소스 공유 채팅방',
      shortName: '공유채팅',
      description: '리소스 공유 채팅방을 홈 화면 앱으로 바로 엽니다.',
      themeColor: '#165dff',
      scope: pathname,
    };
  }

  return null;
}

export function applyBootstrapInstallMetadataForCurrentRoute(): BootstrapInstallMetadataResult {
  if (typeof window === 'undefined') {
    return null;
  }

  const pathname = window.location.pathname;
  const metadata = resolveBootstrapInstallMetadataDefinition(pathname, window.location.search);

  if (!metadata) {
    return null;
  }

  return {
    manifestObjectUrl: createCurrentRouteInstallManifestObjectUrl(metadata),
    title: metadata.title,
    themeColor: metadata.themeColor,
  };
}
