<?php

namespace Tests\Feature\Modules\Segments\ControllersLogic;

use App\Classes\Modules\Segments\ControllersLogic\UpdateSegmentLogic;
use App\Classes\Modules\Segments\DataTransferObjects\SegmentObject;
use App\Classes\Modules\Segments\Services\FetchesSegment;
use App\Classes\Modules\Segments\Services\UpdatesSegment;
use App\Classes\Modules\Segments\Standards\Rules\CanUpdateSegment;
use App\Models\Segment;
use App\Models\User;
use Illuminate\Http\Request;
use PHPUnit\Framework\Attributes\Group;
use Tests\TestCase;
use Mockery;

#[Group('feature')]
#[Group('segments')]
#[Group('logic')]
#[Group('ok_to_run')]
class UpdateSegmentLogicTest extends TestCase
{

    // use DatabaseTransactions;

    /**
     * Test UpdateSegmentLogic execution.
     *
     * @return void
     */
    public function test_update_segment_logic_execution()
    {
        // A R R A N G E
        $email = 'test_update_segment_logic_execution@example.com';
        $user = User::where('email', $email)->first();
        if (!$user) {
            $user = new User();
            $user->name = 'test_update_segment_logic_execution';
            $user->email = $email;
            $user->type = 1;
            $user->password = bcrypt('password');
            $user->save();
        }
        $this->actingAs($user);

        $segment = new Segment();
        $segment->id = 1;
        $segment->name = 'test_update_segment_logic_execution';

        // Mock FetchesSegment
        $fetchesSegment = Mockery::mock(FetchesSegment::class);
        $fetchesSegment->shouldReceive('execute')
            ->once()
            ->with(['id' => 1])
            ->andReturn($segment);

        // Mock CanUpdateSegment
        $canUpdateSegment = Mockery::mock(CanUpdateSegment::class);
        $canUpdateSegment->shouldReceive('passes')
            ->once()
            ->with(Mockery::type(SegmentObject::class))
            ->andReturn(true);

        // Mock UpdatesSegment
        $updatesSegment = Mockery::mock(UpdatesSegment::class);
        $updatesSegment->shouldReceive('execute')
            ->once()
            ->with($segment, Mockery::type(SegmentObject::class))
            ->andReturn($segment);

        $logic = new UpdateSegmentLogic($canUpdateSegment, $updatesSegment, $fetchesSegment);

        $request = Request::create('/api/segments/1', 'PUT', [
            'name' => 'test_update_segment_logic_execution_NEW'
        ]);
        $request->setRouteResolver(function () {
            $route = Mockery::mock(\Illuminate\Routing\Route::class);
            $route->shouldReceive('parameter')->with('id', null)->andReturn(1);
            return $route;
        });

        // A C T
        $response = $logic->execute($request);

        // A S S E R T
        $this->assertEquals(200, $response->getStatusCode());
        $data = $response->getData(true);
        $this->assertEquals('Updated Segment Successful', $data['title']);
    }

    protected function tearDown(): void
    {
        parent::tearDown();
        Mockery::close();
    }
}
