import json
from os import PathLike, path
from typing import TypeAlias, List, Dict, Final, Literal, TypeVar

# Error and warning messages
ERROR_MESSAGE1: Final[str] = 'Invalid Symbols - Dots, dashes, and separators must be single characters!'
ERROR_MESSAGE2: Final[str] = 'Invalid Characters - Use only specified dots, dashes, spaces, and separators!'
ERROR_MESSAGE3: Final[str] = 'Invalid Language - The specified language is not recognized or supported'

# Custom types
Language: TypeAlias = Literal['english', 'spanish', 'french', 'russian', 'ukrainian', 'numbers', 'special']
JSONDictionary: TypeAlias = Dict[str, Dict[str, str]]
PathLikeString: TypeAlias = str | PathLike

# Other
SUPPORTED_LANGUAGES: List[str] = ['english', 'spanish', 'french', 'russian', 'ukrainian']

# Generic types
KT = TypeVar('KT')
VT = TypeVar('VT')


# Useful functions
def reverse_dictionary(dictionary: Dict[KT, VT], /) -> Dict[VT, KT]:
	"""
	Reverse a dictionary

	:parameter dictionary: Input dictionary

	:returns: List of individual Morse code characters
	"""

	return {value: key for key, value in dictionary.items()}


def get_encodes() -> JSONDictionary:
	"""
	Load the Morse code encodings from the "encodes.json"

	:returns: Dictionary containing Morse code encodings
	"""

	file_path: str = path.join(path.dirname(path.abspath(__file__)), 'codes', 'encodes.json')

	with open(file_path, 'r', encoding='utf-8') as file:
		return json.load(file)


def get_decodes() -> JSONDictionary:
	"""
	Load the Morse code decodings from the "decodes.json"

	:returns: Dictionary containing Morse code decodings
	"""

	file_path: str = path.join(path.dirname(path.abspath(__file__)), 'codes', 'decodes.json')

	with open(file_path, 'r', encoding='utf-8') as file:
		return {key: reverse_dictionary(value) for key, value in json.load(file).items()}


def separate_words(words: str, /, dot: str, dash: str, separator: str) -> List[str]:
	"""
	Separate a string into Morse code letters

	:parameter words: Input string
	:parameter dot: Symbol representing dots
	:parameter dash: Symbol representing dashes
	:parameter separator: Symbol separating words

	:returns: List of Morse code letters
	"""

	letters: List[str] = []
	current: str = ''

	for character in words:
		if character in (dot, dash):
			current += character
		elif character == separator:
			if current:
				letters.append(current)
				current = ''
			letters.append(separator)
		elif character == ' ':
			if current:
				letters.append(current)
				current = ''
		else:
			current += character

	if current:
		letters.append(current)

	return letters


def separate_letters(letters: List[str], /) -> List[str]:
	"""
	Separate Morse code letters into individual characters

	:parameter letters: Input list

	:returns: List of individual Morse code characters
	"""

	return [character for letter in letters for character in letter]
