<?php

namespace Tests\Feature;

use App\Models\{Account,Rtm,Site,User};
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Tests\TestCase;

class AccountRoleTest extends TestCase
{
	use DatabaseTransactions;

	private Collection $setup;

	private function init()
	{
		$this->setup = collect();
		$this->setup->put('user',collect());
		$this->setup->put('account',collect());

		// Create our sites
		$this->setup->put('site',[
			'a'=>Site::factory()->create(['url'=>'Test A']),
			'b'=>Site::factory()->create(['url'=>'Test B']),
		]);

		// For each site, create 9 accounts - 1 wholesaler, 2 resellers, 6 accounts
		foreach ($this->setup['site'] as $key => $so) {
			$this->setup->get('user')->put($key,
				[
					'w'=>User::factory()->create(['firstname'=>'Wholesaler','site_id'=>$so->site_id]),
					'r1'=>User::factory()->create(['firstname'=>'Reseller 1','site_id'=>$so->site_id]),
					'r2'=>User::factory()->create(['firstname'=>'Reseller 1-2','site_id'=>$so->site_id]),
					'a1-1'=>User::factory()->create(['firstname'=>'Account 1-1','site_id'=>$so->site_id]),
					'a1-2'=>User::factory()->create(['firstname'=>'Account 1-2','site_id'=>$so->site_id]),
					'a1-3'=>User::factory()->create(['firstname'=>'Account 1-2','site_id'=>$so->site_id]),
					'a2-1'=>User::factory()->create(['firstname'=>'Account 2-1','site_id'=>$so->site_id]),
					'a2-2'=>User::factory()->create(['firstname'=>'Account 2-2','site_id'=>$so->site_id]),
					'a2-3'=>User::factory()->create(['firstname'=>'Account 2-2','site_id'=>$so->site_id]),
				]
			);
			$us = $this->setup->get('user');

			$this->setup->get('account')->put($key,
				[
					'w'=>Account::factory()->create(['company'=>'Wholesaler','site_id'=>$so->site_id,'user_id'=>Arr::get($us,sprintf('%s.%s',$key,'w'))->id]),
					'r1'=>Account::factory()->create(['company'=>'Reseller 1','site_id'=>$so->site_id,'user_id'=>Arr::get($us,sprintf('%s.%s',$key,'r1'))->id]),
					'r2'=>Account::factory()->create(['company'=>'Reseller 1-2','site_id'=>$so->site_id,'user_id'=>Arr::get($us,sprintf('%s.%s',$key,'r2'))->id]),
				]
			);
			$as = $this->setup->get('account');

			// Setup the RTM to support
			$w = Rtm::factory()->create(['name'=>'Wholesaler','site_id'=>$so->site_id,'account_id'=>Arr::get($as,sprintf('%s.%s',$key,'w'))->id,'parent_id'=>null]);
			$r1 = Rtm::factory()->create(['name'=>'Reseller 1','site_id'=>$so->site_id,'account_id'=>Arr::get($as,sprintf('%s.%s',$key,'r1'))->id,'parent_id'=>$w->id]);
			$r2 = Rtm::factory()->create(['name'=>'Reseller 1-2','site_id'=>$so->site_id,'account_id'=>Arr::get($as,sprintf('%s.%s',$key,'r2'))->id,'parent_id'=>$r1->id]);

			// Update our RTM for the reseller accounts
			Arr::get($as,sprintf('%s.%s',$key,'r1'))->forceFill(['rtm_id'=>$w->id])->save();
			Arr::get($as,sprintf('%s.%s',$key,'r2'))->forceFill(['rtm_id'=>$r1->id])->save();

			$this->setup->get('account')->put($key,array_merge($this->setup->get('account')->get($key),
				[
					'a1-1'=>Account::factory()->create(['company'=>'Account 1-1','site_id'=>$so->site_id,'rtm_id'=>$r1->id]),
					'a1-2'=>Account::factory()->create(['company'=>'Account 1-2','site_id'=>$so->site_id,'rtm_id'=>$r1->id]),
					'a1-3'=>Account::factory()->create(['company'=>'Account 1-3','site_id'=>$so->site_id,'rtm_id'=>$r1->id]),
					'a2-1'=>Account::factory()->create(['company'=>'Account 2-1','site_id'=>$so->site_id,'rtm_id'=>$r2->id]),
					'a2-2'=>Account::factory()->create(['company'=>'Account 2-2','site_id'=>$so->site_id,'rtm_id'=>$r2->id]),
					'a2-3'=>Account::factory()->create(['company'=>'Account 2-3','site_id'=>$so->site_id,'rtm_id'=>$r2->id]),
				]
			));
		}
	}

    /**
     * Test our roles work correctly
     *
     * @return void
     */
    public function test_account_role()
    {
        // Setup
		$this->init();

		// For each site
		foreach ($this->setup['site'] as $site => $so) {
			Config::set('site',$so);

			// Foreach user
			foreach ($this->setup['user'] as $user => $uo) {
				if ($site !== $user)
					continue;

				// Check our roles
				$this->assertEquals('wholesaler',$uo['w']->role());
				$this->assertEquals('reseller',$uo['r1']->role());
				$this->assertEquals('reseller',$uo['r2']->role());
				$this->assertEquals('customer',$uo['a1-1']->role());
				$this->assertEquals('customer',$uo['a1-2']->role());
				$this->assertEquals('customer',$uo['a1-3']->role());
				$this->assertEquals('customer',$uo['a2-1']->role());
				$this->assertEquals('customer',$uo['a2-2']->role());
				$this->assertEquals('customer',$uo['a2-3']->role());

				// Check that accounts do not have an RTM
				$this->assertNull($uo['a1-1']->rtm);
				$this->assertNull($uo['a1-2']->rtm);
				$this->assertNull($uo['a1-3']->rtm);
				$this->assertNull($uo['a2-1']->rtm);
				$this->assertNull($uo['a2-2']->rtm);
				$this->assertNull($uo['a2-3']->rtm);

				// Check that the RTM exists for resellers and wholesalers
				$this->assertModelExists($uo['r1']->rtm);
				$this->assertModelExists($uo['r2']->rtm);
				$this->assertModelExists($uo['w']->rtm);

				// Check the hierarchy
				$this->assertEquals(3,$uo['w']->rtm_list()->count());
				$this->assertEquals(2,$uo['r1']->rtm_list()->count());
				$this->assertEquals(1,$uo['r2']->rtm_list()->count());

				// Check that the users get the right amount of accounts
				$this->assertEquals(9,$uo['w']->accounts->count());
				$this->assertEquals(8,$uo['r1']->accounts->count());
				$this->assertEquals(4,$uo['r2']->accounts->count());
			}
		}
    }
}
