import re
import unicodedata

jp_pos_to_en_pos = {
    '投': 'P',
    '捕': 'C',
    '一': '1B',
    '二': '2B',
    '三': '3B',
    '遊': 'SS',
    '左': 'LF',
    '中': 'CF',
    '右': 'RF',
    '右中': 'RCF',
    '左中': 'LCF'
}

def translate_pa_outcome(outcome):

  partial_outcomes = {
      'ファウルフライ': 'FF',
      'ファウルライナー': 'FL',
      'ゴロ': 'GB',
      'フライ': 'FB',
      'ライナー': 'LD',
      '安打': '1B',
      '2塁打': '2B',
      '3塁打': '3B',
      'ランニング本塁打': 'IHR', # inside-the-park home run
      '本塁打': 'HR',
      '犠打': 'SH',
      '犠飛': 'SF',
      '併殺打': 'DP', # what about triple plays?
      'エラー': 'E',
      '犠打野選': 'SH FC',
      '野選': 'FC'
  }

  if outcome.endswith('三振'):
    if outcome.startswith('空振り'):
      return 'K'
    elif outcome.startswith('見逃し'):
      return 'inv_K'
  elif outcome == '四球':
    return 'BB'
  elif outcome == '死球':
    return 'HBP'
  elif outcome == '敬遠(申告敬遠)':
    return 'IBB'
  elif outcome == 'スリーバント失敗':
    return 'bunt_K' # have to confirm
  elif outcome == '犠打失':
    return 'failed_SH' # have to confirm
  elif outcome == '犠飛失':
    return 'failed_SF' #have to confirm
  elif outcome.endswith('走塁妨害'):
    return 'obstruction'
  elif outcome.endswith('走塁妨害'):
    return 'dropped_K_safe'
  elif outcome == '振り逃げ' or '暴投' in outcome:
    return 'WP' # reached base on WP; on another search, 振り逃げ is an uncaught third strike
  elif outcome.endswith('塁けん制 アウト'):
    return outcome.replace('塁けん制 アウト', 'B PK')
  elif 'けん制アウト' in outcome:
    return 'XB PK' # pickoff at unknown base
  elif outcome == '守備妨害':
    return 'defensive_interference'
  elif '盗塁失敗' in outcome:
    return 'CS'
  elif tag_search:= re.search(r'[123本](・[123本])*塁(間|上)タッチアウト', outcome):
    outcome = unicodedata.normalize('NFKC', tag_search.group(0))
    outcome = outcome.replace('本', 'H')
    bases = re.findall(r'\d|H', outcome)
    return ' '.join(bases) + 'TO' # tag out
  elif '捕逸' in outcome:
    return 'PB' # reached base on passed ball

  for _outcome in partial_outcomes.keys():
    if outcome.endswith(_outcome):
      return f'{jp_pos_to_en_pos[outcome.removesuffix(_outcome)]} {partial_outcomes[_outcome]}'

  return outcome

jp_pitch_to_en_pitch = {
    # fastballs
    'ストレート': '4-Seam Fastball',
    'ツーシーム': '2-Seam Fastball',
    'カットボール': 'Cutter',
    'ワンシーム': '1-Seam Fastball',
    'シンカー': 'Sinker',
    'シュート': 'Shootball',

    # breaking balls
    'スライダー': 'Slider',
    '縦スライダー': 'Vertical Slider',
    '高速スライダー': 'Hard Slider',
    'スラーブ': 'Slurve',
    'カーブ': 'Curveball',
    'ナックルカーブ': 'Knuckle Curve',
    'スローカーブ': 'Slow Curve',
    'パワーカーブ': 'Power Curve',
    'スクリュー': 'Screwball',

    # off speed
    'チェンジアップ': 'Changeup',
    'スプリット': 'Splitter',
    'フォーク': 'Forkball',
    'パーム': 'Palmball',

    # other
    'スローボール': 'Eephus',
}

jp_pitch_to_pitch_code = {
    # fastballs
    'ストレート': 'FF',
    'ツーシーム': 'FT',
    'カットボール': 'FC',
    'ワンシーム': 'FE',
    'シンカー': 'SI',
    'シュート': 'SH',

    # breaking balls
    'スライダー': 'SL',
    '縦スライダー': 'VS',
    '高速スライダー': 'HS',
    'スラーブ': 'SV',
    'カーブ': 'CU',
    'ナックルカーブ': 'KC',
    'スローカーブ': 'CS',
    'パワーカーブ': 'PC',
    'スクリュー': 'SC',

    # off speed
    'チェンジアップ': 'CH',
    'スプリット': 'FS',
    'フォーク': 'FO',
    'パーム': 'PA',

    # other
    'スローボール': 'EP',
}

def translate_pitch_outcome(outcome):

  partial_outcomes = {
      '失': 'E',
      '犠打': 'SH',
      '犠飛': 'SF',
      '邪直': 'FLD', # foul line drive
      '邪飛': 'FF',
      'ゴロ': 'GB',
      '飛': 'FB',
      '直': 'LD',
      '安': '1B',
      '2': '2B',
      '3': '3B',
      '走本': 'IHR', # inside-the-park home run, should confirm
      '本': 'HR',
      '併打': 'DP',
      '犠野': 'SH FC',
      '野選': 'FC'

  }

  if outcome == 'ボール':
    return 'B'
  elif outcome == 'ファウル':
    return 'F'
  elif outcome == '空振り':
    return 'SS' # swinging strike
  elif outcome == '見逃し':
    return 'LS' # swinging strike
  elif outcome == '空三振':
    return 'K'
  elif outcome == '見三振':
    return 'inv_K'
  elif outcome == 'バ三振':
    return 'bunt_K'
  elif outcome == '四球':
    return 'BB'
  elif outcome == '死球':
    return 'HBP'
  elif outcome == '犠打失':
    return 'SH_E' # or SBE? sac hit error
  elif outcome == '犠飛失':
    return 'SF_E' # sac fly error
  elif outcome == '走妨':
    return 'obstruction'
  elif outcome == '反則投球':
    return 'illegal_pitch'
  elif outcome == '守妨':
    return 'defensive_interference'
  elif outcome == '暴振逃':
    return 'WP_S'
  elif outcome == '逸振逃':
    return 'PB_S'

  for _outcome in partial_outcomes.keys():
    if outcome.endswith(_outcome):
      return f'{jp_pos_to_en_pos[outcome.removesuffix(_outcome)]} {partial_outcomes[_outcome]}'

  return outcome

max_pitch_types = len(jp_pitch_to_en_pitch)