<?php

namespace App\Classes\FTN\Process\Netmail;

use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Log;

use App\Classes\FTN\Process;
use App\Classes\FTN\Process\Netmail\Robot\Unknown;
use App\Models\{Echomail,Netmail};
use App\Notifications\Netmails\FixCantHandle;
use App\Notifications\Netmails\Areafix\{CommandsProcessed,InvalidPassword,NotConfiguredHere};

/**
 * Process messages to Ping
 *
 * @package App\Classes\FTN\Process
 */
final class Areafix extends Process
{
	private const LOGKEY = 'RP-';

	public const areafix_commands = 'App\\Classes\\FTN\\Process\\Netmail\\Robot\\Areafix\\';

	public static function handle(Echomail|Netmail $mo): bool
	{
		if (((strtolower($mo->to) !== 'areafix') || (strtolower($mo->to) !== 'filefix')) && (! ($mo instanceof Netmail)))
			return FALSE;

		Log::info(sprintf('%s:- Processing *FIX [%s] message from (%s) [%s]',self::LOGKEY,$mo->to,$mo->from,$mo->fftn->ftn));

		// If this is not a node we manage, then respond with a sorry can help you
		if (! $mo->fftn->system->sessions->count()) {
			Notification::route('netmail',$mo->fftn)->notify(new NotConfiguredHere($mo));

			return TRUE;
		}

		// If this nodes password is not correct
		if ($mo->fftn->pass_fix !== strtoupper($mo->subject)) {
			Notification::route('netmail',$mo->fftn)->notify(new InvalidPassword($mo));

			return TRUE;
		}

		if ((strtolower($mo->to) === 'areafix'))
			return self::areafix($mo);

		if ((strtolower($mo->to) === 'filefix'))
			return self::filefix($mo);

		return FALSE;
	}

	public static function areafix(Netmail $mo): bool
	{
		$result = collect();
		$result->push('--> BEGIN <--');

		foreach ($mo->body_lines as $command) {
			// Skip empty lines
			if (! $command)
				continue;

			$command = explode(' ',strtoupper(trim($command)));

			// If command starts with '...' or '---', its a tear/tag line, and we have reached the end
			if (str_starts_with($command[0],'...') || str_starts_with($command[0],'---')) {
				Log::debug(sprintf('%s:= We got a tearline/tagline, end of processing',self::LOGKEY));

				$result->push('--> END OF PROCESSING <--');

				break;

			// If command doesnt start with %, its an area
			} elseif (! str_starts_with($command[0],'%')) {
				Log::debug(sprintf('%s:= Assuming command [%s] is an AREA command',self::LOGKEY,$command[0]));

				array_unshift($command,'%AREA');
			}

			// Parse the message body and pluck out the commands on each line
			$class = self::areafix_commands.ucfirst(strtolower(substr($command[0],1)));

			if (! class_exists($class)) {
				$result->push(sprintf('%-25s <-- **COMMAND UNKNOWN**',join(' ',$command)));

				continue;
			}

			// Drop the command from the array, the rest are arguments
			array_shift($command);

			// Refresh our echoareas
			$mo->fftn->load('echoareas');

			$o = new $class($mo,$command);
			$result->push($o->process());
		}

		// Reply with a confirmation of what commands were processed
		Notification::route('netmail',$mo->fftn)->notify(new CommandsProcessed($mo,$result));

		return TRUE;
	}

	public static function filefix(Netmail $mo): bool
	{
		Notification::route('netmail',$mo->fftn)->notify(new FixCantHandle($mo));

		return TRUE;
	}
}