<?php

namespace Tests\Tenant;

use App\Facades\Settings;
use App\Jobs\RunScheduledSyncTask;
use App\ScheduledTasks\ActionRegistry;
use App\ScheduledTasks\Actions\RunStockSyncAction;
use App\ScheduledTasks\TaskRunContext;
use Database\Seeders\Tenant\StockSyncSystemTaskSeeder;
use Illuminate\Support\Facades\Bus;
use Mtc\MercuryDataModels\ScheduledTask;
use Mtc\MercuryDataModels\ScheduledTaskRun;
use Tests\TenantTestCase;

class StockSyncSystemTaskTest extends TenantTestCase
{
    public function testSeederCreatesAReadOnlySystemTaskFromTheFrequencySetting(): void
    {
        Settings::update('stock-sync-frequency', 'twice-daily');

        (new StockSyncSystemTaskSeeder())->run();

        $task = ScheduledTask::query()->where('name', 'Stock sync')->first();
        $this->assertNotNull($task);
        $this->assertEquals(ScheduledTask::MANAGED_BY_SYSTEM, $task->managed_by);
        $this->assertEquals(['09:00', '17:00'], collect($task->schedule_rules)->pluck('time')->toArray());
        $this->assertEquals('stock-sync', $task->actions->first()->action_type);
    }

    public function testSeederIsIdempotent(): void
    {
        (new StockSyncSystemTaskSeeder())->run();
        (new StockSyncSystemTaskSeeder())->run();

        $this->assertEquals(
            1,
            ScheduledTask::query()->where('name', 'Stock sync')->count()
        );
        $this->assertEquals(
            1,
            ScheduledTask::query()->where('name', 'Stock sync')->first()->actions()->count()
        );
    }

    public function testSeederRenamesAnExistingSystemTaskInPlace(): void
    {
        $existing = ScheduledTask::factory()->create([
            'name' => 'AutoTrader stock sync',
            'managed_by' => ScheduledTask::MANAGED_BY_SYSTEM,
        ]);
        $existing->actions()->create(['order' => 1, 'action_type' => 'stock-sync', 'config' => []]);

        (new StockSyncSystemTaskSeeder())->run();

        $this->assertEquals(1, ScheduledTask::query()->where('managed_by', ScheduledTask::MANAGED_BY_SYSTEM)->count());
        $this->assertEquals('Stock sync', $existing->fresh()->name);
    }

    public function testEveryHourFrequencyMapsToTheWorkingWindow(): void
    {
        Settings::update('stock-sync-frequency', 'every-hour');

        (new StockSyncSystemTaskSeeder())->run();

        $task = ScheduledTask::query()->where('name', 'Stock sync')->first();
        $times = collect($task->schedule_rules)->pluck('time')->values()->toArray();
        $this->assertEquals('06:00', $times[0]);
        $this->assertEquals('22:00', end($times));
        $this->assertCount(17, $times);
        $this->assertTrue(collect($task->schedule_rules)->every(fn ($r) => $r['frequency'] === 'daily'));
    }

    public function testStockSyncActionIsNotUserSelectable(): void
    {
        $selectableKeys = app(ActionRegistry::class)->selectable()->keys();

        $this->assertFalse($selectableKeys->contains('stock-sync'));
        $this->assertTrue($selectableKeys->contains('export-map'));
    }

    public function testActionDispatchesTheStockSyncJob(): void
    {
        Bus::fake();

        $run = ScheduledTaskRun::factory()->create();
        $result = app(RunStockSyncAction::class)->execute([], new TaskRunContext($run));

        $this->assertEquals('completed', $result->status);
        Bus::assertDispatchedSync(RunScheduledSyncTask::class);
    }
}
