<?php

namespace Tests\Feature;

use App\Enums\AppointmentStatus;
use App\Enums\InvoiceStatus;
use App\Enums\PaymentStatus;
use App\Enums\ReminderStatus;
use App\Enums\UserRole;
use App\Models\Appointment;
use App\Models\Business;
use App\Models\Customer;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\ReminderLog;
use App\Models\ScheduledReminder;
use App\Models\Service;
use App\Models\StaffProfile;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class DashboardAndReminderStatsTest extends TestCase
{
    use RefreshDatabase;

    public function test_business_dashboard_uses_database_backed_stats(): void
    {
        [$owner, $business] = $this->ownerWithBusiness();
        [$customer, $staff, $service, $appointment] = $this->bookingFixtures($business);
        $invoice = Invoice::factory()->create([
            'business_id' => $business->id,
            'customer_id' => $customer->id,
            'invoice_number' => 'INV-LIVE-DASH',
            'status' => InvoiceStatus::Unpaid->value,
            'total' => 200,
            'balance_due' => 200,
            'issue_date' => now()->toDateString(),
        ]);
        Payment::factory()->create([
            'business_id' => $business->id,
            'invoice_id' => $invoice->id,
            'customer_id' => $customer->id,
            'amount' => 150,
            'status' => PaymentStatus::Paid->value,
            'paid_at' => now(),
        ]);
        ScheduledReminder::factory()->create([
            'business_id' => $business->id,
            'customer_id' => $customer->id,
            'appointment_id' => $appointment->id,
            'channel' => 'email',
            'type' => 'appointment_reminder',
            'recipient' => 'live-customer@example.test',
            'scheduled_at' => now()->addHour(),
        ]);

        $otherBusiness = Business::factory()->create(['status' => 'active']);
        $otherCustomer = Customer::factory()->create([
            'business_id' => $otherBusiness->id,
            'name' => 'Other Tenant Dashboard Customer',
        ]);
        Appointment::factory()->create([
            'business_id' => $otherBusiness->id,
            'customer_id' => $otherCustomer->id,
            'starts_at' => now()->setTime(9, 0),
            'ends_at' => now()->setTime(10, 0),
        ]);

        $this->actingAs($owner)
            ->withSession(['current_business_id' => $business->id])
            ->get(route('admin.dashboard'))
            ->assertOk()
            ->assertSee('Total Bookings')
            ->assertSee('$150.00')
            ->assertSee('$200.00 due')
            ->assertSee($customer->name)
            ->assertSee($staff->name)
            ->assertSee($service->name)
            ->assertSee(url('/book/'.$business->slug))
            ->assertDontSee('Other Tenant Dashboard Customer');
    }

    public function test_reminder_overview_logs_and_scheduled_pages_use_database_queries(): void
    {
        [$owner, $business] = $this->ownerWithBusiness();
        [$customer, , $service, $appointment] = $this->bookingFixtures($business);
        $scheduledCustomer = Customer::factory()->create([
            'business_id' => $business->id,
            'name' => 'Scheduled Reminder Customer',
        ]);

        ReminderLog::factory()->create([
            'business_id' => $business->id,
            'scheduled_reminder_id' => null,
            'customer_id' => $customer->id,
            'channel' => 'whatsapp',
            'type' => 'appointment_reminder',
            'recipient' => '15550001111',
            'message_preview' => 'Live reminder sent from database.',
            'status' => ReminderStatus::Sent->value,
            'sent_at' => now(),
        ]);
        ReminderLog::factory()->create([
            'business_id' => $business->id,
            'scheduled_reminder_id' => null,
            'customer_id' => $customer->id,
            'channel' => 'email',
            'type' => 'invoice_reminder',
            'recipient' => 'live-customer@example.test',
            'message_preview' => 'Invoice reminder failed from database.',
            'status' => ReminderStatus::Failed->value,
            'failure_reason' => 'SMTP failed during test',
            'sent_at' => now()->subMinutes(5),
        ]);
        ScheduledReminder::factory()->create([
            'business_id' => $business->id,
            'customer_id' => $scheduledCustomer->id,
            'appointment_id' => $appointment->id,
            'channel' => 'whatsapp',
            'type' => 'booking_confirmation',
            'recipient' => '15550002222',
            'message' => 'Live scheduled reminder from database.',
            'scheduled_at' => now()->addDay(),
            'status' => ReminderStatus::Scheduled->value,
        ]);

        $this->actingAs($owner)
            ->withSession(['current_business_id' => $business->id])
            ->get(route('admin.reminders.index'))
            ->assertOk()
            ->assertSee('Live reminder sent from database.')
            ->assertSee('Invoice reminder failed from database.')
            ->assertSee('50%');

        $this->actingAs($owner)
            ->withSession(['current_business_id' => $business->id])
            ->get(route('admin.reminders.logs', ['status' => 'failed', 'channel' => 'email']))
            ->assertOk()
            ->assertSee('SMTP failed during test')
            ->assertSee('Invoice Reminder')
            ->assertDontSee('Live reminder sent from database.');

        $this->actingAs($owner)
            ->withSession(['current_business_id' => $business->id])
            ->get(route('admin.reminders.scheduled', ['channel' => 'whatsapp']))
            ->assertOk()
            ->assertSee('Scheduled Reminder Customer')
            ->assertSee('WhatsApp')
            ->assertSee($service->name);
    }

    public function test_reminder_filters_show_empty_states(): void
    {
        [$owner, $business] = $this->ownerWithBusiness();

        $this->actingAs($owner)
            ->withSession(['current_business_id' => $business->id])
            ->get(route('admin.reminders.logs', ['q' => 'nothing-can-match-this']))
            ->assertOk()
            ->assertSee('No reminder logs found');

        $this->actingAs($owner)
            ->withSession(['current_business_id' => $business->id])
            ->get(route('admin.reminders.scheduled', ['q' => 'nothing-can-match-this']))
            ->assertOk()
            ->assertSee('No scheduled reminders found');
    }

    private function ownerWithBusiness(): array
    {
        $owner = User::factory()->create([
            'role' => UserRole::BusinessOwner->value,
        ]);
        $business = Business::factory()->create([
            'owner_id' => $owner->id,
            'name' => 'Live Stats Salon',
            'slug' => 'live-stats-salon',
            'status' => 'active',
            'currency' => 'USD',
            'timezone' => 'UTC',
            'meta' => ['booking_link_clicks' => 20],
        ]);

        return [$owner, $business];
    }

    private function bookingFixtures(Business $business): array
    {
        $customer = Customer::factory()->create([
            'business_id' => $business->id,
            'name' => 'Live Dashboard Customer',
            'phone' => '(555) 101-2020',
        ]);
        $staff = StaffProfile::factory()->create([
            'business_id' => $business->id,
            'name' => 'Live Dashboard Staff',
        ]);
        $service = Service::factory()->create([
            'business_id' => $business->id,
            'name' => 'Live Dashboard Hair Cut',
            'price' => 65,
            'duration_minutes' => 60,
        ]);
        $appointment = Appointment::factory()->create([
            'business_id' => $business->id,
            'customer_id' => $customer->id,
            'staff_profile_id' => $staff->id,
            'service_id' => $service->id,
            'status' => AppointmentStatus::Confirmed->value,
            'starts_at' => now()->setTime(9, 0),
            'ends_at' => now()->setTime(10, 0),
            'price' => 65,
            'payment_status' => 'paid',
        ]);

        return [$customer, $staff, $service, $appointment];
    }
}
