<?php

namespace Tests;

use App\Http\Middleware\TrackRequests;
use App\LocalisationService;
use App\Middleware\InitializeTenancyByDomain;
use App\SiteRepository;
use App\Tier;
use Mtc\MercuryDataModels\Tenant;
use Stancl\Tenancy\Middleware\InitializeTenancyByRequestData;

/**
 * Handles tenant initialization for tests.
 * Real tenant (from master DB) or fake tenant (no master DB needed).
 */
trait UsesTenancy
{
    // Auto-configured based on needsMasterDatabase
    protected bool $useRealTenant = true;

    // Fake tenant configuration (when useRealTenant = false)
    protected string $fakeTenantTier = Tier::ENTERPRISE->value;
    protected string $fakeTenantDomain = 'foo.localhost';

    // Optional settings for tenant-only tests
    protected bool $useTestSettingRepository = true;

    protected function initializeTenancy(): void
    {
        if ($this->useRealTenant) {
            $this->initializeRealTenant();
        } else {
            $this->initializeFakeTenant();
            $this->disableTenantOnlyMiddlewares();
            $this->setupTenantOnlyMocks();
        }
    }

    protected function initializeRealTenant(): void
    {
        $tenant = Tenant::create([
            'tier' => 'pro',
        ]);
        $tenant->domains()->create(['domain' => 'demo.com']);
        tenancy()->initialize($tenant);
    }

    protected function initializeFakeTenant(): void
    {
        $fakeTenant = new Tenant([
            'tier' => $this->fakeTenantTier,
        ]);
        $fakeTenant->id = 'test-tenant';

        tenancy()->initialize($fakeTenant);

        if (method_exists($this, 'partialMock')) {
            $this->partialMock(SiteRepository::class, function ($mock) {
                $mock->shouldReceive('baseUrl')->andReturn('/foo.localhost');
                $mock->shouldReceive('siteDomain')->andReturn('foo.localhost');
            });

            $this->partialMock(LocalisationService::class, function ($mock) {
                $mock->shouldReceive('phonePrefix')->andReturn('+44');
            });
        }
    }

    protected function disableTenantOnlyMiddlewares(): void
    {
        $this->withoutMiddleware([
            'auth:sanctum',
            InitializeTenancyByRequestData::class,
            InitializeTenancyByDomain::class,
            TrackRequests::class,
        ]);
    }

    protected function setupTenantOnlyMocks(): void
    {
        if ($this->useTestSettingRepository) {
            $this->app->bind('site-settings', TestSettingRepository::class);
        }

        $this->app->bind('feature-flags', TestFeatureRepository::class);
    }
}
