<?php

declare(strict_types=1);

namespace Apexl\Tests\Core\FeatureTests\Relations;

use app\module\newtonsTrailers\Entity\Company;
use app\module\newtonsTrailers\Entity\Contact;
use app\module\newtonsTrailers\Enum\CompanyContactType;
use PHPUnit\Framework\Attributes\Test;

final class HasOneViaPivotTest extends AbstractRelationTest
{
    #[Test]
    public function fetch(): void
    {
        $company = Company::factory()->create();
        $contact = Contact::factory()->create();

        self::$db->executeSql(
            'INSERT INTO contacts__companies (contact_id, company_id, type, weight) VALUES (?, ?, ?, ?)',
            [
                $contact->id,
                $company->id,
                CompanyContactType::MAIN->value,
                1,
            ]
        );

        $found = Contact::find(
            id: $contact->id,
            fields: [
                'company_main.id',
            ],
        );

        $this->assertInstanceOf(Company::class, $found->company_main);
        $this->assertEquals($company->id, $found->company_main->id);
    }

    #[Test]
    public function notSet(): void
    {
        $company = Company::factory()->create();

        $this->assertNull($company->beating_heart);
    }

    #[Test]
    public function replace(): void
    {
        $company1 = Company::factory()->create();
        $company2 = Company::factory()->create();
        $contact = Contact::factory()->create();

        $contact->relation('company_main')->set($company1->id);

        $this->assertInstanceOf(Company::class, $contact->company_main);
        $this->assertEquals($company1->id, $contact->company_main->id);

        $contact->relation('company_main')->set($company2->id);

        $this->assertInstanceOf(Company::class, $contact->company_main);
        $this->assertEquals($company2->id, $contact->company_main->id);

        $found = Contact::find(
            id: $contact->id,
            fields: [
                'company_main.id',
            ],
        );

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

    #[Test]
    public function setEntity(): void
    {
        $company = Company::factory()->create();
        $contact = Contact::factory()->create();

        $contact->company_main()->set($company);

        $this->assertInstanceOf(Company::class, $contact->company_main);
        $this->assertEquals($company->id, $contact->company_main->id);

        $found = Contact::find(
            id: $contact->id,
            fields: [
                'company_main.id',
            ],
        );

        $this->assertInstanceOf(Company::class, $found->company_main);
        $this->assertEquals($company->id, $found->company_main->id);
    }

    #[Test]
    public function setEntityId(): void
    {
        $company1 = Company::factory()->create();
        $company2 = Company::factory()->create();
        $contact = Contact::factory()->create();

        $contact->relation('company_main')->set($company1->id);
        $contact->relation('company_parts')->set($company2->id);

        $this->assertInstanceOf(Company::class, $contact->company_main);
        $this->assertEquals($company1->id, $contact->company_main->id);

        $found = Contact::find(
            id: $contact->id,
            fields: [
                'company_main.id',
                'company_parts.abbreviated_name',
            ],
        );

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

    #[Test]
    public function clear(): void
    {
        $company = Company::factory()->create();
        $contact = Contact::factory()->create();

        self::$db->executeSql(
            'INSERT INTO contacts__companies (contact_id, company_id, type, weight) VALUES (?, ?, ?, ?)',
            [
                $contact->id,
                $company->id,
                CompanyContactType::MAIN->value,
                1,
            ]
        );

        $contact->relation('company_main')->clear();

        $found = Contact::find(
            id: $contact->id,
            fields: [
                'company_main.id',
            ],
        );

        $this->assertNull($found->company_main);

    }

}