<?php

use App\Livewire\Studio\Dashboard\Analysis;
use App\Models\Category;
use App\Models\Customer;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Outlet;
use App\Models\Perfume;
use App\Models\User;
use Carbon\Carbon;
use Livewire\Livewire;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

beforeEach(function () {
    $this->setupUser();

    $role = Role::firstOrCreate(['name' => 'Developer']);
    Permission::firstOrCreate(['name' => 'view analysis']);
    $role->givePermissionTo('view analysis');
    $this->user->assignRole($role);
});

it('renders the analysis page correctly', function () {
    $this->actingAs($this->user)
        ->get(route('studio.dashboard.analysis'))
        ->assertOk()
        ->assertSeeLivewire(Analysis::class);
});

it('calculates counting data correctly', function () {
    // Basic counts
    Outlet::factory()->count(2)->create();
    Category::factory()->count(3)->create();

    // Member count (User with customer relation)
    $customerUser = User::factory()->create();
    Customer::factory()->create(['user_id' => $customerUser->id]);

    // Employee count (User with employee relation)
    $employeeUser = User::factory()->create();
    \App\Models\Employee::factory()->create(['user_id' => $employeeUser->id]);

    Livewire::actingAs($this->user)
        ->test(Analysis::class)
        ->assertSet('countingData.0.title', 'Outlet')
        ->assertSet('countingData.0.value', 3) // 1 from setup + 2 created
        ->assertSet('countingData.4.title', 'Member')
        ->assertSet('countingData.4.value', 1);
});

it('filters data by pre-defined periods', function () {
    // Order from 10 days ago
    Order::factory()->paid()->create([
        'total' => 100000,
        'created_at' => now()->subDays(10),
    ]);

    // Order from today
    Order::factory()->paid()->create([
        'total' => 50000,
        'created_at' => now(),
    ]);

    Livewire::actingAs($this->user)
        ->test(Analysis::class)
        // All period (default)
        ->assertSet('orders.5.value', 'Rp150.000')
        // Last 7 days (only shows today's order)
        ->set('period', '7')
        ->assertSet('orders.5.value', 'Rp50.000');
});

it('filters data by custom date range', function () {
    // Order in range
    Order::factory()->paid()->create([
        'total' => 200000,
        'created_at' => Carbon::parse('2024-01-15'),
    ]);

    // Order out of range
    Order::factory()->paid()->create([
        'total' => 100000,
        'created_at' => Carbon::parse('2024-02-15'),
    ]);

    Livewire::actingAs($this->user)
        ->test(Analysis::class)
        ->set('range.start', '2024-01-01')
        ->set('range.end', '2024-01-31')
        ->assertSet('orders.5.value', 'Rp200.000');
});

it('shows top performers correctly with aggregation', function () {
    $p1 = Perfume::factory()->create(['name' => 'Perfume A', 'sale_price' => 1000]);
    $p2 = Perfume::factory()->create(['name' => 'Perfume B', 'sale_price' => 2000]);

    // Sale of Perfume A (Total sales: 1500)
    $o1 = Order::factory()->paid()->create();
    OrderItem::factory()->forOrder($o1)->forPerfume($p1)->create([
        'unit_price' => 500,
        'quantity' => 3,
    ]);

    // Sale of Perfume B (Total sales: 4000)
    $o2 = Order::factory()->paid()->create();
    OrderItem::factory()->forOrder($o2)->forPerfume($p2)->create([
        'unit_price' => 2000,
        'quantity' => 2,
    ]);

    Livewire::actingAs($this->user)
        ->test(Analysis::class)
        ->assertSet('topPerfumes.0.name', 'Perfume B')
        ->assertSet('topPerfumes.0.total_sales', 'Rp4.000')
        ->assertSet('topPerfumes.1.name', 'Perfume A')
        ->assertSet('topPerfumes.1.total_sales', 'Rp1.500');
});
