<?php

namespace Tests\Feature;

use App\Models\Appointment;
use App\Models\Dentist;
use App\Models\Patient;
use App\Models\ReviewFeedback;
use App\Models\Tenant;
use App\Support\Tenancy;
use Carbon\CarbonImmutable;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\URL;
use Tests\TestCase;

class RecallAndReviewTest extends TestCase
{
    use RefreshDatabase;

    protected Tenant $tenant;
    protected string $base;

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

        $this->tenant = Tenant::create([
            'name' => 'Smile', 'slug' => 'smile',
            'google_review_url' => 'https://g.page/smile/review',
        ]);
        $this->base = 'http://smile.'.config('tenancy.central_domain');
    }

    protected function appt(): Appointment
    {
        app(Tenancy::class)->set($this->tenant);
        $dentist = Dentist::factory()->create();
        $patient = Patient::factory()->create();
        $appt = Appointment::create([
            'tenant_id' => $this->tenant->id, 'dentist_id' => $dentist->id, 'patient_id' => $patient->id,
            'starts_at' => now()->subDay(), 'ends_at' => now()->subDay()->addMinutes(30),
            'status' => 'completed', 'source' => 'reception',
        ]);
        app(Tenancy::class)->forget();

        return $appt;
    }

    public function test_high_rating_redirects_to_google(): void
    {
        $appt = $this->appt();
        $url = URL::signedRoute('public.review', ['tenant_slug' => 'smile', 'appointment' => $appt->uuid]);

        $this->post($url, ['rating' => 5])
            ->assertRedirect('https://g.page/smile/review');

        app(Tenancy::class)->set($this->tenant);
        $this->assertDatabaseHas('review_feedback', ['rating' => 5, 'appointment_id' => $appt->id]);
    }

    public function test_low_rating_is_captured_internally(): void
    {
        $appt = $this->appt();
        $url = URL::signedRoute('public.review', ['tenant_slug' => 'smile', 'appointment' => $appt->uuid]);

        $this->post($url, ['rating' => 2, 'comment' => 'Long wait'])
            ->assertOk()->assertSee(__('Thank you!'));

        app(Tenancy::class)->set($this->tenant);
        $fb = ReviewFeedback::firstOrFail();
        $this->assertSame(2, $fb->rating);
        $this->assertSame('Long wait', $fb->comment);
    }

    public function test_review_link_requires_valid_signature(): void
    {
        $appt = $this->appt();
        $this->get($this->base.'/review/'.$appt->uuid)->assertForbidden();
    }

    public function test_set_next_visit_creates_recall_on_completion(): void
    {
        app(Tenancy::class)->set($this->tenant);
        $this->tenant->subscription()->create([
            'plan_id' => \App\Models\Plan::first()->id, 'status' => 'trialing',
            'starts_at' => now(), 'current_period_ends_at' => now()->addDays(14),
        ]);
        $dentist = Dentist::factory()->create();
        $patient = Patient::factory()->create();
        $appt = Appointment::create([
            'tenant_id' => $this->tenant->id, 'dentist_id' => $dentist->id, 'patient_id' => $patient->id,
            'starts_at' => now()->addHour(), 'ends_at' => now()->addHour()->addMinutes(30),
            'status' => 'checked_in', 'source' => 'reception',
        ]);
        $owner = \App\Models\User::withoutEvents(fn () => \App\Models\User::create([
            'tenant_id' => $this->tenant->id, 'name' => 'O', 'email' => 'o@x.com', 'password' => 'password123',
        ]));
        $owner->assignRole('clinic_owner');
        app(Tenancy::class)->forget();

        $this->actingAs($owner)
            ->patch($this->base.'/appointments/'.$appt->id.'/status', [
                'status' => 'completed',
                'recall_months' => 6,
                'recall_reason' => 'Crown follow-up',
            ])->assertRedirect();

        app(Tenancy::class)->set($this->tenant);
        $this->assertDatabaseHas('recalls', [
            'patient_id' => $patient->id, 'reason' => 'Crown follow-up', 'status' => 'scheduled',
        ]);
    }
}
