<?php

namespace Tests\Units\Repository;

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

use App\Models\CashbookAccount;
use App\Models\CashbookEntry;

use App\Repositories\Cashbook\CashbookRepository;

class CashbookRepositoryTest extends \TestCase
{
    use DatabaseTransactions;

    public function testCashOnHandForSingleEntry()
    {
        $acc = factory(CashbookAccount::class, 'Cashbook')->create();
        $entry = factory(CashbookEntry::class, 'debit')->make();
        $entry->account()->associate($acc);
        $entry->save();

        $repo = new CashbookRepository;

        $cashOnHand = $repo->cashOnHand("Cashbook");

        $this->assertEquals(1, $cashOnHand->count());
        $this->assertEquals($entry->beginning_balance, $cashOnHand[0]->beginning_balance);
        $this->assertEquals($entry->debit, $cashOnHand[0]->debit);
        $this->assertEquals($entry->credit, $cashOnHand[0]->credit);
        $this->assertEquals($entry->ending_balance, $cashOnHand[0]->ending_balance);
    }

    public function testCashOnHandForMultipleSingleCurrencyEntries()
    {
        $php = \App\Models\Base\Currency::where('name', 'Peso')->first();
        $acc = factory(CashbookAccount::class, 'Cashbook')->create();

        $entry = factory(CashbookEntry::class, 'debit')->make();
        $entry->currency()->associate($php);
        $entry->account()->associate($acc);
        $entry->entered_at = \Carbon\Carbon::now()->subDays(10);
        $entry->created_at = \Carbon\Carbon::now()->subDays(10);
        $entry->updated_at = \Carbon\Carbon::now()->subDays(10);
        $entry->save();

        $entry2 = factory(CashbookEntry::class, 'debit')->make();
        $entry2->currency()->associate($php);
        $entry2->account()->associate($acc);
        $entry2->entered_at = \Carbon\Carbon::now()->subDays(9);
        $entry2->created_at = \Carbon\Carbon::now()->subDays(9);
        $entry2->updated_at = \Carbon\Carbon::now()->subDays(9);
        $entry2->save();

        $entry3 = factory(CashbookEntry::class, 'debit')->make();
        $entry3->currency()->associate($php);
        $entry3->account()->associate($acc);
        $entry3->entered_at = \Carbon\Carbon::now()->subDays(8);
        $entry3->created_at = \Carbon\Carbon::now()->subDays(8);
        $entry3->updated_at = \Carbon\Carbon::now()->subDays(8);
        $entry3->save(['timestamps' => false]);

        $repo = new CashbookRepository;

        $cashOnHand = $repo->cashOnHand("Cashbook");

        $this->assertEquals(1, $cashOnHand->count());
        $this->assertEquals($entry3->beginning_balance, $cashOnHand[0]->beginning_balance);
        $this->assertEquals($entry3->debit, $cashOnHand[0]->debit);
        $this->assertEquals($entry3->credit, $cashOnHand[0]->credit);
        $this->assertEquals($entry3->ending_balance, $cashOnHand[0]->ending_balance);
    }

    public function testCashOnHandForMultipleCurrencyEntries()
    {
        $php = \App\Models\Base\Currency::where('name', 'Peso')->first();
        $eur = \App\Models\Base\Currency::where('name', 'Euro')->first();
        $acc = factory(CashbookAccount::class, 'Cashbook')->create();

        $entry = factory(CashbookEntry::class, 'debit')->make();
        $entry->currency()->associate($php);
        $entry->account()->associate($acc);
        $entry->entered_at = \Carbon\Carbon::now()->subDays(10);
        $entry->save();

        $entry2 = factory(CashbookEntry::class, 'debit')->make();
        $entry2->currency()->associate($eur);
        $entry2->account()->associate($acc);
        $entry2->entered_at = \Carbon\Carbon::now()->subDays(9);
        $entry2->save();

        $repo = new CashbookRepository;

        $cashOnHand = $repo->cashOnHand("Cashbook");

        $this->assertEquals(2, $cashOnHand->count());

        // assert php values
        $p = $cashOnHand->where('currency.name', 'Peso')->first();
        $this->assertEquals($entry->beginning_balance, $p->beginning_balance);
        $this->assertEquals($entry->debit, $p->debit);
        $this->assertEquals($entry->credit, $p->credit);
        $this->assertEquals($entry->ending_balance, $p->ending_balance);

        // assert eur values
        $e = $cashOnHand->where('currency.name', 'Euro')->first();
        $this->assertEquals($entry2->beginning_balance, $e->beginning_balance);
        $this->assertEquals($entry2->debit, $e->debit);
        $this->assertEquals($entry2->credit, $e->credit);
        $this->assertEquals($entry2->ending_balance, $e->ending_balance);
    }
}