<?php

namespace App\Tests\Unit\Service\OnChange\Organization;

use App\Entity\Billing\BillingSetting;
use App\Entity\Organization\Organization;
use App\Entity\Organization\Parameters;
use App\Enum\Organization\LegalEnum;
use App\Service\OnChange\OnChangeContext;
use App\Service\OnChange\Organization\OnOrganizationChange;
use PHPUnit\Framework\TestCase;

class OnOrganizationChangeTest extends TestCase
{
    /**
     * @see OnOrganizationChange::beforeChange()
     */
    public function testBeforeChangeNoChange(): void
    {
        $onOrganizationChange =  $this
            ->getMockBuilder(OnOrganizationChange::class)
            ->setMethodsExcept(['beforeChange'])
            ->disableOriginalConstructor()
            ->getMock();

        $onOrganizationChange
            ->expects(self::never())
            ->method('onLegalStatusChange')
            ->willReturnSelf();

        $previousOrganization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
        $previousOrganization->expects(self::once())->method('getLegalStatus')->willReturn('ASSOCIATION_LAW_1901');

        $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
        $context->method('previousData')->willReturn($previousOrganization);

        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
        $organization->expects(self::once())->method('getLegalStatus')->willReturn('ASSOCIATION_LAW_1901');

        $onOrganizationChange->beforeChange($organization, $context);
    }

    /**
     * @see OnOrganizationChange::beforeChange()
     */
    public function testBeforeChangeLegalStatusChanged(): void
    {
        $onOrganizationChange =  $this
            ->getMockBuilder(OnOrganizationChange::class)
            ->setMethodsExcept(['beforeChange'])
            ->disableOriginalConstructor()
            ->getMock();

        $onOrganizationChange
            ->expects(self::once())
            ->method('onLegalStatusChange')
            ->willReturnSelf();

        $previousOrganization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
        $previousOrganization->expects(self::once())->method('getLegalStatus')->willReturn('ASSOCIATION_LAW_1901');

        $context = $this->getMockBuilder(OnChangeContext::class)->disableOriginalConstructor()->getMock();
        $context->method('previousData')->willReturn($previousOrganization);

        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
        $organization->expects(self::once())->method('getLegalStatus')->willReturn('LOCAL_AUTHORITY');

        $onOrganizationChange->beforeChange($organization, $context);
    }

    /**
     * @see OnOrganizationChange::onLegalStatusChange()
     */
    public function testOnLegalStatusChangeToAsso(): void
    {

        $onOrganizationChange =  $this
            ->getMockBuilder(OnOrganizationChange::class)
            ->setMethodsExcept(['onLegalStatusChange'])
            ->disableOriginalConstructor()
            ->getMock();

        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
        $organization->method('getLegalStatus')->willReturn(LegalEnum::ASSOCIATION_LAW_1901()->getValue());

        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
        $organization->method('getParameters')->willReturn($parameters);

        $billingSettings = $this->getMockBuilder(BillingSetting::class)->disableOriginalConstructor()->getMock();
        $organization->method('getBillingSetting')->willReturn($billingSettings);

        $parameters->expects(self::never())->method('setShowAdherentList');
        $billingSettings->expects(self::never())->method('setApplyVat');

        $onOrganizationChange->onLegalStatusChange($organization);
    }

    /**
     * @see OnOrganizationChange::onLegalStatusChange()
     */
    public function testOnLegalStatusChangeToSociety(): void
    {

        $onOrganizationChange =  $this
            ->getMockBuilder(OnOrganizationChange::class)
            ->setMethodsExcept(['onLegalStatusChange'])
            ->disableOriginalConstructor()
            ->getMock();

        $organization = $this->getMockBuilder(Organization::class)->disableOriginalConstructor()->getMock();
        $organization->method('getLegalStatus')->willReturn(LegalEnum::COMMERCIAL_SOCIETY()->getValue());

        $parameters = $this->getMockBuilder(Parameters::class)->disableOriginalConstructor()->getMock();
        $organization->method('getParameters')->willReturn($parameters);

        $billingSettings = $this->getMockBuilder(BillingSetting::class)->disableOriginalConstructor()->getMock();
        $organization->method('getBillingSetting')->willReturn($billingSettings);

        $parameters->expects(self::once())->method('setShowAdherentList')->with(false);
        $billingSettings->expects(self::once())->method('setApplyVat')->with(true);

        $onOrganizationChange->onLegalStatusChange($organization);
    }
}
