<?php

namespace Tests\Feature;

use App\Domain\Facility\Models\Facility;
use App\Domain\Facility\Services\FacilityService;
use App\Domain\Shared\Models\Academy;
use App\Domain\Training\Models\Activity;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;

/**
 * Recording which sports a facility can host.
 *
 * `facility_activities.academy_id` is NOT NULL and the pivot has no model to
 * stamp it, so `$facility->activities()->sync([...])` — which is what BOTH write
 * paths use, FacilityService::create() and FacilityForm::save() — threw a
 * not-null violation on every tenant. Ticking a sport on a facility had never
 * once worked, which is why no facility anywhere has a row here and why the
 * schedule builder still offers every group in the academy for every pitch:
 * `2026_08_30_000003` treats "no rows" as "hosts anything".
 *
 * Nothing pinned it because the failure needs Postgres to show up at all — the
 * default sqlite suite has no such table.
 *
 *   DB_CONNECTION=pgsql DB_HOST=127.0.0.1 DB_DATABASE=oc_sport_test \
 *     ./vendor/bin/phpunit --filter FacilityActivityPivotTest
 */
class FacilityActivityPivotTest extends TestCase
{
    private ?Academy $academy = null;

    protected function setUp(): void
    {
        parent::setUp();

        if (config('database.default') !== 'pgsql') {
            $this->markTestSkipped('Needs a restored Postgres tenant.');
        }

        if (! $this->academy = Academy::first()) {
            $this->markTestSkipped('No academy in the restored tenant.');
        }

        app()->instance('current_academy', $this->academy);
        DB::beginTransaction();
    }

    protected function tearDown(): void
    {
        DB::rollBack();
        parent::tearDown();
    }

    public function test_a_facility_can_record_the_sport_it_hosts(): void
    {
        $activity = Activity::first();
        $actor = User::first();

        if (! $activity || ! $actor) {
            $this->markTestSkipped('Tenant has no activity or user to build on.');
        }

        $facility = app(FacilityService::class)->create([
            'academy_id' => $this->academy->id,
            'branch_id'  => $this->branchId(),
            'code' => 'PIVOTTEST', 'name' => 'Pivot probe', 'name_ar' => 'اختبار',
            'type' => 'field', 'status' => 'active',
            'operating_start' => '09:00', 'operating_end' => '23:00',
        ], $actor, [$activity->id], ['rows' => 1, 'columns' => 1]);

        $pivot = DB::table('facility_activities')->where('facility_id', $facility->id)->first();

        $this->assertNotNull($pivot, 'sync() wrote no pivot row');
        $this->assertSame(
            (int) $this->academy->id,
            (int) $pivot->academy_id,
            'the pivot must carry the academy — the column is NOT NULL',
        );
        $this->assertSame(1, $facility->activities()->count(), 'the relation must read its own row back');
    }

    public function test_resyncing_does_not_orphan_the_academy(): void
    {
        $activities = Activity::limit(2)->get();
        $actor = User::first();

        if ($activities->count() < 1 || ! $actor) {
            $this->markTestSkipped('Tenant has no activity or user to build on.');
        }

        $facility = app(FacilityService::class)->create([
            'academy_id' => $this->academy->id,
            'branch_id'  => $this->branchId(),
            'code' => 'PIVOTTEST2', 'name' => 'Pivot probe 2', 'name_ar' => 'اختبار ٢',
            'type' => 'field', 'status' => 'active',
        ], $actor, [$activities->first()->id], []);

        // The edit path — FacilityForm::save() calls sync() directly on the model.
        $facility->activities()->sync($activities->pluck('id')->all());

        $rows = DB::table('facility_activities')->where('facility_id', $facility->id)->get();

        $this->assertCount($activities->count(), $rows);
        foreach ($rows as $row) {
            $this->assertSame((int) $this->academy->id, (int) $row->academy_id);
        }
    }

    private function branchId(): int
    {
        return (int) DB::table('branches')
            ->where('academy_id', $this->academy->id)
            ->whereNull('deleted_at')
            ->orderBy('id')
            ->value('id');
    }
}
