<?php

namespace Tests\Feature;

use App\Filament\Tenant\Pages\CalendarBoard;
use App\Models\Central\Company;
use App\Models\Central\Plan;
use App\Models\Tenant\Appointment;
use App\Models\Tenant\Client;
use App\Models\Tenant\Post;
use App\Models\Tenant\User;
use App\Models\Tenant\Vehicle;
use App\Tenancy\TenantManager;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Livewire\Livewire;
use Tests\TestCase;

class CalendarEnhancementsTest extends TestCase
{
    use RefreshDatabase;

    private Company $company;

    protected function setUp(): void
    {
        parent::setUp();
        $plan = Plan::firstOrCreate(['slug' => 'test'], ['name' => 'T', 'price' => 0, 'features' => []]);
        $this->company = Company::create(['plan_id' => $plan->id, 'slug' => 'ce-' . uniqid(), 'name' => 'CE', 'status' => 'active']);
        app(TenantManager::class)->setCurrent($this->company);
    }

    public function test_view_mode_day_returns_one_day(): void
    {
        Carbon::setTestNow('2026-06-10 10:00:00');
        $page = new CalendarBoard;
        $page->weekStart = '2026-06-10';
        $page->viewMode = 'day';
        $days = $page->getDays();

        $this->assertCount(1, $days);
        $this->assertEquals('2026-06-10', $days[0]['date']);
        Carbon::setTestNow();
    }

    public function test_view_mode_month_returns_30_or_31_days(): void
    {
        $page = new CalendarBoard;
        $page->weekStart = '2026-06-01';
        $page->viewMode = 'month';
        $days = $page->getDays();

        $this->assertCount(30, $days);   // June has 30 days
        $this->assertEquals('2026-06-01', $days[0]['date']);
        $this->assertEquals('2026-06-30', $days[29]['date']);
    }

    public function test_view_mode_custom_uses_range(): void
    {
        $page = new CalendarBoard;
        $page->weekStart = '2026-06-10';
        $page->viewMode = 'custom';
        $page->customStart = '2026-06-10';
        $page->customEnd = '2026-06-13';
        $days = $page->getDays();

        $this->assertCount(4, $days);
        $this->assertEquals('2026-06-10', $days[0]['date']);
        $this->assertEquals('2026-06-13', $days[3]['date']);
    }

    public function test_create_post_inline_adds_to_calendar(): void
    {
        $admin = User::create(['name' => 'A', 'email' => 'a@e.com', 'password' => bcrypt('x'), 'role' => 'admin', 'status' => 'active']);
        $this->actingAs($admin);

        Livewire::test(CalendarBoard::class)
            ->call('openNewPostForm')
            ->set('newPost.name', 'Curte 1')
            ->set('newPost.color', '#ff0000')
            ->set('newPost.hours_per_day', 8)
            ->set('newPost.description', 'fără lift')
            ->call('createPost')
            ->assertSet('showNewPostForm', false);

        $post = Post::where('name', 'Curte 1')->first();
        $this->assertNotNull($post);
        $this->assertEquals(8.0, (float) $post->hours_per_day);
        $this->assertEquals('fără lift', $post->description);
    }

    public function test_rename_post_updates_name_and_default_master(): void
    {
        $admin = User::create(['name' => 'A', 'email' => 'a@e.com', 'password' => bcrypt('x'), 'role' => 'admin', 'status' => 'active']);
        $master = User::create(['name' => 'Vasile', 'email' => 'v@e.com', 'password' => bcrypt('x'), 'role' => 'mechanic', 'status' => 'active']);
        $post = Post::create(['name' => 'Pod 1', 'color' => '#3b82f6', 'is_active' => true]);
        $this->actingAs($admin);

        Livewire::test(CalendarBoard::class)
            ->call('openRenamePost', $post->id)
            ->set('renamingPostName', 'Pod electric')
            ->set('renamingPostMasterId', $master->id)
            ->call('saveRenamePost')
            ->assertSet('renamingPostId', null);

        $post->refresh();
        $this->assertEquals('Pod electric', $post->name);
        $this->assertEquals($master->id, $post->default_master_id);
    }

    public function test_new_appointment_autofills_master_from_post_default(): void
    {
        $master = User::create(['name' => 'Vasile', 'email' => 'v@e.com', 'password' => bcrypt('x'), 'role' => 'mechanic', 'status' => 'active']);
        $post = Post::create(['name' => 'Pod 1', 'color' => '#3b82f6', 'is_active' => true, 'default_master_id' => $master->id]);

        Livewire::test(CalendarBoard::class)
            ->set('groupBy', 'post')
            ->call('openNewForm', $post->id, '2026-06-10');

        $component = Livewire::test(CalendarBoard::class);
        $component->set('groupBy', 'post')->call('openNewForm', $post->id, '2026-06-10');

        // The newAppt.master_id should have been auto-set from post.default_master_id
        $page = new CalendarBoard;
        $page->groupBy = 'post';
        $page->openNewForm($post->id, '2026-06-10');
        $this->assertEquals($master->id, $page->newAppt['master_id']);
        $this->assertEquals($post->id, $page->newAppt['post_id']);
    }

    public function test_list_view_returns_flat_appointments(): void
    {
        $client = Client::create(['name' => 'C', 'phone' => '+37399000000', 'type' => 'individual', 'status' => 'active']);
        $vehicle = Vehicle::create(['client_id' => $client->id, 'make' => 'BMW', 'model' => 'X5', 'plate' => 'L-1']);
        $post = Post::create(['name' => 'Pod 1', 'color' => '#3b82f6', 'is_active' => true]);
        Appointment::create([
            'post_id' => $post->id, 'client_id' => $client->id, 'vehicle_id' => $vehicle->id,
            'date' => '2026-06-10', 'time_start' => '10:00', 'time_end' => '11:00',
            'title' => 'Schimb ulei', 'status' => 'scheduled',
        ]);

        $page = new CalendarBoard;
        $page->weekStart = '2026-06-08';
        $page->viewMode = 'week';
        $list = $page->getListAppointments();

        $this->assertCount(1, $list);
        $this->assertEquals('Schimb ulei', $list[0]['title']);
        $this->assertEquals('C', $list[0]['client_name']);
        $this->assertEquals('+37399000000', $list[0]['client_phone']);
        $this->assertEquals('Pod 1', $list[0]['post_name']);
    }

    public function test_export_pdf_returns_streamed_pdf_response(): void
    {
        $client = Client::create(['name' => 'C', 'phone' => '+37399000000', 'type' => 'individual', 'status' => 'active']);
        $post = Post::create(['name' => 'Pod 1', 'color' => '#3b82f6', 'is_active' => true]);
        Appointment::create([
            'post_id' => $post->id, 'client_id' => $client->id,
            'date' => Carbon::now()->startOfWeek()->toDateString(),
            'time_start' => '09:00', 'time_end' => '10:00',
            'title' => 'Test PDF', 'status' => 'scheduled',
        ]);

        $page = new CalendarBoard;
        $page->mount();
        $page->viewMode = 'week';

        $response = $page->exportPdf();

        // It's a StreamedResponse
        $this->assertInstanceOf(\Symfony\Component\HttpFoundation\StreamedResponse::class, $response);
        $cd = $response->headers->get('content-disposition');
        $this->assertStringContainsString('programari_', $cd);
        $this->assertStringEndsWith('.pdf', $cd);
    }
}
