<?php

namespace Tests\Feature\Audit;

use App\Mail\WorkOrderReadyMail;
use App\Models\Central\Company;
use App\Models\Central\Plan;
use App\Models\Tenant\Client;
use App\Models\Tenant\Vehicle;
use App\Models\Tenant\WorkOrder;
use App\Services\NotificationDispatcher;
use App\Tenancy\TenantManager;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;

/**
 * The multi-channel fallback is the most subtle integration in the system:
 * Telegram wins if the client has a chat_id + tenant bot configured; otherwise
 * fall back to email. If neither, do nothing. Tenant flag must respect both.
 */
class NotificationFallbackTest extends TestCase
{
    use RefreshDatabase;

    public function test_telegram_wins_when_chat_id_present(): void
    {
        $ctx = $this->bootTenantWithBot();
        $client = $this->makeClient(['telegram_chat_id' => '12345', 'email' => 'x@example.com']);
        $wo = $this->makeReadyWo($client, $ctx);

        Mail::fake();
        Http::fake(['api.telegram.org/*' => Http::response(['ok' => true])]);

        $ok = app(NotificationDispatcher::class)->workOrderReady($wo);

        $this->assertTrue($ok);
        Http::assertSent(fn ($r) => str_contains($r->url(), 'sendMessage'));
        Mail::assertNotSent(WorkOrderReadyMail::class);
    }

    public function test_falls_back_to_email_when_no_chat_id(): void
    {
        $ctx = $this->bootTenantWithBot();
        $client = $this->makeClient(['email' => 'x@example.com']);
        $wo = $this->makeReadyWo($client, $ctx);

        Mail::fake();
        Http::fake();
        $ok = app(NotificationDispatcher::class)->workOrderReady($wo);

        $this->assertTrue($ok);
        Mail::assertSent(WorkOrderReadyMail::class);
        Http::assertNothingSent();
    }

    public function test_returns_false_when_no_channel_available(): void
    {
        $ctx = $this->bootTenantWithBot();
        $client = $this->makeClient([]);  // no email, no chat_id
        $wo = $this->makeReadyWo($client, $ctx);

        Mail::fake();
        $ok = app(NotificationDispatcher::class)->workOrderReady($wo);

        $this->assertFalse($ok);
        Mail::assertNothingSent();
    }

    public function test_tenant_disable_flag_overrides_channels(): void
    {
        $ctx = $this->bootTenantWithBot();
        // Disable the wo_ready notification globally for this tenant.
        $ctx['company']->update([
            'settings' => array_merge_recursive((array) $ctx['company']->settings, [
                'notify' => ['wo_ready' => false],
            ]),
        ]);

        $client = $this->makeClient(['email' => 'x@example.com']);
        $wo = $this->makeReadyWo($client, $ctx);

        Mail::fake();
        Http::fake();
        $ok = app(NotificationDispatcher::class)->workOrderReady($wo);

        $this->assertFalse($ok);
        Mail::assertNothingSent();
    }

    private function bootTenantWithBot(): array
    {
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $company = Company::create([
            'plan_id' => $plan->id, 'slug' => 'nf-' . uniqid(),
            'name' => 'Notify', 'status' => 'active',
            'settings' => ['telegram' => ['bot_token' => 'FAKE:TOKEN']],
        ]);
        app(TenantManager::class)->setCurrent($company);
        return compact('company');
    }

    private function makeClient(array $attrs): Client
    {
        return Client::create(array_merge([
            'name' => 'C', 'phone' => '+3737' . random_int(1000000, 9999999),
            'type' => 'individual', 'status' => 'active',
        ], $attrs));
    }

    private function makeReadyWo(Client $client, array $ctx): WorkOrder
    {
        $vehicle = Vehicle::create(['client_id' => $client->id, 'make' => 'X', 'model' => 'Y', 'plate' => 'NF' . random_int(100, 999)]);
        return WorkOrder::create([
            'number' => WorkOrder::generateNumber($ctx['company']->id),
            'client_id' => $client->id, 'vehicle_id' => $vehicle->id,
            'opened_at' => today(), 'status' => 'ready', 'total' => 500,
        ]);
    }
}
