<?php

namespace App\Console\Commands\Areafix;

use Carbon\Carbon;
use Illuminate\Console\Command;

use App\Models\{Address,Echoarea,Echomail};

class Rescan extends Command
{
	/**
	 * The name and signature of the console command.
	 *
	 * @var string
	 */
	protected $signature = 'areafix:rescan {ftn} {area} {days?}';

	/**
	 * The console command description.
	 *
	 * @var string
	 */
	protected $description = 'Resend some echomail to a node';

	/**
	 * Execute the console command.
	 *
	 * @return mixed
	 * @throws \Exception
	 */
	public function handle()
	{
		if (($this->argument('days')) && (! is_numeric($this->argument('days'))))
			throw new \Exception('Days must be numeric: '.$this->argument('days'));

		$ao = Address::findFtn($this->argument('ftn'));

		if (! $ao)
			throw new \Exception('FTN not found: '.$this->argument('ftn'));

		// Check that the area belongs to the domain for the FTN
		if (! $this->argument('area'))
			throw new \Exception('Areaname is required');

		$eao = Echoarea::where('name',$this->argument('area'))->singleOrFail();
		if ($eao->domain_id !== $ao->zone->domain_id)
			throw new \Exception(sprintf('Echo area [%s] is not in domain [%s] for FTN [%s]',$eao->name,$ao->zone->domain->name,$ao->ftn));

		// Check that the user is subscribed
		if (! $ao->echoareas->contains($eao->id))
			throw new \Exception(sprintf('FTN [%s] is not subscribed to [%s]',$ao->ftn,$eao->name));

		// Check that an FTN can read the area
		if (! $eao->can_read($ao->security))
			throw new \Exception(sprintf('FTN [%s] doesnt have permission to receive [%s]',$ao->ftn,$eao->name));

		foreach (Echomail::select('id')
			->where('echoarea_id',$eao->id)
			->when($this->argument('days'),function($query) {
				return $query->where('created_at','>=',Carbon::now()->subDays($this->argument('days'))->startOfDay());
			})
			->orderBy('datetime')
			->cursor() as $eo) {

			// Echomail hasnt been exported before
			if (! $eo->seenby->count()) {
				$eo->seenby()->attach($ao->id,['export_at'=>Carbon::now()]);
				$this->info(sprintf('Exported [%d] to [%s]',$eo->id,$ao->ftn3d));

			} else {
				$export = $eo->seenby->where('id',$ao->id)->pop();

				// Echomail is pending export
				if ($export && $export->pivot->export_at && is_null($export->pivot->sent_at) && is_null($export->pivot->sent_pkt)) {
					$this->warn(sprintf('Not exporting [%d] already queued for [%s]',$eo->id,$ao->ftn3d));

				// Echomail has been exported
				} elseif ($export) {
					$eo->seenby()->updateExistingPivot($ao,['export_at'=>Carbon::now(),'sent_at'=>NULL,'sent_pkt'=>NULL]);
					$this->info(sprintf('Re-exported [%d] to [%s]',$eo->id,$ao->ftn3d));

				// Echomail has not been exported
				} else {
					$eo->seenby()->attach($ao,['export_at'=>Carbon::now(),'sent_at'=>NULL,'sent_pkt'=>NULL]);
					$this->info(sprintf('Exported [%d] to [%s]',$eo->id,$ao->ftn3d));
				}
			}
		}

		return self::SUCCESS;
	}
}