<?php

namespace Tests\Tenant;

use App\Checklist\AnalyticsConfigured;
use App\Checklist\AtConnectLocationMapping;
use App\Checklist\CheckPrimaryDomain;
use App\Checklist\CloudflareConfigured;
use App\Checklist\CrmLiveMode;
use App\Checklist\DesignReviewPerformed;
use App\Checklist\EmailSenderConfigured;
use App\Checklist\EmailThemeConfigured;
use App\Checklist\FinanceProviderFunctional;
use App\Checklist\FormEmailRecipients;
use App\Checklist\MarketingSignOff;
use App\Checklist\MatomoConfiguredInSettings;
use App\Checklist\MatomoConfiguredInTheme;
use App\Checklist\ReservationRecipientEmails;
use App\Checklist\SeoDataImported;
use App\Checklist\SeoRedirectsImported;
use App\Checklist\ServerMonitoringCheck;
use App\Checklist\SiteAppleTouchCheck;
use App\Checklist\SiteEmailCheck;
use App\Checklist\SiteFaviconCheck;
use App\Checklist\SiteNameCheck;
use App\Checklist\SitePhoneNumberCheck;
use App\Checklist\SpecsProviderOk;
use App\Checklist\StockHasFinanceExamples;
use App\Checklist\StockOnSite;
use App\Checklist\StripeTestMode;
use App\Checklist\ThemeDomainCheck;
use App\Checklist\ThemeEnvProdMode;
use App\Checklist\UserbackDisabled;
use App\Checklist\ValuationProviderOk;
use App\Checklist\VehicleStockSpotCheck;
use App\Contracts\GoLiveChecklist;
use App\Facades\Settings;
use App\Services\CloudflareService;
use App\VehicleSpec\Services\Cap;
use Illuminate\Http\Client\Response;
use Mockery;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\Services\FinanceService;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleFinance;
use Mtc\VehicleValuation\Contracts\ValuationResponse;
use Mtc\VehicleValuation\Facades\Valuation;
use Tests\TenantTestCase;

class ChecklistTest extends TenantTestCase
{
    // =========================================================================
    // Manual Confirm Classes - These require manual confirmation
    // =========================================================================

    public function testAnalyticsConfiguredRequiresManualConfirm(): void
    {
        $check = new AnalyticsConfigured();

        $this->assertEquals('analytics_configured', $check->key());
        $this->assertEquals(GoLiveChecklist::FRONTEND, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testAtConnectLocationMappingRequiresManualConfirm(): void
    {
        $check = new AtConnectLocationMapping();

        $this->assertEquals('at_connect_location_mapping', $check->key());
        $this->assertEquals(GoLiveChecklist::DEVELOPER, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testDesignReviewPerformedRequiresManualConfirm(): void
    {
        $check = new DesignReviewPerformed();

        $this->assertEquals('design_review_performed', $check->key());
        $this->assertEquals(GoLiveChecklist::FRONTEND, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testEmailSenderConfiguredRequiresManualConfirm(): void
    {
        $check = new EmailSenderConfigured();

        $this->assertEquals('email_sender_configured', $check->key());
        $this->assertEquals(GoLiveChecklist::DOMAINS, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testEmailThemeConfiguredRequiresManualConfirm(): void
    {
        $check = new EmailThemeConfigured();

        $this->assertEquals('email_theme_configured', $check->key());
        $this->assertEquals(GoLiveChecklist::FRONTEND, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testMarketingSignOffRequiresManualConfirm(): void
    {
        $check = new MarketingSignOff();

        $this->assertEquals('marketing_sign_off', $check->key());
        $this->assertEquals(GoLiveChecklist::MARKETING, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testMatomoConfiguredInThemeRequiresManualConfirm(): void
    {
        $check = new MatomoConfiguredInTheme();

        $this->assertEquals('matomo_configured_theme', $check->key());
        $this->assertEquals(GoLiveChecklist::FRONTEND, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testServerMonitoringCheckRequiresManualConfirm(): void
    {
        $check = new ServerMonitoringCheck();

        $this->assertEquals('server_monitoring', $check->key());
        $this->assertEquals(GoLiveChecklist::DOMAINS, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testThemeEnvProdModeRequiresManualConfirm(): void
    {
        $check = new ThemeEnvProdMode();

        $this->assertEquals('theme_env_prod_mode', $check->key());
        $this->assertEquals(GoLiveChecklist::FRONTEND, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testVehicleStockSpotCheckRequiresManualConfirm(): void
    {
        $check = new VehicleStockSpotCheck();

        $this->assertEquals('vehicle_stock_spot_check', $check->key());
        $this->assertEquals(GoLiveChecklist::DEVELOPER, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testSeoDataImportedRequiresManualConfirm(): void
    {
        $check = new SeoDataImported();

        $this->assertEquals('seo_data_imported', $check->key());
        $this->assertEquals(GoLiveChecklist::MARKETING, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    public function testSeoRedirectsImportedRequiresManualConfirm(): void
    {
        $check = new SeoRedirectsImported();

        $this->assertEquals('redirects_imported', $check->key());
        $this->assertEquals(GoLiveChecklist::MARKETING, $check->category());
        $this->assertTrue($check->requiresManualConfirm());
        $this->assertFalse($check->handle());
    }

    // =========================================================================
    // Settings-based Classes
    // =========================================================================

    public function testSiteNameCheckPassesWhenNameSet(): void
    {
        Settings::update('app-name', 'Test Site Name');

        $check = new SiteNameCheck();

        $this->assertEquals('site_name', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertFalse($check->requiresManualConfirm());
        $this->assertTrue($check->handle());
    }

    public function testSiteNameCheckFailsWhenNameNotSet(): void
    {
        Settings::update('app-name', '');

        $check = new SiteNameCheck();

        $this->assertFalse($check->handle());
    }

    public function testSiteEmailCheckPassesWhenEmailSet(): void
    {
        Settings::update('app-contact-contact_email', 'test@example.com');

        $check = new SiteEmailCheck();

        $this->assertEquals('site_email', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testSiteEmailCheckFailsWhenEmailNotSet(): void
    {
        Settings::update('app-contact-contact_email', '');

        $check = new SiteEmailCheck();

        $this->assertFalse($check->handle());
    }

    public function testSitePhoneNumberCheckPassesWhenPhoneSet(): void
    {
        Settings::update('app-contact-contact_number', '01234567890');

        $check = new SitePhoneNumberCheck();

        $this->assertEquals('site_phone_number', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testSitePhoneNumberCheckFailsWhenPhoneNotSet(): void
    {
        Settings::update('app-contact-contact_number', '');

        $check = new SitePhoneNumberCheck();

        $this->assertFalse($check->handle());
    }

    public function testSiteFaviconCheckPassesWhenFaviconSet(): void
    {
        Settings::update('site-favicon', '/path/to/favicon.ico');

        $check = new SiteFaviconCheck();

        $this->assertEquals('site_favicon', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testSiteFaviconCheckFailsWhenFaviconNotSet(): void
    {
        Settings::update('site-favicon', '');

        $check = new SiteFaviconCheck();

        $this->assertFalse($check->handle());
    }

    public function testSiteAppleTouchCheckPassesWhenIconSet(): void
    {
        Settings::update('site-apple-touch-icon', '/path/to/apple-touch-icon.png');

        $check = new SiteAppleTouchCheck();

        $this->assertEquals('apple_touch', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testSiteAppleTouchCheckFailsWhenIconNotSet(): void
    {
        Settings::update('site-apple-touch-icon', '');

        $check = new SiteAppleTouchCheck();

        $this->assertFalse($check->handle());
    }

    public function testUserbackDisabledPassesWhenTokenNotSet(): void
    {
        Settings::update('tracking-userback-token', '');

        $check = new UserbackDisabled();

        $this->assertEquals('userback_disabled', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testUserbackDisabledFailsWhenTokenSet(): void
    {
        Settings::update('tracking-userback-token', 'some-token');

        $check = new UserbackDisabled();

        $this->assertFalse($check->handle());
    }

    public function testCrmLiveModePassesWhenAppNameSet(): void
    {
        Settings::update('app-name', 'Test Site');

        $check = new CrmLiveMode();

        $this->assertEquals('crm_live_mode', $check->key());
        $this->assertEquals(GoLiveChecklist::DEVELOPER, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testCrmLiveModeFailsWhenAppNameNotSet(): void
    {
        Settings::update('app-name', '');

        $check = new CrmLiveMode();

        $this->assertFalse($check->handle());
    }

    public function testFormEmailRecipientsPassesWhenAppNameSet(): void
    {
        Settings::update('app-name', 'Test Site');

        $check = new FormEmailRecipients();

        $this->assertEquals('form_email_recipients', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testFormEmailRecipientsFailsWhenAppNameNotSet(): void
    {
        Settings::update('app-name', '');

        $check = new FormEmailRecipients();

        $this->assertFalse($check->handle());
    }

    public function testStripeTestModePassesWithLiveKeys(): void
    {
        Settings::update('sales-stripe-enabled', true);
        Settings::update('sales-stripe-public_key', 'pk_live_123456');
        Settings::update('sales-stripe-private_key', 'sk_live_789012');

        $check = new StripeTestMode();

        $this->assertEquals('stripe_test_mode', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertTrue($check->isApplicable(tenant()));
        $this->assertTrue($check->handle());
    }

    public function testStripeTestModeFailsWithTestPublicKey(): void
    {
        Settings::update('sales-stripe-enabled', true);
        Settings::update('sales-stripe-public_key', 'pk_test_123456');
        Settings::update('sales-stripe-private_key', 'sk_live_789012');

        $check = new StripeTestMode();

        $this->assertFalse($check->handle());
    }

    public function testStripeTestModeFailsWithTestPrivateKey(): void
    {
        Settings::update('sales-stripe-enabled', true);
        Settings::update('sales-stripe-public_key', 'pk_live_123456');
        Settings::update('sales-stripe-private_key', 'sk_test_789012');

        $check = new StripeTestMode();

        $this->assertFalse($check->handle());
    }

    public function testStripeTestModeNotApplicableWhenDisabled(): void
    {
        Settings::update('sales-stripe-enabled', false);

        $check = new StripeTestMode();

        $this->assertFalse($check->isApplicable(tenant()));
    }

    // =========================================================================
    // Tenant Property Classes - Workflow Tests
    // =========================================================================

    public function testMatomoConfiguredInSettingsPassesWithMatomoId(): void
    {
        $tenant = tenant();
        $tenant->matomo_site_id = 123;

        $check = new MatomoConfiguredInSettings();

        $this->assertEquals('matomo_configured_settings', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertFalse($check->requiresManualConfirm());
        $this->assertTrue($check->handle());
    }

    public function testMatomoConfiguredInSettingsFailsWithoutMatomoId(): void
    {
        $tenant = tenant();
        $tenant->matomo_site_id = null;

        $check = new MatomoConfiguredInSettings();

        $this->assertFalse($check->handle());
    }

    public function testThemeDomainCheckIsApplicableWithThemeName(): void
    {
        $tenant = tenant();
        $tenant->theme_name = 'custom-theme';

        $check = new ThemeDomainCheck();

        $this->assertEquals('theme_domain', $check->key());
        $this->assertEquals(GoLiveChecklist::FRONTEND, $check->category());
        $this->assertTrue($check->isApplicable($tenant));
    }

    public function testThemeDomainCheckNotApplicableWithoutThemeName(): void
    {
        $tenant = tenant();
        $tenant->theme_name = null;

        $check = new ThemeDomainCheck();

        $this->assertFalse($check->isApplicable($tenant));
    }

    public function testThemeDomainCheckHandleAlwaysReturnsFalse(): void
    {
        $check = new ThemeDomainCheck();

        $this->assertFalse($check->handle());
    }

    // =========================================================================
    // Domain-based Classes
    // Note: CheckPrimaryDomain workflow tests require master database with
    // domains table. We test key/category here; integration tests should
    // cover the full workflow.
    // =========================================================================

    public function testCheckPrimaryDomainKeyAndCategory(): void
    {
        $check = new CheckPrimaryDomain();

        $this->assertEquals('primary_domain', $check->key());
        $this->assertEquals(GoLiveChecklist::DOMAINS, $check->category());
        $this->assertFalse($check->requiresManualConfirm());
    }

    // =========================================================================
    // Vehicle-based Classes
    // =========================================================================

    public function testStockOnSitePassesWithActiveVehicles(): void
    {
        Vehicle::factory()->create(['is_published' => true]);

        $check = new StockOnSite();

        $this->assertEquals('stock_on_site', $check->key());
        $this->assertEquals(GoLiveChecklist::DEVELOPER, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testStockOnSiteFailsWithNoVehicles(): void
    {
        Vehicle::query()->delete();

        $check = new StockOnSite();

        $this->assertFalse($check->handle());
    }

    public function testStockOnSiteFailsWithOnlyInactiveVehicles(): void
    {
        Vehicle::query()->delete();
        Vehicle::factory()->create(['is_published' => false]);

        $check = new StockOnSite();

        $this->assertFalse($check->handle());
    }

    public function testStockHasFinanceExamplesPassesWhenAllVehiclesHaveFinance(): void
    {
        Vehicle::query()->delete();
        $vehicle = Vehicle::factory()->create(['is_published' => true]);
        VehicleFinance::factory()->create(['vehicle_id' => $vehicle->id]);

        $check = new StockHasFinanceExamples();

        $this->assertEquals('stock_has_finance', $check->key());
        $this->assertEquals(GoLiveChecklist::DEVELOPER, $check->category());
        $this->assertTrue($check->handle());
    }

    public function testStockHasFinanceExamplesFailsWhenVehiclesMissingFinance(): void
    {
        Vehicle::query()->delete();
        Vehicle::factory()->create(['is_published' => true]);

        $check = new StockHasFinanceExamples();

        $this->assertFalse($check->handle());
    }

    public function testStockHasFinanceExamplesPassesWithNoActiveVehicles(): void
    {
        Vehicle::query()->delete();

        $check = new StockHasFinanceExamples();

        // No active vehicles means 0 without finance, so passes
        $this->assertTrue($check->handle());
    }

    public function testStockHasFinanceExamplesFailsWithMultipleVehiclesMissingFinance(): void
    {
        Vehicle::query()->delete();
        $vehicleWithFinance = Vehicle::factory()->create(['is_published' => true]);
        VehicleFinance::factory()->create(['vehicle_id' => $vehicleWithFinance->id]);
        Vehicle::factory()->create(['is_published' => true]); // No finance

        $check = new StockHasFinanceExamples();

        $this->assertFalse($check->handle());
    }

    // =========================================================================
    // CloudflareConfigured - Workflow Tests with Mocking
    // =========================================================================

    public function testCloudflareConfiguredKeyAndCategory(): void
    {
        $check = new CloudflareConfigured();

        $this->assertEquals('cloudflare_configured', $check->key());
        $this->assertEquals(GoLiveChecklist::DOMAINS, $check->category());
        $this->assertFalse($check->requiresManualConfirm());
    }

    public function testCloudflareConfiguredFailsWhenCloudflareNotEnabled(): void
    {
        $tenant = tenant();
        $tenant->has_cloudflare = false;

        $check = new CloudflareConfigured();
        $result = $check->handle();

        $this->assertFalse($result);
    }

    public function testCloudflareConfiguredPassesWhenClearSucceeds(): void
    {
        $tenant = tenant();
        $tenant->has_cloudflare = true;

        $mockResponse = Mockery::mock(Response::class);
        $mockResponse->shouldReceive('successful')->andReturn(true);

        $mockCloudflareService = Mockery::mock(CloudflareService::class);
        $mockCloudflareService->shouldReceive('clear')->with($tenant)->andReturn($mockResponse);

        $this->app->instance(CloudflareService::class, $mockCloudflareService);

        $check = new CloudflareConfigured();
        $result = $check->handle();

        $this->assertTrue($result);
    }

    public function testCloudflareConfiguredFailsWhenClearFails(): void
    {
        $tenant = tenant();
        $tenant->has_cloudflare = true;

        $mockResponse = Mockery::mock(Response::class);
        $mockResponse->shouldReceive('successful')->andReturn(false);
        $mockResponse->shouldReceive('status')->andReturn(403);

        $mockCloudflareService = Mockery::mock(CloudflareService::class);
        $mockCloudflareService->shouldReceive('clear')->with($tenant)->andReturn($mockResponse);

        $this->app->instance(CloudflareService::class, $mockCloudflareService);

        $check = new CloudflareConfigured();
        $result = $check->handle();

        $this->assertFalse($result);
    }

    // =========================================================================
    // FinanceProviderFunctional - Workflow Tests with Mocking
    // =========================================================================

    public function testFinanceProviderFunctionalKeyAndCategory(): void
    {
        $check = new FinanceProviderFunctional();

        $this->assertEquals('finance_provider_functional', $check->key());
        $this->assertEquals(GoLiveChecklist::DEVELOPER, $check->category());
        $this->assertFalse($check->requiresManualConfirm());
    }

    public function testFinanceProviderFunctionalNotApplicableWithoutProvider(): void
    {
        Settings::update('finance-codeweavers-enabled', false);
        Settings::update('finance-ivendi-enabled', false);
        Settings::update('finance-evolution-enabled', false);
        Settings::update('finance-santander-enabled', false);

        $check = new FinanceProviderFunctional();

        $this->assertFalse($check->isApplicable(tenant()));
    }

    public function testFinanceProviderFunctionalPassesWhenProviderReturnsSuccess(): void
    {
        Settings::update('finance-codeweavers-enabled', true);

        Vehicle::factory()->create(['is_published' => true]);

        $mockFinanceService = Mockery::mock(FinanceService::class);
        $mockFinanceService->shouldReceive('get')
            ->andReturn(['status' => 'success', 'data' => []]);

        $this->app->instance(FinanceService::class, $mockFinanceService);

        $check = new FinanceProviderFunctional();
        $result = $check->handle();

        $this->assertTrue($result);
    }

    public function testFinanceProviderFunctionalFailsWhenProviderReturnsFail(): void
    {
        Settings::update('finance-codeweavers-enabled', true);

        Vehicle::factory()->create(['is_published' => true]);

        $mockFinanceService = Mockery::mock(FinanceService::class);
        $mockFinanceService->shouldReceive('get')
            ->andReturn(['status' => 'fail', 'message' => 'Provider error']);

        $this->app->instance(FinanceService::class, $mockFinanceService);

        $check = new FinanceProviderFunctional();
        $result = $check->handle();

        $this->assertFalse($result);
    }

    // =========================================================================
    // SpecsProviderOk - Workflow Tests with Mocking
    // =========================================================================

    public function testSpecsProviderOkKeyAndCategory(): void
    {
        $check = new SpecsProviderOk();

        $this->assertEquals('specs_provider_ok', $check->key());
        $this->assertEquals(GoLiveChecklist::DEVELOPER, $check->category());
        $this->assertFalse($check->requiresManualConfirm());
    }

    public function testSpecsProviderOkNotApplicableWithoutProvider(): void
    {
        // Disable all spec providers
        Settings::update('vehicle-spec-providers-cap-enabled', false);
        Settings::update('vehicle-spec-providers-autotrader-enabled', false);
        Settings::update('vehicle-spec-providers-motor-check-enabled', false);
        Settings::update('vehicle-spec-providers-hpi-enabled', false);

        $check = new SpecsProviderOk();

        $this->assertFalse($check->isApplicable(tenant()));
    }

    public function testSpecsProviderOkIsApplicableWithCapProvider(): void
    {
        Settings::update('vehicle-spec-providers-cap-enabled', true);

        // Mock the Cap config to avoid actual API initialization
        $mockCapConfig = Mockery::mock(\App\VehicleSpec\Config\CapConfig::class);
        $this->app->instance(\App\VehicleSpec\Config\CapConfig::class, $mockCapConfig);

        $check = new SpecsProviderOk();

        // It should be applicable when Cap provider is enabled
        $this->assertTrue($check->isApplicable(tenant()));
    }

    // =========================================================================
    // ValuationProviderOk - Workflow Tests with Mocking
    // =========================================================================

    public function testValuationProviderOkKeyAndCategory(): void
    {
        $check = new ValuationProviderOk();

        $this->assertEquals('valuation_provider_ok', $check->key());
        $this->assertEquals(GoLiveChecklist::DEVELOPER, $check->category());
        $this->assertFalse($check->requiresManualConfirm());
    }

    public function testValuationProviderOkNotApplicableWithoutDriver(): void
    {
        Valuation::shouldReceive('hasEnabledDriver')->andReturn(false);

        $check = new ValuationProviderOk();

        $this->assertFalse($check->isApplicable(tenant()));
    }

    public function testValuationProviderOkIsApplicableWithDriver(): void
    {
        Valuation::shouldReceive('hasEnabledDriver')->andReturn(true);

        $check = new ValuationProviderOk();

        $this->assertTrue($check->isApplicable(tenant()));
    }

    public function testValuationProviderOkPassesWithRetailPrice(): void
    {
        config(['app.checklist_vehicles' => ['AB12CDE']]);

        $valuationResponse = new ValuationResponse(
            provider: 'test',
            registration: 'AB12CDE',
            mileage: 50000,
            vehicleType: 'car',
            retailPrice: 15000.00,
            averagePrice: null,
        );

        Valuation::shouldReceive('hasEnabledDriver')->andReturn(true);
        Valuation::shouldReceive('getVehicleVariants')
            ->with('AB12CDE', 50000)
            ->andReturn([['variant_id' => 'var123']]);
        Valuation::shouldReceive('testProvider')
            ->with('AB12CDE', 50000, 'var123')
            ->andReturn($valuationResponse);

        $check = new ValuationProviderOk();
        $result = $check->handle();

        $this->assertTrue($result);
    }

    public function testValuationProviderOkPassesWithAveragePrice(): void
    {
        config(['app.checklist_vehicles' => ['XY98ZAB']]);

        $valuationResponse = new ValuationResponse(
            provider: 'test',
            registration: 'XY98ZAB',
            mileage: 50000,
            vehicleType: 'car',
            retailPrice: null,
            averagePrice: 12000.00,
        );

        Valuation::shouldReceive('hasEnabledDriver')->andReturn(true);
        Valuation::shouldReceive('getVehicleVariants')->andReturn([]);
        Valuation::shouldReceive('testProvider')->andReturn($valuationResponse);

        $check = new ValuationProviderOk();
        $result = $check->handle();

        $this->assertTrue($result);
    }

    public function testValuationProviderOkFailsWithNoPrices(): void
    {
        config(['app.checklist_vehicles' => ['NO12PRX']]);

        $valuationResponse = new ValuationResponse(
            provider: 'test',
            registration: 'NO12PRX',
            mileage: 50000,
            vehicleType: 'car',
            retailPrice: null,
            averagePrice: null,
        );

        Valuation::shouldReceive('hasEnabledDriver')->andReturn(true);
        Valuation::shouldReceive('getVehicleVariants')->andReturn([]);
        Valuation::shouldReceive('testProvider')->andReturn($valuationResponse);

        $check = new ValuationProviderOk();
        $result = $check->handle();

        $this->assertFalse($result);
    }

    public function testValuationProviderOkFailsOnException(): void
    {
        config(['app.checklist_vehicles' => ['EX12CEP']]);

        Valuation::shouldReceive('hasEnabledDriver')->andReturn(true);
        Valuation::shouldReceive('getVehicleVariants')
            ->andThrow(new \Exception('Provider unavailable'));

        $check = new ValuationProviderOk();
        $result = $check->handle();

        $this->assertFalse($result);
    }

    // =========================================================================
    // ReservationRecipientEmails - guards against mtc addresses on live sites
    // =========================================================================

    public function testReservationRecipientEmailsKeyAndCategory(): void
    {
        $check = new ReservationRecipientEmails();

        $this->assertEquals('reservation_recipient_emails', $check->key());
        $this->assertEquals(GoLiveChecklist::CONFIGURATION, $check->category());
        $this->assertFalse($check->requiresManualConfirm());
    }

    public function testReservationRecipientEmailsPassesWhenNoRecipientsConfigured(): void
    {
        Dealership::query()->delete();
        Settings::update('reservations-admin-team-emails', '');

        $check = new ReservationRecipientEmails();

        $this->assertTrue($check->handle());
    }

    public function testReservationRecipientEmailsPassesWithOnlyClientAddresses(): void
    {
        Dealership::query()->delete();
        Settings::update('reservations-admin-team-emails', 'sales@dealer.com, admin@dealer.co.uk');

        $check = new ReservationRecipientEmails();

        $this->assertTrue($check->handle());
    }

    public function testReservationRecipientEmailsFailsWhenGlobalSettingHasMtcAddress(): void
    {
        Dealership::query()->delete();
        Settings::update('reservations-admin-team-emails', 'sales@dealer.com, dev@mtcmedia.co.uk');

        $check = new ReservationRecipientEmails();

        $this->assertFalse($check->handle());
        $this->assertStringContainsString('dev@mtcmedia.co.uk', $check->getFailureReason());
    }

    public function testReservationRecipientEmailsFailsWhenDealershipOverrideHasMtcAddress(): void
    {
        Dealership::query()->delete();
        Settings::update('reservations-admin-team-emails', 'sales@dealer.com');
        Dealership::factory()->create([
            'name' => 'Test Dealership',
            'data' => ['reservation_team_emails' => 'team@mtc.co.uk'],
        ]);

        $check = new ReservationRecipientEmails();

        $this->assertFalse($check->handle());
        $this->assertStringContainsString('team@mtc.co.uk', $check->getFailureReason());
    }

    // =========================================================================
    // GoLiveChecklist Base Class Tests
    // =========================================================================

    public function testNameReturnsTranslatedKey(): void
    {
        $check = new SiteNameCheck();

        $this->assertNotEmpty($check->name());
        $this->assertIsString($check->name());
    }

    public function testDescriptionReturnsTranslatedKey(): void
    {
        $check = new SiteNameCheck();

        $this->assertNotEmpty($check->description());
        $this->assertIsString($check->description());
    }

    public function testDefaultIsApplicableReturnsTrue(): void
    {
        $check = new SiteNameCheck();

        $this->assertTrue($check->isApplicable(tenant()));
    }

    public function testDefaultRequiresManualConfirmReturnsFalse(): void
    {
        $check = new SiteNameCheck();

        $this->assertFalse($check->requiresManualConfirm());
    }

    public function testFailureReasonIsSetOnFailure(): void
    {
        Settings::update('app-name', '');

        $check = new SiteNameCheck();
        $check->handle();

        $this->assertNotEmpty($check->getFailureReason());
    }
}
