<?php

namespace Ignite\Core\Tests\Unit\Services\Importers;

use Ignite\Core\Entities\Participant;
use Ignite\Core\Models\Import\Hashers\TransactionHasher;
use Ignite\Core\Tests\Helpers\TransactionHelper;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Ignite\Core\Entities\User;
use Ignite\Core\Tests\TestCase;
use Ignite\Core\Entities\Transaction;
use Ignite\Core\Services\Importers\Transactions;

class TransactionsTest extends TestCase
{
    use DatabaseMigrations;
    use TransactionHelper;

    /**
     * @test
     * @group Transaction
     * @group Importer
     */
    public function it_will_save_the_transaction_when_given_correctly_formatted_data()
    {
        $this->loginAsAdmin();

        $user = factory(User::class)->create(['email' => 'it@brightspot.email']);
        factory(Participant::class)->create([
            'user_id' => $user->getKey(),
            'email' => $user->email
        ]);

        $import = $this->setupImport("type,amount,email,description\r\nEARNED,100,it@brightspot.email,Transaction #1");

        /** @var Transactions $importer */
        $importer = app(Transactions::class);

        $data = [
            'type' => Transaction::EARNED,
            'value' => $amount = 100,
            'user_id' => $user->email,
            'description' => $description = 'Transaction #1'
        ];

        $importer->record($import)->prepare();

        $transformed = $importer->transform($data);

        $result = $importer->save($transformed);

        $this->assertTrue($result);

        $this->assertDatabaseHas('core_transaction', [
            'user_id' => $user->getKey(),
            'value' => $amount,
            'type' => Transaction::EARNED,
            'description' => $description,
            'hash' => app(TransactionHasher::class)->hash([
                'identifier' => $user->email,
                'value' => $amount,
                'description' => $description,
                'type' => Transaction::EARNED
            ]),
        ]);
    }

    /**
     * @test
     * @group Transaction
     * @group Importer
     */
    public function it_will_save_the_transaction_resource_when_given_correctly_formatted_data_but_user_does_not_exist()
    {
        $this->loginAsAdmin();

        /** @var Transactions $importer */
        $importer = app(Transactions::class);

        $result = $importer->save([
            'type' => Transaction::EARNED,
            'value' => $amount = 100,
            'email' => $identifier = 'foobar@brightspot.email',
            'description' => $description = 'Transaction #1'
        ]);

        $this->assertTrue($result);

        $this->assertDatabaseHas('core_transaction_resource', [
            'identifier' => $identifier,
            'value' => $amount,
            'type' => Transaction::EARNED,
            'description' => $description,
        ]);
    }

    /**
     * @test
     * @group Transaction
     * @group Importer
     */
    public function it_will_validate_the_data()
    {
        $this->loginAsAdmin();

        $user = factory(User::class)->create(['email' => 'it@brightspot.email']);
        factory(Participant::class)->create([
            'user_id' => $user->getKey(),
            'email' => $user->email
        ]);

        $import = $this->setupImport("type,amount,email,description\r\n,,,");

        /** @var Transactions $importer */
        $importer = app(Transactions::class);

        $data = [
            'type' => '',
            'value' => '',
            'user_id' => '',
            'description' => ''
        ];

        $importer->record($import)->prepare();

        $validator = $importer->validate($data);

        $this->assertTrue($validator->fails());
    }

    /**
     * @test
     */
    public function it_will_look_for_synonyms_when_fetching_headers()
    {
        $this->loginAsAdmin();

        $user = factory(User::class)->create(['email' => 'it@brightspot.email']);
        factory(Participant::class)->create([
            'user_id' => $user->getKey(),
            'email' => $user->email
        ]);

        $import = $this->setupImport("type,balance,employee_id,description,submitted at,taxed_at\r\n,,,,,");

        /** @var Transactions $importer */
        $importer = app(Transactions::class);

        $importer->record($import)->prepare();

        $headers = $importer->getHeaders();

        $this->assertEquals('type', $headers[0]);
        $this->assertEquals('value', $headers[1]);
        $this->assertEquals('user_id', $headers[2]);
        $this->assertEquals('description', $headers[3]);
        $this->assertEquals('transaction_date', $headers[4]);
        $this->assertEquals('tax_date', $headers[5]);
    }
}
