<?php

namespace App\Console\Commands\Filefix;

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

use App\Models\{Address,Filearea,File};

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

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

	/**
	 * Execute the console command.
	 *
	 * @return int
	 * @throws \Exception
	 */
	public function handle(): int
	{
		$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');

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

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

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

		foreach (File::select('id')
			->where('filearea_id',$fao->id)
			->when($this->argument('file'),function($query) {
				return $query->where('name','=',$this->argument('days'));
			})
			->orderBy('datetime')
			->cursor() as $fo) {

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

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

				// File 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]',$fo->id,$ao->ftn3d));

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

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

		return self::SUCCESS;
	}
}