<?php

namespace App\Filament\Widgets;

use App\Models\Inventory\StockBatch;
use App\Models\Scopes\BranchScope;
use App\Services\CurrentContext;
use Filament\Widgets\ChartWidget;
use Illuminate\Support\Facades\Auth;

class MarginBubbleChart extends ChartWidget
{
    protected static ?int $sort = 19;

    protected int|string|array $columnSpan = 1;

    protected ?string $heading = 'Margin bubble';

    protected ?string $description = 'Cost vs. sale price per receipt lot; bubble size = units left on that lot.';

    public static function canView(): bool
    {
        return Auth::user()?->hasPermissionTo('dashboard.access') ?? false;
    }

    protected function getData(): array
    {
        $branchId = app(CurrentContext::class)->branchId();

        // One point per sellable lot — price drift across consignments shows
        // up as a spread of bubbles instead of one product-wide average.
        // Branch semantics mirror Product::withStockFor(): an explicit branch
        // pins the query to it, null aggregates the accessible branches.
        $points = StockBatch::query()
            ->when($branchId !== null, fn ($q) => $q
                ->withoutGlobalScope(BranchScope::class)
                ->where('branch_id', $branchId))
            ->whereHas('product', fn ($q) => $q->where('is_active', true))
            ->active()
            ->where('available_quantity', '>', 0)
            ->whereNotNull('sale_price')
            ->orderByDesc('available_quantity')
            ->limit(60)
            ->get(['id', 'batch_cost', 'sale_price', 'available_quantity'])
            ->map(function (StockBatch $lot): array {
                $available = max(0, (float) $lot->available_quantity);

                // Radius scaled with the square root of the stock so bubbles stay readable.
                $radius = (float) round(min(28, max(4, sqrt($available) + 1)), 1);

                return [
                    'x' => round((float) ($lot->batch_cost ?? 0), 2),
                    'y' => round((float) $lot->sale_price, 2),
                    'r' => $radius,
                ];
            })
            ->all();

        return [
            'datasets' => [[
                'label' => 'Lots',
                'data' => $points,
                'backgroundColor' => 'rgba(139, 92, 246, 0.55)',
                'borderColor' => '#8b5cf6',
            ]],
            'labels' => [],
        ];
    }

    protected function getType(): string
    {
        return 'bubble';
    }
}
