<?php

declare(strict_types=1);

namespace Tests\Support\Imitation;

use App\Support\RussianRegions;
use Database\Seeders\PricingTierSeeder;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Tests\Concerns\SharesSupplierPdo;
use Tests\TestCase;

/**
 * Base test case for Phase 1 imitation harness tests.
 *
 * Seeds reference data (pricing_tiers, suppliers) once per test within a
 * database transaction so every test starts from a clean, known state.
 *
 * Usage:
 *   Extend this class (PHPUnit-style) or include the trait equivalents
 *   in Pest tests. Pest tests should prefer:
 *
 *     uses(DatabaseTransactions::class, SharesSupplierPdo::class);
 *     beforeEach(fn () => (new ImitationTestCase())->seedReferenceData());
 *
 * Schema dependencies (exact columns verified against db/schema.sql):
 *   pricing_tiers: id, tier_no (1..7), leads_in_tier, price_per_lead_kopecks,
 *                  is_active, effective_from, created_at, updated_at
 *   suppliers:     id, code, name, accepts_types (varchar[]), cost_rub,
 *                  channel, quality_score, is_active, sort_order, created_at
 *
 * Note: suppliers (b1/b2/b3/direct) are seeded via the initial schema
 * migration and delta-migrations — they are expected to already exist in
 * the test database. This case does NOT re-seed suppliers; it only verifies
 * that at least one supplier row with code='b1' is present and seeds
 * pricing_tiers via PricingTierSeeder.
 *
 * phone_ranges are NOT seeded globally. Tests that exercise the region-
 * resolution cascade (Россвязь lookup) should call seedPhoneRange() directly
 * for the specific range their scenario requires.
 *
 * Task 0.5 — Phase 1 Portal Client Imitation Harness.
 * Spec: docs/superpowers/specs/2026-06-03-portal-client-imitation-phase1-design.md
 */
abstract class ImitationTestCase extends TestCase
{
    use DatabaseTransactions;
    use SharesSupplierPdo;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seedReferenceData();
    }

    /**
     * Seed shared reference data required by all imitation tests.
     *
     * Called automatically from setUp(). Safe to call multiple times within a
     * transaction (PricingTierSeeder uses updateOrCreate; supplier check is
     * read-only).
     */
    public function seedReferenceData(): void
    {
        // Pricing tiers — required by LedgerService::chargeForDelivery.
        // PricingTierSeeder uses updateOrCreate so it is safe to call within
        // a DatabaseTransactions-wrapped test.
        $this->seed(PricingTierSeeder::class);

        // Tenant context: global bypass to allow cross-tenant reads during seeding.
        DB::statement("SELECT set_config('app.current_tenant_id', '0', true)");
    }

    /**
     * Seed a single phone range for Россвязь prefix lookup tests.
     *
     * Only call this when your specific test scenario exercises the Россвязь
     * branch of LeadRegionResolver (e.g. DaData degradation tests).
     *
     * @param  int  $defCode  DEF-code prefix (e.g. 999).
     * @param  int  $from  Lower bound of number range (e.g. 0).
     * @param  int  $to  Upper bound of number range (e.g. 99999).
     * @param  int  $subjectCode  Subject code (1..89, порядковый, НЕ ГИБДД).
     *                            Use App\Support\RussianRegions::nameToCode() for lookup.
     */
    protected function seedPhoneRange(
        int $defCode,
        int $from,
        int $to,
        int $subjectCode,
    ): void {
        // Anchor phone_ranges_imports row first — phone_ranges.import_id is a
        // required FK (migration 2026_05_31_100000). F1 fix: the previous version
        // used non-existent columns (range_from/range_to/region_name) and omitted
        // import_id, so every Россвязь-branch test that called it failed at runtime.
        $importId = DB::table('phone_ranges_imports')->insertGetId([
            'imported_at' => now(),
            'source_url' => 'test://rossvyaz',
            'rows_inserted' => 1,
            'rows_updated' => 0,
            'checksum_sha256' => str_repeat('0', 64),
            'status' => 'completed',
            'completed_at' => now(),
        ]);

        DB::table('phone_ranges')->insert([
            'def_code' => $defCode,
            'from_num' => $from,
            'to_num' => $to,
            'operator' => 'test-operator',
            'region' => RussianRegions::CODE_TO_NAME[$subjectCode] ?? 'test-region',
            'region_normalized' => null,
            'subject_code' => $subjectCode,
            'imported_at' => now(),
            'import_id' => $importId,
        ]);
    }
}
