import * as Application from 'expo-application'
import { Platform } from 'react-native'
import type { AccountType } from 'src/state/accountStore'
import data from './branding.json'

/** Public-facing brand strings. Source of truth: src/lib/branding.json */
export const APP = data

/** OAuth client_name sent to servers during app registration */
export const oauthClientName = (platform: string) => `${APP.name} for ${platform}`

/**
 * Display name of the server software for an account, for user-facing copy
 * (Settings → Accounts row pill, Settings active-account row, login error
 * messages). Plan §2.5 — Phase 1 declares the helper; Phase 4 / §9.44 are
 * the primary consumers when the Settings UI surfaces a per-row server-type
 * pill. The function shape (rather than a flat constant) is the point: the
 * Pixelfed string remains the configurable value in `branding.json`, the
 * Mastodon string is hardcoded because there is no Mastodon-fork branching
 * in v1 (plan §1.2 / §6.1).
 */
export function serverSoftwareDisplayName(type: AccountType): string {
  if (type === 'mastodon') return 'Mastodon'
  return APP.serverSoftwareDisplayName
}

/**
 * Lowercase noun for the server software, used in sentence-form copy ("your
 * Pixelfed instance" / "your Mastodon instance"). Plan §8.5 / §9.46 lay out
 * the i18n-deferred unification of these strings; Phase 1 declares the
 * helper so any per-type sentence built today picks the right noun.
 */
export function serverNoun(type: AccountType): string {
  if (type === 'mastodon') return 'Mastodon'
  return APP.serverSoftwareDisplayName
}

// User-Agent string. Plan §2.4 / item 12 — Mastodon clients are expected to
// identify themselves; the format below mirrors the convention used by the
// Mastodon project's own outbound traffic. Computed once per process; the app
// version and platform are immutable for the lifetime of an install.
const PLATFORM_TAG: string = (() => {
  const os = Platform.OS
  if (os === 'ios') return 'iOS'
  if (os === 'android') return 'Android'
  return os.charAt(0).toUpperCase() + os.slice(1)
})()

const USER_AGENT: string = (() => {
  const version = Application.nativeApplicationVersion ?? APP.name
  return `${APP.name}/${version} (${PLATFORM_TAG}; +https://halflig.ht/)`
})()

/**
 * Identifying User-Agent header value. Set on every outbound request from
 * `ApiContext.request` and from the lower-level `requests.ts` primitives.
 * The same value is sent regardless of account type — Pixelfed, Mastodon,
 * and the unauthenticated nodeinfo / OAuth-discovery probes all benefit
 * from a self-identifying client (helps server admins triage bot vs client
 * traffic, and gives upstream maintainers something to grep for).
 */
export function userAgentHeader(): string {
  return USER_AGENT
}

/**
 * Format an instance hostname for inclusion in user-facing limit messages.
 * Strips a leading scheme/path the registry shouldn't have stored but might
 * (defensive — `AccountSummary.instance` is host-only by design), drops the
 * trailing slash, lowercases, and truncates very long hosts so the consent
 * sheet's title doesn't wrap awkwardly. Empty input falls back to a generic
 * "your server" so the caller never has to branch.
 */
export function formatHostForLimitMsg(instance: string | null | undefined): string {
  if (!instance) return 'your server'
  let host = instance.trim()
  if (!host) return 'your server'
  // If a caller accidentally passed a URL, strip the scheme + path.
  host = host.replace(/^[a-z]+:\/\//i, '').replace(/\/.*$/, '')
  host = host.toLowerCase()
  if (!host) return 'your server'
  // Cap at 40 chars so absurdly-long subdomains don't blow up the sheet
  // title. Truncate from the front because the TLD is the meaningful suffix
  // (`mastodon.social` vs `pleroma.example`).
  const MAX = 40
  if (host.length > MAX) host = `…${host.slice(-(MAX - 1))}`
  return host
}
