<?php

namespace App\Classes\FTN\Process\Netmail\Robot\Filefix;

use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

use App\Classes\FTN\Process\Netmail\Robot\Areafix\Base;
use App\Jobs\FilefixRescan;

// Filearea Processing Command
class Area extends Base
{
	private const LOGKEY = 'FFA';

	private const command = '%AREA';

	public static function help(): array
	{
		return [
			self::command.' [-|+]<FILEAREA> [R|D=<DAYS>]',
			'   Use the area command to subscribe (+) or unsubscribe (-) to a FILEAREA',
			'   Arguments:',
			'   - FILEAREA (required) name of area to subscribe or unsubscribe',
			'   - D=DAYS (optional) number of days to resend files from this area that you',
			'     havent already received (useful if you are resubscribing to an area and',
			'     have received files in the past)',
			'   - R=DAYS (optional) number of days to resend files from this area (even if',
			'     it was sent to you previously)',
			'   Notes:',
			'   * "+" is optional, and is implied if "-" is not used',
			'   * "R" and "D" options only apply to subscribing',
		];
	}

	public function process(): string
	{
		$command = self::command.' '.join(' ',$this->arguments);

		if (! ($area=Arr::get($this->arguments,0,NULL)))
			return sprintf('%-25s <-- INVALID, AN AREA IS REQUIRED',$command);

		// If command starts with '-', its to unsubscribe
		if (str_starts_with($area,'-')) {
			$sub = FALSE;
			$area = substr($area,1);

		} elseif (str_starts_with($area,'+')) {
			$sub = TRUE;
			$area = substr($area,1);

		} else {
			$sub = TRUE;
			$area = $area;
		}

		Log::debug(sprintf('%s:- Processing [%s] for [%s]',self::LOGKEY,$sub ? 'ADD' : 'REMOVE',$area));

		// Drop the area from the arguments, the rest are options
		array_shift($this->arguments);

		// Area exists
		if ($fa=$this->mo->fftn->domain->fileareas->where('name',$area)->pop()) {
			// If already subscribed
			if ($nea=$this->mo->fftn->fileareas->where('name',$area)->pop()) {
				// requesting to subscribe "You already are since..., arguments ignored
				if ($sub) {
					Log::debug(sprintf('%s:- FTN [%s] ALREADY subscribed to [%s] since [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area,$nea->pivot->subscribed));

					return sprintf('%-25s <-- ALREADY subscribed since %s',$command,$nea->pivot->subscribed);

				// requesting to unsubscribe
				} else {
					$this->mo->fftn->fileareas()->detach($fa->id);

					// Remove sub, clear queue
					$x = DB::table('file_seenby')
						->where('address_id',$this->mo->fftn->id)
						->join('files',['files.id'=>'file_seenby.file_id'])
						->where('filearea_id',$nea->id)
						->whereNotNull('export_at')
						->whereNull('sent_at')
						->orderBy('files.datetime')
						->skip(1)		// Might already being sent in this session
						->delete();

					Log::debug(sprintf('%s:- FTN [%s] UNSUBSCRIBED from [%s] clearing [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area,$x));

					return sprintf('%-25s <-- UNSUBSCRIBED, CLEARED [%d] FILES from queue',$command,$x);
				}

			// If not subscribed
			} else {
				// requesting to subscribe, subsubsribe and rescan if arguments
				if ($sub) {
					$this->mo->fftn->fileareas()->attach([$fa->id=>['subscribed'=>Carbon::now()]]);

					// If we have arguments, they are to rescan
					if (count($this->arguments) === 1) {
						$m = [];
						if (preg_match('/^([DR])=([0-9]+)$/',$this->arguments[0],$m)) {
							switch ($m[1]) {
								// Scan
								case 'D':
									FilefixRescan::dispatch($this->mo->fftn,$fa,$m[2])
										->onQueue('mail');

									return sprintf('%-25s <-- SUBSCRIBED, RESCAN [%d] DAYS queued',$command,$m[2]);

								// Scan
								case 'R':
									FilefixRescan::dispatch($this->mo->fftn,$fa,$m[2],TRUE)
										->onQueue('mail');

									return sprintf('%-25s <-- SUBSCRIBED, FORCE RESCAN [%d] DAYS queued',$command,$m[2]);
							}
						}

						return sprintf('%-25s <-- SUBSCRIBED, INVALID OPTIONS',$command);

					} elseif (count($this->arguments) > 1) {
						Log::debug(sprintf('%s:- FTN [%s] subscribed to [%s], extra commands [%s] ignored',self::LOGKEY,$this->mo->fftn->ftn,$area,join('|',$this->arguments)));

						return sprintf('%-25s <-- SUBSCRIBED, OPTIONS IGNORED',$command);

					} else {
						Log::debug(sprintf('%s:- FTN [%s] subscribed to [%s]',self::LOGKEY,$this->mo->fftn->ftn,$area));

						return sprintf('%-25s <-- SUBSCRIBED',$command);
					}

					// If not subscribed, "you arent subscribed, arguments ignored"
				} else {
					Log::debug(sprintf('%s:- FTN [%s] is NOT subscribed to [%s], NO ACTION taken',self::LOGKEY,$this->mo->fftn->ftn,$area));

					return sprintf('%-25s <-- NOT subscribed, NO ACTION taken',$command);
				}
			}

		} else {
			Log::debug(sprintf('%s:- FILE [%s] area UNKNOWN [%s], NO ACTION taken',self::LOGKEY,$this->mo->fftn->ftn,$area));

			return sprintf('%-25s <-- AREA UNKNOWN, NO ACTION TAKEN',$command);
		}
	}
}