<?php

namespace Tests\Feature;

use App\Models\Memo;
use App\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Symfony\Component\HttpFoundation\Response;
use Tests\TestCase;

class MemosTest extends TestCase
{
    use RefreshDatabase;

    /** @test */
    public function an_unauthenticated_user_should_redirect_to_login()
    {
        $response = $this->post('/api/memos', $this->data());

        $this->assertGuest($guard = null);
        $response->assertRedirect('/login');
        $this->assertCount(0, Memo::all());
    }

    /** @test */
    public function an_unauthenticated_user_can_add_a_memo()
    {
        $this->withoutExceptionHandling();

        $this->actingAs($user = factory(\App\User::class)->create(), 'api');

        $response = $this->post('/api/memos', $this->data());

        $memo = Memo::first();

//        $this->assertCount(1, Contact::all());
        $this->assertEquals('Test Name', $memo->name);
        $this->assertEquals('Test Memo', $memo->memo);

        $response->assertStatus(Response::HTTP_CREATED);
        $response->assertJson([
            'data' => [
                'memo_id' => $memo->id
            ],
            'links' => [
                'self' => $memo->path(),
            ]
        ]);
    }

    /** @test */
    public function memo_name_are_required()
    {
        $this->actingAs($user = factory(\App\User::class)->create(), 'api');
        $response = $this->post('/api/memos', array_merge($this->data(), ['name' => '']));

        $response->assertSessionHasErrors('name');
        $this->assertCount(0, Memo::all());
    }

    /** @test */
    public function memo_are_required()
    {
        $this->actingAs($user = factory(\App\User::class)->create(), 'api');
        $response = $this->post('/api/memos', array_merge($this->data(), ['memo' => '']));

        $response->assertSessionHasErrors('memo');
        $this->assertCount(0, Memo::all());
    }

    /** @test */
    public function a_memo_can_be_retrieved()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');

        $memo = factory(Memo::class)->create(['user_id' => $user->id]);

        $response = $this->get('/api/memos/' . $memo->id );

        $response->assertJson([
            'data' => [
                'memo_id' => $memo->id,
                'name' => $memo->name,
                'memo' => $memo->memo,
                'last_updated' => $memo->updated_at->diffForHumans(),
            ]
        ]);
    }

    /** @test */
    public function a_memo_can_be_patch()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');

        $memo = factory(Memo::class)->create(['user_id' => $user->id]);

        $response = $this->patch('/api/memos/' . $memo->id, $this->data());

        $memo = $memo->fresh();

        $this->assertEquals('Test Memo', $memo->memo);

        $response->assertStatus(Response::HTTP_OK);
        $response->assertJson([
            'data' => [
                'memo_id' => $memo->id
            ],
            'links' => [
                'self' => $memo->path(),
            ]
        ]);
    }

    /** @test */
    public function only_the_owner_can_patch_the_memo()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');
        $memo = factory(Memo::class)->create();

        $anotherUser = factory(User::class)->create();

        $response = $this->patch('/api/memos/' . $memo->id, array_merge($this->data(), ['api_token' => $anotherUser->api_token]));

        $response->assertStatus(Response::HTTP_FORBIDDEN);
    }

    /** @test */
    public function a_memo_can_be_delete()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');

        $memo = factory(Memo::class)->create(['user_id' => $user->id]);

        $response = $this->delete('/api/memos/' . $memo->id);

        $memo = $memo->fresh();

        $this->assertCount(0, Memo::all());

        $response->assertStatus(Response::HTTP_NO_CONTENT);
    }

    /** @test */
    public function only_the_owner_can_delete_the_memo()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');
        $memo = factory(Memo::class)->create();

        $anotherUser = factory(User::class)->create();

        $response = $this->delete('/api/memos/' . $memo->id, ['api_token' => $anotherUser->api_token]);

        $response->assertStatus(Response::HTTP_FORBIDDEN);
    }

    /** @test */
    public function a_list_of_memos_can_be_fetched_for_the_authenticated_user()
    {
        $this->actingAs($user = factory(User::class)->create(), 'api');
        $anotherUser = factory(User::class)->create();

        $memo = factory(Memo::class)->create(['user_id' => $user->id]);
        $anotherMemo = factory(Memo::class)->create(['user_id' => $anotherUser->id]);

        $response = $this->get('/api/memos');

        $response->assertJsonCount(1)
            ->assertJson( [
                'data' => [
                    [
                        'data' => [
                            'memo_id' => $memo->id
                        ]
                    ]
                ]
            ]);
    }

    /** @test */
    public function only_the_users_memos_can_be_retrieved()
    {
        $user = factory(User::class)->create();
        $memo = factory(Memo::class)->create(['user_id' => $user->id]);

        $this->actingAs($anotherUser = factory(User::class)->create(), 'api');
        $response = $this->get('/api/memos/' . $memo->id );

        $response->assertStatus(Response::HTTP_FORBIDDEN);
    }

//    /** @test */
//    public function user_can_add_tag_to_memo()
//    {
//        //$this->withoutExceptionHandling();
//
//        $memo = $this->post('/api/memos', $this->data());
//        $tag = factory(Tag::class)->create(['user_id' => $this->user->id]);
//
//        $response = $this->patch('/api/tag/add-tag/' . $tag->slug, ['api_token' => $this->user->api_token, 'model' => $memo['data']]);
//
//        $response->assertStatus(Response::HTTP_CREATED)
//            ->assertJson( [
//                    'data' => [
//                        'memo_id' => $memo['data']['memo_id'],
//                        'tags' => [
//                            [
//                                'data' => [
//                                    'tag_id' => $tag->id,
//                                    'name' => $tag->name,
//                                    'slug' => $tag->slug,
//                                ]
//                            ]
//                        ]
//                    ]
//                ]
//            );
//    }

//    /** @test */
//    public function user_can_remove_tag_to_memo()
//    {
//        //$this->withoutExceptionHandling();
//
//        $memo = $this->post('/api/memos', $this->data());
//        $tag = factory(Tag::class)->create(['user_id' => $this->user->id]);
//
//        $response = $this->patch('/api/tag/add-tag/' . $tag->slug, ['api_token' => $this->user->api_token, 'model' => $memo['data']]);
//
//        $response->assertStatus(Response::HTTP_CREATED)
//            ->assertJson( [
//                    'data' => [
//                        'memo_id' => $memo['data']['memo_id'],
//                        'tags' => [
//                            [
//                                'data' => [
//                                    'tag_id' => $tag->id,
//                                    'name' => $tag->name,
//                                    'slug' => $tag->slug,
//                                ]
//                            ]
//                        ]
//                    ]
//                ]
//            );
//
//        $response = $this->patch('/api/tag/remove-tag/' . $tag->slug, ['api_token' => $this->user->api_token, 'model' => $memo['data']]);
//
//        $response->assertStatus(Response::HTTP_CREATED)
//            ->assertJson( [
//                    'data' => [
//                        'memo_id' => $memo['data']['memo_id'],
//                        'tags' => []
//                    ]
//                ]
//            );
//    }

    private function data()
    {
        return [
            'name' => 'Test Name',
            'memo' => 'Test Memo',
        ];
    }
}
