<?php
namespace Tests\Unit\admin\Controllers;

use PHPUnit\Framework\TestCase;
use admin\Controllers\IntegrationsController;
use Domain\Integrations\IntegrationsRepository;

class IntegrationsControllerTest extends TestCase
{
    private $repository;
    private IntegrationsController $controller;

    protected function setUp(): void
    {
        $this->repository = $this->createMock(IntegrationsRepository::class);
        $this->controller = new IntegrationsController($this->repository);
    }

    public function testConstructorAcceptsDependencies(): void
    {
        $controller = new IntegrationsController($this->repository);
        $this->assertInstanceOf(IntegrationsController::class, $controller);
    }

    public function testConstructorRequiresRepository(): void
    {
        $reflection = new \ReflectionClass(IntegrationsController::class);
        $constructor = $reflection->getConstructor();
        $params = $constructor->getParameters();

        $this->assertCount(1, $params);
        $this->assertEquals(
            'Domain\Integrations\IntegrationsRepository',
            $params[0]->getType()->getName()
        );
    }

    public function testHasAllApiloSettingsMethods(): void
    {
        $methods = [
            'apilo_settings',
            'apilo_settings_save',
            'apilo_authorization',
        ];

        foreach ($methods as $method) {
            $this->assertTrue(
                method_exists($this->controller, $method),
                "Method $method does not exist"
            );
        }
    }

    public function testHasAllApiloDataFetchMethods(): void
    {
        $methods = [
            'get_platform_list',
            'get_status_types_list',
            'get_carrier_account_list',
            'get_payment_types_list',
        ];

        foreach ($methods as $method) {
            $this->assertTrue(
                method_exists($this->controller, $method),
                "Method $method does not exist"
            );
        }
    }

    public function testHasAllApiloProductMethods(): void
    {
        $methods = [
            'apilo_create_product',
            'apilo_product_search',
            'apilo_product_select_save',
            'apilo_product_select_delete',
        ];

        foreach ($methods as $method) {
            $this->assertTrue(
                method_exists($this->controller, $method),
                "Method $method does not exist"
            );
        }
    }

    public function testHasAllShopproMethods(): void
    {
        $methods = [
            'shoppro_settings',
            'shoppro_settings_save',
            'shoppro_product_import',
        ];

        foreach ($methods as $method) {
            $this->assertTrue(
                method_exists($this->controller, $method),
                "Method $method does not exist"
            );
        }
    }

    public function testApiloSettingsReturnsString(): void
    {
        $reflection = new \ReflectionClass($this->controller);
        $this->assertEquals('string', (string) $reflection->getMethod('apilo_settings')->getReturnType());
    }

    public function testShopproSettingsReturnsString(): void
    {
        $reflection = new \ReflectionClass($this->controller);
        $this->assertEquals('string', (string) $reflection->getMethod('shoppro_settings')->getReturnType());
    }

    public function testVoidReturnTypes(): void
    {
        $reflection = new \ReflectionClass($this->controller);

        $voidMethods = [
            'apilo_settings_save',
            'apilo_authorization',
            'get_platform_list',
            'get_status_types_list',
            'get_carrier_account_list',
            'get_payment_types_list',
            'apilo_create_product',
            'apilo_product_search',
            'apilo_product_select_save',
            'apilo_product_select_delete',
            'shoppro_settings_save',
            'shoppro_product_import',
        ];

        foreach ($voidMethods as $method) {
            $this->assertEquals(
                'void',
                (string) $reflection->getMethod($method)->getReturnType(),
                "Method $method should return void"
            );
        }
    }

    public function testDoesNotHaveSellasistMethods(): void
    {
        $reflection = new \ReflectionClass($this->controller);
        $methods = array_map(fn($m) => $m->getName(), $reflection->getMethods());

        foreach ($methods as $method) {
            $this->assertStringNotContainsString(
                'sellasist',
                strtolower($method),
                "Controller should not have sellasist method: $method"
            );
        }
    }

    public function testDoesNotHaveBaselinkerMethods(): void
    {
        $reflection = new \ReflectionClass($this->controller);
        $methods = array_map(fn($m) => $m->getName(), $reflection->getMethods());

        foreach ($methods as $method) {
            $this->assertStringNotContainsString(
                'baselinker',
                strtolower($method),
                "Controller should not have baselinker method: $method"
            );
        }
    }
}
