<?php

namespace Core\App\Services\Shipping;

use Core\App\Integrations\Shipping\MaystroClient;

class ShippingStatusPresenter
{
    public static function meta(?string $provider, $status = null, ?int $statusCode = null): array
    {
        $provider = strtolower(trim((string)$provider));
        if ($provider === 'maystro') {
            return self::maystroMeta($status, $statusCode);
        }
        return EcotrackStatusMapper::meta(is_scalar($status) ? (string)$status : null);
    }

    public static function timeline(?string $provider, array $shipping = []): array
    {
        $provider = strtolower(trim((string)$provider));
        if ($provider === 'maystro') {
            return self::maystroTimeline($shipping);
        }
        return [
            'type'        => 'steps',
            'steps'       => EcotrackStatusMapper::timelineSteps(),
            'activeIndex' => EcotrackStatusMapper::activeIndex($shipping['status'] ?? null),
        ];
    }

    public static function isDelivered(?string $provider, array $shipping = []): bool
    {
        $provider   = strtolower(trim((string)$provider));
        $status     = (string)($shipping['status'] ?? '');
        $statusCode = isset($shipping['status_code']) ? (int)$shipping['status_code'] : null;

        if ($provider === 'maystro') {
            return $statusCode === 41 || strtoupper($status) === 'DELIVERED';
        }

        $meta = EcotrackStatusMapper::meta($status);
        return ($meta['group'] ?? '') === 'delivered' || ($meta['group'] ?? '') === 'finance';
    }

    public static function isIssue(?string $provider, array $shipping = []): bool
    {
        $provider   = strtolower(trim((string)$provider));
        $status     = (string)($shipping['status'] ?? '');
        $statusCode = isset($shipping['status_code']) ? (int)$shipping['status_code'] : null;

        if ($provider === 'maystro') {
            if ($statusCode !== null) {
                return in_array($statusCode, [10, 11, 12, 32, 42, 50, 51, 52, 53], true);
            }
            return in_array(self::normalizeMaystroStatus($status, null), [
                'IN_TRANSIT_TO_BE_RETURNED', 'PENDING', 'OUT_OF_STOCK',
                'ALERTED', 'POSTPONED', 'ABORTED', 'READY_TO_RETURN',
                'TAKEN_BY_STORE', 'NOT_RECEIVED',
            ], true);
        }

        $meta = EcotrackStatusMapper::meta($status);
        return ($meta['group'] ?? '') === 'issues';
    }

    /**
     * All 18 official Maystro statuses (from API documentation)
     * code => [arabic, english, badge-class, group, icon, order]
     */
    public static function allMaystroStatuses(): array
    {
        return [
            'CREATED'                   => ['تم إنشاء الشحنة',        'Created',                  'bg-secondary',        'in_progress', 'bi-file-earmark-text',   1],
            'PICK_UP_REQUESTED'         => ['تم طلب الاستلام',        'Pick up requested',        'bg-primary',          'in_progress', 'bi-box-arrow-up',        2],
            'IN_PROCESS'                => ['قيد المعالجة',            'In process',               'bg-primary',          'in_progress', 'bi-boxes',               3],
            'WAITING_TRANSIT'           => ['بانتظار التحويل',         'Waiting transit',          'bg-info',             'in_progress', 'bi-hourglass-split',     4],
            'IN_TRANSIT_TO_BE_SHIPPED'  => ['في الطريق للشحن',        'In transit to be shipped', 'bg-info',             'in_progress', 'bi-arrow-right-circle',  5],
            'READY_TO_SHIP'             => ['جاهزة للشحن',            'Ready to ship',            'bg-primary',          'in_progress', 'bi-box-seam',            6],
            'ASSIGNED'                  => ['تم تعيين المندوب',       'Assigned',                 'bg-info',             'in_progress', 'bi-person-check',        7],
            'SHIPPED'                   => ['تم الشحن',                'Shipped',                  'bg-info',             'in_progress', 'bi-truck',               8],
            'DELIVERED'                 => ['تم التسليم',              'Delivered',                'bg-success',          'delivered',   'bi-check-circle',        9],
            // Issue statuses (shown separately)
            'IN_TRANSIT_TO_BE_RETURNED' => ['في الطريق للإرجاع',      'In transit to be returned','bg-warning text-dark', 'issues',     'bi-arrow-return-left',   10],
            'PENDING'                   => ['قيد الانتظار',            'Pending',                  'bg-warning text-dark', 'issues',     'bi-hourglass',           11],
            'OUT_OF_STOCK'              => ['نفاد المخزون',            'Out of stock',             'bg-warning text-dark', 'issues',     'bi-exclamation-circle',  12],
            'ALERTED'                   => ['تم التنبيه',              'Alerted',                  'bg-warning text-dark', 'issues',     'bi-bell',                13],
            'POSTPONED'                 => ['مؤجلة',                   'Postponed',                'bg-warning text-dark', 'issues',     'bi-calendar-x',          14],
            'ABORTED'                   => ['ألغيت الشحنة',           'Aborted',                  'bg-danger',           'issues',      'bi-x-circle',            15],
            'READY_TO_RETURN'           => ['جاهزة للإرجاع',          'Ready to return',          'bg-warning text-dark', 'issues',     'bi-arrow-counterclockwise',16],
            'TAKEN_BY_STORE'            => ['تم استلامها من المتجر',  'Taken by store',           'bg-warning text-dark', 'issues',     'bi-shop',                17],
            'NOT_RECEIVED'              => ['لم تُستلم',              'Not received',             'bg-warning text-dark', 'issues',     'bi-question-circle',     18],
            // Internal
            'SENT'                      => ['تم إنشاء الشحنة',        'Shipment created',         'bg-secondary',        'in_progress', 'bi-file-earmark-text',    1],
            'ERROR'                     => ['خطأ في الشحن',           'Error',                    'bg-danger',           'issues',      'bi-exclamation-triangle', 0],
            'UNKNOWN'                   => ['حالة غير معروفة',        'Unknown',                  'bg-secondary',        'unknown',     'bi-question',             0],
        ];
    }

    private static function maystroMeta($status = null, ?int $statusCode = null): array
    {
        $normalized = self::normalizeMaystroStatus($status, $statusCode);
        $map        = self::allMaystroStatuses();
        $entry      = $map[$normalized] ?? $map['UNKNOWN'];

        [$ar, $en, $badge, $group, $icon, $order] = $entry;
        $label = function_exists('__')
            ? __('shipping.maystro.status.' . strtolower($normalized), $en)
            : $en;

        return [
            'code'      => $normalized,
            'label_key' => 'shipping.maystro.status.' . strtolower($normalized),
            'fallback'  => $label,
            'badge'     => $badge,
            'group'     => $group,
            'icon'      => $icon,
        ];
    }

    private static function maystroTimeline(array $shipping): array
    {
        $normalized = self::normalizeMaystroStatus(
            $shipping['status'] ?? null,
            isset($shipping['status_code']) ? (int)$shipping['status_code'] : null
        );

        $map = self::allMaystroStatuses();

        // ── ALWAYS show all 18 statuses as steps ────────────────────────
        // Split into: main progress flow + issue statuses
        $mainFlow = [
            'CREATED', 'PICK_UP_REQUESTED', 'IN_PROCESS',
            'WAITING_TRANSIT', 'IN_TRANSIT_TO_BE_SHIPPED',
            'READY_TO_SHIP', 'ASSIGNED', 'SHIPPED', 'DELIVERED',
        ];

        $issueStatuses = [
            'IN_TRANSIT_TO_BE_RETURNED', 'PENDING', 'OUT_OF_STOCK',
            'ALERTED', 'POSTPONED', 'ABORTED',
            'READY_TO_RETURN', 'TAKEN_BY_STORE', 'NOT_RECEIVED',
        ];

        // Build steps from main flow
        $steps = [];
        foreach ($mainFlow as $code) {
            $entry = $map[$code] ?? $map['UNKNOWN'];
            $steps[] = [
                'code'      => $code,
                'label_key' => 'shipping.maystro.status.' . strtolower($code),
                'fallback'  => function_exists('__') ? __('shipping.maystro.status.' . strtolower($code), $entry[1]) : $entry[1],
                'icon'      => $entry[4],
                'group'     => $entry[3],
            ];
        }

        // Active step index in main flow
        $mainFlowIndex  = array_flip($mainFlow);
        $activeCode     = $normalized;

        // If current status is an issue, find which main step it maps to
        $isIssue = in_array($normalized, $issueStatuses, true);
        if ($isIssue) {
            // Issue statuses map to step positions
            $issueToStep = [
                'IN_TRANSIT_TO_BE_RETURNED' => 5, // after READY_TO_SHIP
                'PENDING'                   => 2,
                'OUT_OF_STOCK'              => 2,
                'ALERTED'                   => 7, // after SHIPPED
                'POSTPONED'                 => 7,
                'ABORTED'                   => 7,
                'READY_TO_RETURN'           => 7,
                'TAKEN_BY_STORE'            => 7,
                'NOT_RECEIVED'              => 7,
            ];
            $activeIndex = $issueToStep[$normalized] ?? 0;
        } else {
            $activeIndex = $mainFlowIndex[$activeCode] ?? ($activeCode === 'SENT' ? 0 : 0);
        }

        // ── Build lifecycle events ───────────────────────────────────────
        $events = [];
        foreach ((array)($shipping['tracking_lifecycle'] ?? []) as $event) {
            if (!is_array($event)) continue;

            $evCode  = isset($event['status_code']) && is_numeric($event['status_code'])
                ? self::normalizeMaystroStatus(null, (int)$event['status_code'])
                : self::normalizeMaystroStatus(
                    $event['label'] ?? $event['status'] ?? $event['state'] ?? $event['name'] ?? null,
                    null
                );

            $entry = $map[$evCode] ?? null;
            $label = $entry
                ? (function_exists('__') ? __('shipping.maystro.status.' . strtolower($evCode), $entry[1]) : $entry[1])
                : (function_exists('__') ? __('shipping.maystro.status.' . strtolower($evCode), str_replace('_', ' ', ucwords(strtolower($evCode), '_'))) : $evCode);

            $date = trim((string)(($event['date'] ?? '') . ' ' . ($event['time'] ?? '')));
            $note = $event['note'] ?? $event['message'] ?? $event['description'] ?? null;

            $events[] = [
                'label' => $label ?: 'Update',
                'date'  => $date ?: null,
                'note'  => $note ? (string)$note : null,
                'code'  => $evCode,
                'group' => $entry[3] ?? 'in_progress',
                'icon'  => $entry[4] ?? 'bi-circle',
            ];
        }

        // Synthesize event if none from lifecycle
        if (empty($events)) {
            $entry   = $map[$normalized] ?? $map['UNKNOWN'];
            $label   = function_exists('__') ? __('shipping.maystro.status.' . strtolower($normalized), $entry[1]) : $entry[1];
            $events[] = [
                'label' => $label,
                'date'  => $shipping['last_update_at'] ?? $shipping['created_at'] ?? null,
                'note'  => null,
                'code'  => $normalized,
                'group' => $entry[3],
                'icon'  => $entry[4],
            ];
        }

        // Add current issue status as extra event if relevant
        if ($isIssue) {
            $entry  = $map[$normalized];
            $label  = function_exists('__') ? __('shipping.maystro.status.' . strtolower($normalized), $entry[1]) : $entry[1];
            $alreadyHasIssue = false;
            foreach ($events as $ev) {
                if ($ev['code'] === $normalized) { $alreadyHasIssue = true; break; }
            }
            if (!$alreadyHasIssue) {
                $events[] = [
                    'label' => '⚠️ ' . $label,
                    'date'  => $shipping['last_update_at'] ?? null,
                    'note'  => null,
                    'code'  => $normalized,
                    'group' => 'issues',
                    'icon'  => $entry[4],
                ];
            }
        }

        return [
            'type'        => 'steps',   // always show the full 9-step progress bar
            'steps'       => $steps,
            'activeIndex' => $activeIndex,
            'isIssue'     => $isIssue,
            'issueStatus' => $isIssue ? $normalized : null,
            'events'      => $events,   // available for detailed view
        ];
    }

    public static function normalizeMaystroStatus($status = null, ?int $statusCode = null): string
    {
        if ($statusCode !== null) {
            return strtoupper(MaystroClient::statusLabel($statusCode));
        }
        $value = strtoupper(trim((string)$status));
        if ($value === '') return 'UNKNOWN';
        if (in_array($value, ['SHIPMENT CREATED', 'SENT'], true)) return 'CREATED';
        return $value;
    }
}
