<?php

declare(strict_types=1);

namespace App\Filament\Widgets;

use App\Business\Purchase\PurchaseCollaborationReminderService;
use App\Filament\Resources\DberpPurchaseExceptions\DberpPurchaseExceptionResource;
use App\Filament\Resources\DberpPurchaseOrders\DberpPurchaseOrderResource;
use App\Filament\Resources\DberpPurchasePriceReferences\DberpPurchasePriceReferenceResource;
use App\Filament\Resources\DberpPurchaseRequests\DberpPurchaseRequestResource;
use App\Filament\Resources\DberpSupplierPerformances\DberpSupplierPerformanceResource;
use App\Services\DberpPermissionService;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
use Illuminate\Support\Facades\Auth;

class PurchaseCollaborationOverviewStatsWidget extends BaseWidget
{
    protected ?string $pollingInterval = null;

    public static function canView(): bool
    {
        return app(DberpPermissionService::class)->allows(Auth::user(), DberpPermissionService::VIEW_WORKBENCH_OVERVIEW);
    }

    protected function getStats(): array
    {
        $metrics = app(PurchaseCollaborationReminderService::class)->overviewMetrics();

        return [
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_pending_request'), (string) $metrics['pending_purchase_request_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_requests'))
                ->color('warning')
                ->url($this->requestUrl('pending')),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_pending_convert'), (string) $metrics['pending_convert_request_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_requests'))
                ->color('primary')
                ->url(DberpPurchaseRequestResource::getUrl('index')),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_urgent_request'), (string) $metrics['urgent_pending_purchase_request_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_requests'))
                ->color('danger')
                ->url(DberpPurchaseRequestResource::getUrl('index')),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_pending_arrival'), (string) $metrics['pending_arrival_order_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_orders'))
                ->color('primary')
                ->url($this->orderUrl()),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_overdue_arrival'), (string) $metrics['overdue_arrival_order_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_overdue'))
                ->color('danger')
                ->url($this->orderUrl(overdue: true)),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_partial_arrival'), (string) $metrics['partial_arrival_order_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_orders'))
                ->color('warning')
                ->url($this->orderUrl(status: 'partially_received')),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_pending_exception'), (string) $metrics['pending_purchase_exception_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_exceptions'))
                ->color('danger')
                ->url($this->exceptionUrl()),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_resupply_exception'), (string) $metrics['pending_resupply_exception_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_resupply'))
                ->color('warning')
                ->url($this->exceptionUrl(status: 'processing', resolutionResult: 'resupply')),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_supplier_attention'), (string) $metrics['supplier_performance_attention_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_supplier'))
                ->color('warning')
                ->url(DberpSupplierPerformanceResource::getUrl('index').'?'.http_build_query(['filters' => ['needs_attention' => ['isActive' => true]]])),
            Stat::make((string) __('dberp.widgets.purchase_workbench.stat_stale_price'), (string) $metrics['stale_purchase_price_reference_count'])
                ->description((string) __('dberp.widgets.purchase_workbench.link_price'))
                ->color('primary')
                ->url(DberpPurchasePriceReferenceResource::getUrl('index').'?'.http_build_query(['filters' => ['is_stale' => ['isActive' => true]]])),
        ];
    }

    private function requestUrl(string $status): string
    {
        return DberpPurchaseRequestResource::getUrl('index').'?'.http_build_query([
            'filters' => [
                'status' => [
                    'value' => $status,
                ],
            ],
        ]);
    }

    private function orderUrl(?string $status = null, bool $overdue = false): string
    {
        $filters = [];

        if ($status !== null) {
            $filters['status'] = ['value' => $status];
        }

        if ($overdue) {
            $filters['is_overdue'] = ['isActive' => true];
        }

        return DberpPurchaseOrderResource::getUrl('index').'?'.http_build_query([
            'filters' => $filters,
        ]);
    }

    private function exceptionUrl(?string $status = null, ?string $resolutionResult = null): string
    {
        $filters = [];

        if ($status !== null) {
            $filters['status'] = ['value' => $status];
        }

        if ($resolutionResult !== null) {
            $filters['resolution_result'] = ['value' => $resolutionResult];
        }

        return DberpPurchaseExceptionResource::getUrl('index').'?'.http_build_query([
            'filters' => $filters,
        ]);
    }
}
