<?php

namespace App\Support\Operational;

use App\Modules\Procurement\Models\PurchaseOrder;
use App\Modules\Procurement\Support\PurchaseOrderLifecycleStatus;
use Illuminate\Support\Facades\View;

final class PurchaseOrderOperationalPresenter
{
    /**
     * @return array{
     *   timelineSteps: list<array{label: string, state: string, kind: string, meta?: string|null}>,
     *   auditRows: list<array{label: string, value: string}>,
     *   statusVariant: string,
     *   blockedHtml: string|null,
     *   nextStepTitle: string|null,
     *   nextStepBody: string|null,
     *   nextStepVariant: string,
     * }
     */
    public function detail(PurchaseOrder $po): array
    {
        $s = PurchaseOrderLifecycleStatus::tryFrom((string) $po->status);
        [$nt, $nb, $nv] = $this->nextTriple($s);

        return [
            'timelineSteps' => $this->timelineSteps($s),
            'auditRows' => $this->auditRows($po),
            'statusVariant' => $this->statusVariant($s),
            'blockedHtml' => $this->blockedHtml($s),
            'nextStepTitle' => $nt,
            'nextStepBody' => $nb,
            'nextStepVariant' => $nv,
        ];
    }

    /**
     * @return list<array{label: string, state: string, kind: string, meta?: string|null}>
     */
    private function timelineSteps(?PurchaseOrderLifecycleStatus $s): array
    {
        $approval = 'pending';
        $recv = 'pending';
        $close = 'pending';
        if ($s === PurchaseOrderLifecycleStatus::Cancelled) {
            $approval = 'done';
            $recv = 'pending';
            $close = 'current';
        } elseif ($s === PurchaseOrderLifecycleStatus::Draft) {
            $approval = 'current';
        } elseif ($s === PurchaseOrderLifecycleStatus::Approved) {
            $approval = 'done';
            $recv = 'current';
        } elseif ($s === PurchaseOrderLifecycleStatus::PartiallyReceived) {
            $approval = 'done';
            $recv = 'current';
            $close = 'pending';
        } elseif ($s === PurchaseOrderLifecycleStatus::FullyReceived) {
            $approval = 'done';
            $recv = 'done';
            $close = 'current';
        } elseif ($s === PurchaseOrderLifecycleStatus::Closed) {
            $approval = 'done';
            $recv = 'done';
            $close = 'done';
        }

        return [
            [
                'label' => __('operational_ui.timeline.po.approval'),
                'state' => $approval,
                'kind' => 'approval',
                'meta' => $s === PurchaseOrderLifecycleStatus::Draft
                    ? __('operational_ui.timeline.meta.pending')
                    : null,
            ],
            [
                'label' => __('operational_ui.timeline.po.receiving'),
                'state' => $recv,
                'kind' => 'fulfillment',
            ],
            [
                'label' => __('operational_ui.timeline.po.closure'),
                'state' => $close,
                'kind' => 'posting',
            ],
        ];
    }

    private function blockedHtml(?PurchaseOrderLifecycleStatus $s): ?string
    {
        if ($s !== PurchaseOrderLifecycleStatus::Cancelled) {
            return null;
        }

        return View::make('components.ui.operational.blocked-alert', [
            'title' => __('operational_ui.blocked.po_cancelled_title'),
            'body' => __('operational_ui.blocked.po_cancelled_body'),
            'variant' => 'warning',
        ])->render();
    }

    /**
     * @return array{0: ?string, 1: ?string, 2: string}
     */
    private function nextTriple(?PurchaseOrderLifecycleStatus $s): array
    {
        return match ($s) {
            PurchaseOrderLifecycleStatus::Draft => [
                __('operational_ui.next.po_approve_title'),
                __('operational_ui.next.po_approve_body'),
                'info',
            ],
            PurchaseOrderLifecycleStatus::Approved => [
                __('operational_ui.next.po_receive_title'),
                __('operational_ui.next.po_receive_body'),
                'info',
            ],
            PurchaseOrderLifecycleStatus::PartiallyReceived => [
                __('operational_ui.next.po_partial_title'),
                __('operational_ui.next.po_partial_body'),
                'warning',
            ],
            PurchaseOrderLifecycleStatus::FullyReceived => [
                __('operational_ui.next.po_received_title'),
                __('operational_ui.next.po_received_body'),
                'info',
            ],
            default => [null, null, 'info'],
        };
    }

    /**
     * @return list<array{label: string, value: string}>
     */
    private function auditRows(PurchaseOrder $po): array
    {
        $rows = [
            ['label' => __('operational_ui.audit.record_id'), 'value' => '#'.$po->getKey()],
            ['label' => __('operational_ui.audit.po_number'), 'value' => (string) $po->po_number],
        ];
        if ($po->created_at) {
            $rows[] = ['label' => __('operational_ui.audit.created_at'), 'value' => (string) $po->created_at];
        }
        if ($po->updated_at) {
            $rows[] = ['label' => __('operational_ui.audit.updated_at'), 'value' => (string) $po->updated_at];
        }

        return $rows;
    }

    private function statusVariant(?PurchaseOrderLifecycleStatus $s): string
    {
        return match ($s) {
            PurchaseOrderLifecycleStatus::Draft => 'warning',
            PurchaseOrderLifecycleStatus::Approved => 'info',
            PurchaseOrderLifecycleStatus::PartiallyReceived => 'warning',
            PurchaseOrderLifecycleStatus::FullyReceived => 'success',
            PurchaseOrderLifecycleStatus::Closed => 'muted',
            PurchaseOrderLifecycleStatus::Cancelled => 'danger',
            default => 'neutral',
        };
    }
}
