<?php

namespace App\Support\Operational;

use App\Modules\Procurement\Models\GoodsReceipt;
use App\Modules\Procurement\Support\GoodsReceiptLifecycleStatus;
use Illuminate\Support\Facades\View;

final class GoodsReceiptOperationalPresenter
{
    /**
     * @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(GoodsReceipt $receipt): array
    {
        $s = GoodsReceiptLifecycleStatus::tryFrom((string) $receipt->status);
        [$nt, $nb, $nv] = $this->nextTriple($s);

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

    /**
     * @return list<array{label: string, state: string, kind: string, meta?: string|null}>
     */
    private function timelineSteps(?GoodsReceiptLifecycleStatus $s): array
    {
        $v = 'pending';
        $p = 'pending';
        if ($s === GoodsReceiptLifecycleStatus::Posted) {
            $v = 'done';
            $p = 'done';
        } elseif ($s === GoodsReceiptLifecycleStatus::Validated) {
            $v = 'done';
            $p = 'current';
        } elseif ($s === GoodsReceiptLifecycleStatus::Draft) {
            $v = 'current';
        } elseif ($s === GoodsReceiptLifecycleStatus::Failed) {
            $v = 'done';
            $p = 'current';
        } elseif ($s === GoodsReceiptLifecycleStatus::Quarantined) {
            $v = 'current';
        }

        return [
            [
                'label' => __('operational_ui.timeline.gr.validation'),
                'state' => $v,
                'kind' => 'validation',
            ],
            [
                'label' => __('operational_ui.timeline.gr.posting'),
                'state' => $p,
                'kind' => 'posting',
            ],
        ];
    }

    private function blockedHtml(?GoodsReceiptLifecycleStatus $s, GoodsReceipt $receipt): ?string
    {
        if ($s === GoodsReceiptLifecycleStatus::Failed) {
            return View::make('components.ui.operational.blocked-alert', [
                'title' => __('operational_ui.blocked.gr_failed_title'),
                'body' => __('operational_ui.blocked.gr_failed_body'),
                'variant' => 'danger',
            ])->render();
        }
        $q = $receipt->relationLoaded('items')
            ? $receipt->items->whereNotNull('quarantined_at')->count()
            : 0;
        if ($q > 0) {
            return View::make('components.ui.operational.blocked-alert', [
                'title' => __('operational_ui.blocked.gr_quarantine_title'),
                'body' => __('operational_ui.blocked.gr_quarantine_body', ['count' => $q]),
                'variant' => 'warning',
            ])->render();
        }

        return null;
    }

    /**
     * @return array{0: ?string, 1: ?string, 2: string}
     */
    private function nextTriple(?GoodsReceiptLifecycleStatus $s): array
    {
        if ($s === GoodsReceiptLifecycleStatus::Draft) {
            return [
                __('operational_ui.next.gr_validate_title'),
                __('operational_ui.next.gr_validate_body'),
                'info',
            ];
        }
        if ($s === GoodsReceiptLifecycleStatus::Validated) {
            return [
                __('operational_ui.next.gr_post_title'),
                __('operational_ui.next.gr_post_body'),
                'warning',
            ];
        }
        if ($s === GoodsReceiptLifecycleStatus::Failed) {
            return [
                __('operational_ui.next.gr_retry_title'),
                __('operational_ui.next.gr_retry_body'),
                'danger',
            ];
        }

        return [null, null, 'info'];
    }

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

        return $rows;
    }

    private function statusVariant(?GoodsReceiptLifecycleStatus $s): string
    {
        return match ($s) {
            GoodsReceiptLifecycleStatus::Draft => 'warning',
            GoodsReceiptLifecycleStatus::Validated => 'info',
            GoodsReceiptLifecycleStatus::Posted => 'success',
            GoodsReceiptLifecycleStatus::Failed => 'danger',
            GoodsReceiptLifecycleStatus::Quarantined => 'warning',
            default => 'neutral',
        };
    }
}
