<?php

namespace App\Modules\Dashboard\Services;

use App\Models\User;
use App\Modules\Admin\Tenancy\Models\Tenant;
use App\Modules\Dashboard\DTOs\ActionCenterWidgetData;
use App\Modules\Procurement\Models\GoodsReceipt;
use App\Modules\Procurement\Models\PurchaseOrder;
use App\Modules\Sales\Models\SalesOrder;
use App\Modules\Dashboard\DTOs\OperationalSnapshot;
use App\Modules\Dashboard\Repositories\TenantBillingSignalsRepository;
use App\Modules\Dashboard\Support\AlertSeverity;
use Illuminate\Support\Facades\Route;

class DashboardActionCenterService
{
    public function __construct(
        private readonly TenantBillingSignalsRepository $billingSignals,
    ) {}

    /**
     * @param  list<string>  $enabledSlugs
     * @return list<ActionCenterWidgetData>
     */
    public function widgets(
        User $user,
        ?OperationalSnapshot $snapshot,
        array $enabledSlugs,
    ): array {
        if ($user->tenant === null || $user->isAdmin()) {
            return [];
        }
        $tenant = $user->tenant;
        $hr = in_array('hr', $enabledSlugs, true);
        $rows = [];
        if ($hr && $snapshot !== null) {
            $rows = array_merge($rows, $this->hrWidgets($user, $snapshot));
        }
        $rows = array_merge($rows, $this->procurementAndSalesQueues($user));
        $rows[] = $this->billingWidget($tenant);
        $rows[] = $this->planWidget($tenant, $user);

        return array_values(array_filter($rows));
    }

    /**
     * @return list<ActionCenterWidgetData>
     */
    private function hrWidgets(User $user, OperationalSnapshot $s): array
    {
        $w = [];
        if ($user->can('leave.view')) {
            $n = $s->pendingLeaveManager + $s->pendingLeaveHr;
            $w[] = new ActionCenterWidgetData(
                key: 'pending_leave',
                title: __('dashboard.action_center.widgets.pending_leave'),
                count: $n,
                severity: $n > 0 ? AlertSeverity::WARNING : AlertSeverity::INFO,
                actionLabel: __('dashboard.action_center.review'),
                actionUrl: Route::has('hr.leave.requests.index') ? route('hr.leave.requests.index') : '#',
                icon: 'fe fe-calendar',
            );
        }
        if ($user->can('attendance.view')) {
            $w[] = new ActionCenterWidgetData(
                key: 'attendance_exceptions_pending',
                title: __('dashboard.action_center.widgets.attendance_exceptions_pending'),
                count: $s->pendingAttendanceExceptions,
                severity: $s->pendingAttendanceExceptions > 0 ? AlertSeverity::WARNING : AlertSeverity::INFO,
                actionLabel: __('dashboard.action_center.open_exceptions'),
                actionUrl: Route::has('hr.attendance.exceptions.index') ? route('hr.attendance.exceptions.index') : '#',
                icon: 'fe fe-alert-triangle',
            );
            $w[] = new ActionCenterWidgetData(
                key: 'attendance_exceptions_critical',
                title: __('dashboard.action_center.widgets.attendance_exceptions_critical'),
                count: $s->criticalAttendanceExceptions,
                severity: $s->criticalAttendanceExceptions > 0 ? AlertSeverity::CRITICAL : AlertSeverity::INFO,
                actionLabel: __('dashboard.action_center.open_exceptions'),
                actionUrl: Route::has('hr.attendance.exceptions.index') ? route('hr.attendance.exceptions.index') : '#',
                icon: 'fe fe-alert-circle',
            );
        }
        if ($user->can('shifts.view')) {
            $w[] = new ActionCenterWidgetData(
                key: 'missing_shifts',
                title: __('dashboard.action_center.widgets.missing_shifts'),
                count: $s->employeesMissingShift,
                severity: $s->employeesMissingShift > 0 ? AlertSeverity::DANGER : AlertSeverity::INFO,
                actionLabel: __('dashboard.action_center.assign'),
                actionUrl: Route::has('hr.shifts.assignments.create') ? route('hr.shifts.assignments.create') : '#',
                icon: 'fe fe-clock',
            );
        }
        if ($user->can('attendance.view')) {
            $w[] = new ActionCenterWidgetData(
                key: 'late_today',
                title: __('dashboard.action_center.widgets.late_today'),
                count: $s->lateToday,
                severity: $s->lateToday > 0 ? AlertSeverity::WARNING : AlertSeverity::INFO,
                actionLabel: __('dashboard.action_center.open_records'),
                actionUrl: Route::has('hr.attendance.index') ? route('hr.attendance.index') : '#',
                icon: 'fe fe-clock',
            );
            $w[] = new ActionCenterWidgetData(
                key: 'absent_today',
                title: __('dashboard.action_center.widgets.absent_today'),
                count: $s->absentToday,
                severity: $s->absentToday > 0 ? AlertSeverity::DANGER : AlertSeverity::INFO,
                actionLabel: __('dashboard.action_center.open_records'),
                actionUrl: Route::has('hr.attendance.index') ? route('hr.attendance.index') : '#',
                icon: 'fe fe-user-x',
            );
        }

        return $w;
    }

    /**
     * @return list<ActionCenterWidgetData>
     */
    private function procurementAndSalesQueues(User $user): array
    {
        $tid = (int) $user->tenant_id;
        if ($tid <= 0) {
            return [];
        }
        $w = [];
        if ($user->can('procurement.purchase_orders.view')) {
            $n = PurchaseOrder::query()->where('tenant_id', $tid)->where('status', 'draft')->count();
            if ($n > 0) {
                $w[] = new ActionCenterWidgetData(
                    key: 'po_drafts',
                    title: __('dashboard.action_center.widgets.pending_po_drafts'),
                    count: $n,
                    severity: AlertSeverity::WARNING,
                    actionLabel: __('operational_ui.link.purchase_orders'),
                    actionUrl: route('procurement.purchase-orders.index', ['status' => 'draft']),
                    icon: 'fe fe-file-text',
                );
            }
        }
        if ($user->can('procurement.goods_receipts.view')) {
            $n = GoodsReceipt::query()->where('tenant_id', $tid)->where('status', 'draft')->count();
            if ($n > 0) {
                $w[] = new ActionCenterWidgetData(
                    key: 'gr_drafts',
                    title: __('dashboard.action_center.widgets.draft_goods_receipts'),
                    count: $n,
                    severity: AlertSeverity::INFO,
                    actionLabel: __('operational_ui.link.goods_receipts'),
                    actionUrl: route('procurement.goods-receipts.index'),
                    icon: 'fe fe-truck',
                );
            }
        }
        if ($user->can('sales.orders.view')) {
            $n = SalesOrder::query()->where('tenant_id', $tid)->where('status', 'draft')->count();
            if ($n > 0) {
                $w[] = new ActionCenterWidgetData(
                    key: 'so_drafts',
                    title: __('dashboard.action_center.widgets.draft_sales_orders'),
                    count: $n,
                    severity: AlertSeverity::INFO,
                    actionLabel: __('operational_ui.link.sales_orders'),
                    actionUrl: route('sales.orders.index', ['status' => 'draft']),
                    icon: 'fe fe-shopping-cart',
                );
            }
        }

        return $w;
    }

    private function billingWidget(Tenant $tenant): ?ActionCenterWidgetData
    {
        $n = $this->billingSignals->subscriptionIssueCount($tenant);

        return new ActionCenterWidgetData(
            key: 'subscription',
            title: __('dashboard.action_center.widgets.subscription'),
            count: $n,
            severity: $n > 0 ? AlertSeverity::CRITICAL : AlertSeverity::INFO,
            actionLabel: __('dashboard.upgrade_plan'),
            actionUrl: route('dashboard.index').'#dashboard-modules',
            icon: 'fe fe-credit-card',
        );
    }

    private function planWidget(Tenant $tenant, User $user): ?ActionCenterWidgetData
    {
        if (! $user->can('employees.view')) {
            return null;
        }
        $n = $this->billingSignals->planLimitRiskCount($tenant);

        return new ActionCenterWidgetData(
            key: 'plan_limits',
            title: __('dashboard.action_center.widgets.plan_limits'),
            count: $n,
            severity: $n > 0 ? AlertSeverity::DANGER : AlertSeverity::INFO,
            actionLabel: __('dashboard.upgrade_plan'),
            actionUrl: route('dashboard.index').'#dashboard-modules',
            icon: 'fe fe-layers',
        );
    }
}
