<?php

declare(strict_types=1);

use Builder\Core\Foundation\Dashboard\Enums\WidgetWidth;
use Builder\Core\Foundation\Dashboard\Widgets\ChartWidget;
use Builder\Core\Foundation\Dashboard\Widgets\CounterWidget;
use Builder\Core\Foundation\Dashboard\Widgets\TextWidget;
use Builder\Core\Foundation\Dashboard\Widgets\Widget;

// ── CounterWidget ────────────────────────────────────────────────────────────

it('CounterWidget extends Widget', function (): void {
    $w = new CounterWidget('total-users', 'Total Users', fn () => 42);
    expect($w)->toBeInstanceOf(Widget::class);
});

it('CounterWidget returns correct key and label', function (): void {
    $w = new CounterWidget('total-users', 'Total Users', fn () => 42);
    expect($w->getKey())->toBe('total-users')
        ->and($w->getLabel())->toBe('Total Users');
});

it('CounterWidget component is CounterWidget', function (): void {
    expect((new CounterWidget('x', 'X', fn () => 0))->getComponent())->toBe('CounterWidget');
});

it('CounterWidget defaults width to third', function (): void {
    expect((new CounterWidget('x', 'X', fn () => 0))->getWidth())->toBe(WidgetWidth::Third);
});

it('CounterWidget getData resolves the value closure', function (): void {
    $w = new CounterWidget('total-users', 'Total Users', fn () => 99, 'users');
    expect($w->getData())->toBe(['value' => 99, 'label' => 'Total Users', 'icon' => 'users']);
});

it('CounterWidget getData works without icon', function (): void {
    $w = new CounterWidget('x', 'X', fn () => 0);
    expect($w->getData()['icon'])->toBeNull();
});

it('CounterWidget defaults permission to null', function (): void {
    expect((new CounterWidget('x', 'X', fn () => 0))->getPermission())->toBeNull();
});

it('CounterWidget defaults isHideable to true', function (): void {
    expect((new CounterWidget('x', 'X', fn () => 0))->isHideable())->toBeTrue();
});

it('CounterWidget toArray includes all fields', function (): void {
    $w = new CounterWidget('stats', 'Stats', fn () => 10);
    $arr = $w->toArray();

    expect($arr)->toHaveKeys(['key', 'label', 'component', 'width', 'data', 'permission', 'hideable'])
        ->and($arr['key'])->toBe('stats')
        ->and($arr['label'])->toBe('Stats')
        ->and($arr['component'])->toBe('CounterWidget')
        ->and($arr['width'])->toBe('third')
        ->and($arr['data']['value'])->toBe(10)
        ->and($arr['permission'])->toBeNull()
        ->and($arr['hideable'])->toBeTrue();
});

it('ChartWidget getKey and getLabel return constructor values', function (): void {
    $w = new ChartWidget('revenue', 'Revenue', 'bar', fn () => []);
    expect($w->getKey())->toBe('revenue')
        ->and($w->getLabel())->toBe('Revenue');
});

// ── TextWidget ────────────────────────────────────────────────────────────────

it('TextWidget extends Widget', function (): void {
    expect(new TextWidget('info', 'Info', 'Hello'))->toBeInstanceOf(Widget::class);
});

it('TextWidget component is TextWidget', function (): void {
    expect((new TextWidget('x', 'X', 'content'))->getComponent())->toBe('TextWidget');
});

it('TextWidget defaults width to half', function (): void {
    expect((new TextWidget('x', 'X', 'content'))->getWidth())->toBe(WidgetWidth::Half);
});

it('TextWidget getData returns content string', function (): void {
    expect((new TextWidget('x', 'X', '<p>Hello</p>'))->getData())->toBe(['content' => '<p>Hello</p>']);
});

it('TextWidget getData resolves content Closure', function (): void {
    $w = new TextWidget('x', 'X', fn () => 'dynamic');
    expect($w->getData())->toBe(['content' => 'dynamic']);
});

it('TextWidget getKey and getLabel return constructor values', function (): void {
    $w = new TextWidget('intro', 'Introduction', 'content');
    expect($w->getKey())->toBe('intro')
        ->and($w->getLabel())->toBe('Introduction');
});

// ── ChartWidget ────────────────────────────────────────────────────────────────

it('ChartWidget extends Widget', function (): void {
    expect(new ChartWidget('signups', 'Signups', 'line', fn () => []))->toBeInstanceOf(Widget::class);
});

it('ChartWidget component is ChartWidget', function (): void {
    expect((new ChartWidget('x', 'X', 'bar', fn () => []))->getComponent())->toBe('ChartWidget');
});

it('ChartWidget defaults width to half', function (): void {
    expect((new ChartWidget('x', 'X', 'pie', fn () => []))->getWidth())->toBe(WidgetWidth::Half);
});

it('ChartWidget getData returns type and dataset', function (): void {
    $dataset = ['labels' => ['A', 'B'], 'datasets' => [['data' => [1, 2]]]];
    $w = new ChartWidget('chart', 'Chart', 'bar', fn () => $dataset);
    expect($w->getData())->toBe(['type' => 'bar', 'dataset' => $dataset]);
});
