export type KeyboardMode = 'lower' | 'upper' | 'special' | 'number'

export type KeyboardAction =
  | 'input'
  | 'backspace'
  | 'enter'
  | 'space'
  | 'left'
  | 'right'
  | 'switch-mode'
  | 'close'
  | 'ok'

export type KeyboardKey = {
  id: string
  label: string
  action: KeyboardAction
  width: number
  value?: string
  nextMode?: KeyboardMode
  popupLabel?: string
  symbol?: string
  actionStyle?: boolean
}

const inputKey = (
  mode: KeyboardMode,
  id: string,
  label: string,
  width = 1,
  value = label,
  extra: Partial<KeyboardKey> = {}
): KeyboardKey => ({
  id: `${mode}-${id}`,
  label,
  action: 'input',
  width,
  value,
  ...extra
})

const actionKey = (
  mode: KeyboardMode,
  id: string,
  label: string,
  action: KeyboardAction,
  width: number,
  extra: Partial<KeyboardKey> = {}
): KeyboardKey => ({
  id: `${mode}-${id}`,
  label,
  action,
  width,
  ...extra
})

const ICON_SYMBOLS = {
  backspace: 'LV_SYMBOL_BACKSPACE',
  enter: 'LV_SYMBOL_NEW_LINE',
  close: 'LV_SYMBOL_KEYBOARD',
  left: 'LV_SYMBOL_LEFT',
  right: 'LV_SYMBOL_RIGHT',
  ok: 'LV_SYMBOL_OK'
} as const

const footerRow = (mode: KeyboardMode): KeyboardKey[] => [
  actionKey(mode, 'close', '', 'close', 2, { symbol: ICON_SYMBOLS.close }),
  actionKey(mode, 'left', '', 'left', 2, { symbol: ICON_SYMBOLS.left }),
  actionKey(mode, 'space', '', 'space', 6, { value: ' ', popupLabel: 'Space' }),
  actionKey(mode, 'right', '', 'right', 2, { symbol: ICON_SYMBOLS.right }),
  actionKey(mode, 'ok', '', 'ok', 2, { symbol: ICON_SYMBOLS.ok })
]

export const KEYBOARD_LAYOUTS: Record<KeyboardMode, KeyboardKey[][]> = {
  lower: [
    [
      actionKey('lower', 'to-special', '1#', 'switch-mode', 2, { nextMode: 'special' }),
      inputKey('lower', 'q', 'q'),
      inputKey('lower', 'w', 'w'),
      inputKey('lower', 'e', 'e'),
      inputKey('lower', 'r', 'r'),
      inputKey('lower', 't', 't'),
      inputKey('lower', 'y', 'y'),
      inputKey('lower', 'u', 'u'),
      inputKey('lower', 'i', 'i'),
      inputKey('lower', 'o', 'o'),
      inputKey('lower', 'p', 'p'),
      actionKey('lower', 'backspace', '', 'backspace', 3, { symbol: ICON_SYMBOLS.backspace })
    ],
    [
      actionKey('lower', 'to-upper', 'ABC', 'switch-mode', 3, { nextMode: 'upper' }),
      inputKey('lower', 'a', 'a'),
      inputKey('lower', 's', 's'),
      inputKey('lower', 'd', 'd'),
      inputKey('lower', 'f', 'f'),
      inputKey('lower', 'g', 'g'),
      inputKey('lower', 'h', 'h'),
      inputKey('lower', 'j', 'j'),
      inputKey('lower', 'k', 'k'),
      inputKey('lower', 'l', 'l'),
      actionKey('lower', 'enter', '', 'enter', 3, { symbol: ICON_SYMBOLS.enter })
    ],
    [
      inputKey('lower', 'underscore', '_', 1, '_', { actionStyle: true }),
      inputKey('lower', 'minus', '-', 1, '-', { actionStyle: true }),
      inputKey('lower', 'z', 'z'),
      inputKey('lower', 'x', 'x'),
      inputKey('lower', 'c', 'c'),
      inputKey('lower', 'v', 'v'),
      inputKey('lower', 'b', 'b'),
      inputKey('lower', 'n', 'n'),
      inputKey('lower', 'm', 'm'),
      inputKey('lower', 'dot', '.', 1, '.', { actionStyle: true }),
      inputKey('lower', 'comma', ',', 1, ',', { actionStyle: true }),
      inputKey('lower', 'colon', ':', 1, ':', { actionStyle: true })
    ],
    footerRow('lower')
  ],
  upper: [
    [
      actionKey('upper', 'to-special', '1#', 'switch-mode', 2, { nextMode: 'special' }),
      inputKey('upper', 'q', 'Q'),
      inputKey('upper', 'w', 'W'),
      inputKey('upper', 'e', 'E'),
      inputKey('upper', 'r', 'R'),
      inputKey('upper', 't', 'T'),
      inputKey('upper', 'y', 'Y'),
      inputKey('upper', 'u', 'U'),
      inputKey('upper', 'i', 'I'),
      inputKey('upper', 'o', 'O'),
      inputKey('upper', 'p', 'P'),
      actionKey('upper', 'backspace', '', 'backspace', 3, { symbol: ICON_SYMBOLS.backspace })
    ],
    [
      actionKey('upper', 'to-lower', 'abc', 'switch-mode', 3, { nextMode: 'lower' }),
      inputKey('upper', 'a', 'A'),
      inputKey('upper', 's', 'S'),
      inputKey('upper', 'd', 'D'),
      inputKey('upper', 'f', 'F'),
      inputKey('upper', 'g', 'G'),
      inputKey('upper', 'h', 'H'),
      inputKey('upper', 'j', 'J'),
      inputKey('upper', 'k', 'K'),
      inputKey('upper', 'l', 'L'),
      actionKey('upper', 'enter', '', 'enter', 3, { symbol: ICON_SYMBOLS.enter })
    ],
    [
      inputKey('upper', 'underscore', '_', 1, '_', { actionStyle: true }),
      inputKey('upper', 'minus', '-', 1, '-', { actionStyle: true }),
      inputKey('upper', 'z', 'Z'),
      inputKey('upper', 'x', 'X'),
      inputKey('upper', 'c', 'C'),
      inputKey('upper', 'v', 'V'),
      inputKey('upper', 'b', 'B'),
      inputKey('upper', 'n', 'N'),
      inputKey('upper', 'm', 'M'),
      inputKey('upper', 'dot', '.', 1, '.', { actionStyle: true }),
      inputKey('upper', 'comma', ',', 1, ',', { actionStyle: true }),
      inputKey('upper', 'colon', ':', 1, ':', { actionStyle: true })
    ],
    footerRow('upper')
  ],
  special: [
    [
      inputKey('special', '1', '1'),
      inputKey('special', '2', '2'),
      inputKey('special', '3', '3'),
      inputKey('special', '4', '4'),
      inputKey('special', '5', '5'),
      inputKey('special', '6', '6'),
      inputKey('special', '7', '7'),
      inputKey('special', '8', '8'),
      inputKey('special', '9', '9'),
      inputKey('special', '0', '0'),
      actionKey('special', 'backspace', '', 'backspace', 3, { symbol: ICON_SYMBOLS.backspace })
    ],
    [
      actionKey('special', 'to-lower', 'abc', 'switch-mode', 3, { nextMode: 'lower' }),
      inputKey('special', 'plus', '+'),
      inputKey('special', 'amp', '&'),
      inputKey('special', 'slash', '/'),
      inputKey('special', 'star', '*'),
      inputKey('special', 'equal', '='),
      inputKey('special', 'percent', '%'),
      inputKey('special', 'bang', '!'),
      inputKey('special', 'question', '?'),
      inputKey('special', 'hash', '#'),
      inputKey('special', 'lt', '<'),
      inputKey('special', 'gt', '>')
    ],
    [
      inputKey('special', 'backslash', '\\'),
      inputKey('special', 'at', '@'),
      inputKey('special', 'dollar', '$'),
      inputKey('special', 'lparen', '('),
      inputKey('special', 'rparen', ')'),
      inputKey('special', 'lbrace', '{'),
      inputKey('special', 'rbrace', '}'),
      inputKey('special', 'lbracket', '['),
      inputKey('special', 'rbracket', ']'),
      inputKey('special', 'semi', ';'),
      inputKey('special', 'double-quote', '"'),
      inputKey('special', 'single-quote', "'")
    ],
    footerRow('special')
  ],
  number: [
    [
      inputKey('number', '1', '1'),
      inputKey('number', '2', '2'),
      inputKey('number', '3', '3'),
      actionKey('number', 'close', '', 'close', 2, {
        symbol: ICON_SYMBOLS.close,
        actionStyle: true
      })
    ],
    [
      inputKey('number', '4', '4'),
      inputKey('number', '5', '5'),
      inputKey('number', '6', '6'),
      actionKey('number', 'ok', '', 'ok', 2, {
        symbol: ICON_SYMBOLS.ok,
        actionStyle: true
      })
    ],
    [
      inputKey('number', '7', '7'),
      inputKey('number', '8', '8'),
      inputKey('number', '9', '9'),
      actionKey('number', 'backspace', '', 'backspace', 2, {
        symbol: ICON_SYMBOLS.backspace,
        actionStyle: false
      })
    ],
    [
      inputKey('number', 'plus-minus', '+/-'),
      inputKey('number', '0', '0'),
      inputKey('number', 'dot', '.'),
      actionKey('number', 'left', '', 'left', 1, {
        symbol: ICON_SYMBOLS.left,
        actionStyle: false
      }),
      actionKey('number', 'right', '', 'right', 1, {
        symbol: ICON_SYMBOLS.right,
        actionStyle: false
      })
    ]
  ]
}
