import {type FontVariant, type TextStyle} from 'react-native'

import {IS_ANDROID, IS_WEB} from '#/env'
import {type Device, device} from '#/storage'

const WEB_FONT_FAMILIES = `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"`

/*
 * DEBUG: Uncomment to test if fonts are actually being applied on Android.
 * This will use a distinctive cursive font. Revert when done testing.
 */
// const DEBUG_FONT_OVERRIDE = 'cursive'
const DEBUG_FONT_OVERRIDE = undefined

/*
 * Google Sans Flex optical size mapping.
 * Picks the correct optical size based on fontSize.
 */
function getGoogleSansFlex(weight: number, fontSize?: number): string {
  const opticalSize = fontSize
    ? fontSize < 14
      ? '9pt'
      : fontSize < 28
        ? '24pt'
        : fontSize < 48
          ? '36pt'
          : fontSize < 96
            ? '72pt'
            : '120pt'
    : '24pt' // default to 24pt if no fontSize provided

  const weightName =
    {
      100: 'Thin',
      200: 'ExtraLight',
      300: 'Light',
      400: 'Regular',
      500: 'Medium',
      600: 'SemiBold',
      700: 'Bold',
      800: 'ExtraBold',
      900: 'Black',
    }[weight] || 'Regular'

  const name = `GoogleSansFlex_${opticalSize}-${weightName}`
  return name
}

const factor = 0.0625 // 1 - (15/16)
const fontScaleMultipliers: Record<Device['fontScale'], number> = {
  '-2': 1 - factor * 1, // unused
  '-1': 1 - factor * 1,
  '0': 1, // default
  '1': 1 + factor * 1,
  '2': 1 + factor * 1, // unused
}

export function computeFontScaleMultiplier(scale: Device['fontScale']) {
  return fontScaleMultipliers[scale]
}

export function getFontScale() {
  return device.get(['fontScale']) ?? '0'
}

export function setFontScale(fontScale: Device['fontScale']) {
  device.set(['fontScale'], fontScale)
}

export function getFontFamily() {
  return device.get(['fontFamily']) || 'theme'
}

export function setFontFamily(fontFamily: Device['fontFamily']) {
  device.set(['fontFamily'], fontFamily)
}

/*
 * Unused fonts are commented out, but the files are there if we need them.
 */
export function applyFonts(
  style: TextStyle,
  fontFamily: 'material' | 'system' | 'theme',
) {
  if (IS_ANDROID && fontFamily === 'material') {
    const weight = Number(style.fontWeight || 400)
    style.fontFamily = getGoogleSansFlex(weight, style.fontSize)
  } else if (fontFamily === 'theme') {
    if (IS_ANDROID) {
      style.fontFamily =
        {
          400: 'Inter-Regular',
          500: 'Inter-Medium',
          600: 'Inter-SemiBold',
          700: 'Inter-Bold',
          800: 'Inter-Bold',
          900: 'Inter-Bold',
        }[String(style.fontWeight || '400')] || 'Inter-Regular'

      if (style.fontStyle === 'italic') {
        if (style.fontFamily === 'Inter-Regular') {
          style.fontFamily = 'Inter-Italic'
        } else {
          style.fontFamily += 'Italic'
        }
      }

      /*
       * These are not supported on Android and actually break the styling.
       */
      delete style.fontWeight
      delete style.fontStyle
    } else {
      style.fontFamily = 'InterVariable'

      if (style.fontStyle === 'italic') {
        style.fontFamily += 'Italic'
      }
    }

    if (IS_WEB) {
      // fallback families only supported on web
      style.fontFamily += `, ${WEB_FONT_FAMILIES}`
    }

    /**
     * Disable contextual alternates and emoji overrides in Inter
     * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant}
     */
    if (IS_WEB) {
      style.fontVariant = (style.fontVariant || []).concat(
        'no-contextual',
        'unicode' as FontVariant, // web supports 'unicode' as a valid value for fontVariant
      )
    } else {
      style.fontVariant = (style.fontVariant || []).concat('no-contextual')
    }
  } else {
    // DEBUG: Use cursive font for testing by uncommenting DEBUG_FONT_OVERRIDE
    if (DEBUG_FONT_OVERRIDE) {
      style.fontFamily = DEBUG_FONT_OVERRIDE
    } else {
      // fallback families only supported on web
      if (IS_WEB) {
        style.fontFamily = style.fontFamily || WEB_FONT_FAMILIES
      }
    }
    /**
     * Overridden to previous spacing for the `system` font option.
     * https://github.com/bluesky-social/social-app/commit/2419096e2409008b7d71fd6b8f8d0dd5b016e267
     */
    style.letterSpacing = 0.25
  }
}

/**
 * Here only for bundling purposes, not actually used.
 */
export {DO_NOT_USE} from '#/alf/util/unusedUseFonts'
