extends Node
class_name TwitchChatBot

@onready var twitch_service = %TwitchService
@onready var twitch_bot: TwitchBot = $TwitchBot
@onready var twitch_bot_o_auth = $TwitchBot/BotAuth/OAuth

@onready var twitch_media_loader = $TwitchService/TwitchMediaLoader
@onready var twitch_chat = $TwitchService/TwitchChat


var broadcasting_twitch_user: TwitchUser
var bot_twitch_user: TwitchUser

signal message_sent(TwitchChatMessage)


@onready var oauth_setting = preload("uid://bj21tvlxs4yx0")
@onready var oauth_token = preload("uid://btwplndtmgkde")



func _ready():

	_populate_oauth_settings()

	# Stop everything if config hasn't been edited
	if ConfigManager.get_setting("client_auth", "broadcaster_username") == "username_goes_here":
		SignalBus.twitch_bot_not_configured.emit()
		return
	_load_and_apply_config()
	_connect_twitch_command_signals()
	twitch_chat.message_received.connect(_on_twitch_chat_message_received)
	_init_twitch_bot_auth()


func _populate_oauth_settings():
	oauth_setting.client_id = ConfigManager.get_setting("client_auth", "client_id")
	oauth_setting.redirect_url = ConfigManager.get_setting("client_auth", "redirect_url")
	_assign_oauth_settings(HelperMethods.get_all_children(self))

# Ignore this. Was getting tired of chasing around everything that needs this assigned
func _assign_oauth_settings(children_nodes):
	for child in children_nodes:
		if "oauth_setting" in child:
			child.oauth_setting = oauth_setting







func _init_twitch_bot_auth():
	var setup_successful: bool = await twitch_service.setup()
	if setup_successful:
		print("Twitch Service successfully set up and authenticated!")
		SignalBus.twitch_bot_authenticated.emit()
		await _init_users_from_config()
		_init_bot_info()
		_init_chat_info()
	else:
		printerr("Twitch Service setup failed. Check authentication.")


func _init_users_from_config():
	var broadcaster_login := str(ConfigManager.get_setting("client_auth", "broadcaster_username"))
	var bot_login := str(ConfigManager.get_setting("client_auth", "bot_username"))
	if broadcaster_login != "" and broadcaster_login != "username_goes_here":
		if twitch_service.has_method("get_user"):
			broadcasting_twitch_user = await twitch_service.get_user(broadcaster_login)

	if bot_login != "" and bot_login != "username_goes_here":
		if twitch_service.has_method("get_user"):
			bot_twitch_user = await twitch_service.get_user(bot_login)


func _init_bot_info():
	if bot_twitch_user:
		twitch_bot.sender = bot_twitch_user
		twitch_bot.receiver = broadcasting_twitch_user
		print("Authenticated as: %s (ID: %s)" % [bot_twitch_user.display_name, bot_twitch_user.id])
	else:
		print(bot_twitch_user)
		printerr("Could not get current bot info. RESTART")


func _init_chat_info():
	twitch_chat.broadcaster_user = broadcasting_twitch_user
	twitch_chat.sender_user = bot_twitch_user
	twitch_chat.subscribe()


func _load_and_apply_config():
	var magick_executable_path := str(ConfigManager.get_setting("basic", "magick_path"))
	if magick_executable_path == ConfigManager.DEFAULT_SETTINGS.basic.magick_path:
		## This fallback transformer isn't great. Transparent animated gifs don't play correctly
		twitch_media_loader.image_transformer = NativeImageTransformer.new()
	else:
		twitch_media_loader.image_transformer.imagemagic_path = magick_executable_path


func _connect_twitch_command_signals():
	for twitch_command in HelperMethods.get_all_children(twitch_service):
		if twitch_command is TwitchCommand:
			twitch_command.command_received.connect(_on_twitch_command_received)


func _on_twitch_chat_message_received(message):
	message_sent.emit(message)


func _on_twitch_command_received(from_username, info, args):
	match str(info.command.name).to_lower():
		"voice":
			twitch_bot.send_message("test command received from %s! %s" % [from_username, args])
		"test":
			twitch_bot.send_message("test command received from %s!" % from_username)
		"hello":
			twitch_bot.send_message("Hello! %s!" % from_username)
		"_":
			print("error. command received but no callback!")


func send_message_from_bot(message_string: String):
	if twitch_bot == null or twitch_bot.sender == null:
		printerr("TwitchBot not configured (missing sender/receiver/token).")
		return
	await twitch_bot.send_message(message_string)
