<?php

declare(strict_types=1);

namespace Apexl\Tests\Core\FeatureTests\Relations;

use apexl\entityCore\collections\EntityCollection;
use app\module\newtonsTrailers\Entity\Company;
use app\module\newtonsTrailers\Entity\EmailLog;
use app\module\newtonsTrailers\Entity\VehicleTrailer;
use app\module\newtonsTrailers\Interface\HasEntityLinksInterface;
use PHPUnit\Framework\Attributes\Test;

final class LinkedEntityTest extends AbstractRelationTest
{
    #[Test]
    public function findsSingularLinkedEntities()
    {
        $emailLog = EmailLog::factory()->create();

        $company1 = Company::factory()->create();
        $company2 = Company::factory()->create();

        $vehicle_trailer1 = VehicleTrailer::factory()->create();
        $vehicle_trailer2 = VehicleTrailer::factory()->create();

        self::$db->insert(HasEntityLinksInterface::TABLE__LINKS)
            ->fields([
                'local_entity' => EmailLog::class,
                'local_entity_id' => $emailLog->id,
                'remote_entity' => Company::class,
                'remote_entity_id' => $company1->id,
            ])->execute();


        self::$db->insert(HasEntityLinksInterface::TABLE__LINKS)
            ->fields([
                'local_entity' => EmailLog::class,
                'local_entity_id' => $emailLog->id,
                'remote_entity' => VehicleTrailer::class,
                'remote_entity_id' => $vehicle_trailer2->id,
            ])->execute();

        $found = $emailLog->find($emailLog->id, fields: [
            'linked_company.id',
            'linked_vehicle_trailer.id',
        ]);

        $this->assertInstanceOf(Company::class, $found->linked_company);
        $this->assertEquals($found->linked_company->id, $company1->id);

        $this->assertInstanceOf(VehicleTrailer::class, $found->linked_vehicle_trailer);
        $this->assertEquals($found->linked_vehicle_trailer->id, $vehicle_trailer2->id);
    }

    #[Test]
    public function updatesLinkedEntities()
    {
        $emailLog = EmailLog::factory()->create();

        $company1 = Company::factory()->create();
        $company2 = Company::factory()->create();

        $vehicle_trailer1 = VehicleTrailer::factory()->create();

        $emailLog->linked_company()->set($company2->id);
        $emailLog->linked_vehicle_trailer()->set($vehicle_trailer1->id);

        $found = $emailLog->find($emailLog->id, fields: [
            'linked_company.id',
            'linked_vehicle_trailer.id',
        ]);

        $this->assertInstanceOf(Company::class, $found->linked_company);
        $this->assertEquals($found->linked_company->id, $company2->id);

        $this->assertInstanceOf(VehicleTrailer::class, $found->linked_vehicle_trailer);
        $this->assertEquals($found->linked_vehicle_trailer->id, $vehicle_trailer1->id);
    }

    #[Test]
    public function getsAllLinkedEntities()
    {
        $emailLog = EmailLog::factory()->create();

        $company1 = Company::factory()->create();
        $company2 = Company::factory()->create();

        $vehicle_trailer1 = VehicleTrailer::factory()->create();

        $emailLog->linked_company()->add($company1->id);
        $emailLog->linked_vehicle_trailer()->add($vehicle_trailer1->id);

        $found = EmailLog::find($emailLog->id, fields: [
            'linked_company.id',
            'linked_vehicle_trailer.id',
        ]);

        $links = $found->allLinkedEntities();

        $this->assertInstanceOf(EntityCollection::class, $links);
        $this->assertCount(2, $links);
    }
}
