<?php

namespace App\Services\Courier;

use App\Services\Customer\CustomerQualityService;

class CourierStatusMapper
{
    /**
     * Provider-approved exact Out for Delivery codes.
     * Intermediate codes must never be added to this list.
     */
    private const OUT_FOR_DELIVERY_CODES = [
        'steadfast' => ['out_for_delivery'],
    ];

    public function map(?string $externalStatus, string $provider = 'steadfast'): array
    {
        $normalizedStatus = $this->normalizeStatus((string) $externalStatus);

        if ($normalizedStatus === '') {
            return $this->result(null, 'no_status', false);
        }

        $provider = $this->normalizeStatus($provider);

        if (in_array($normalizedStatus, self::OUT_FOR_DELIVERY_CODES[$provider] ?? [], true)) {
            return $this->result('picked_up', 'out_for_delivery', true, true);
        }

        if (in_array($normalizedStatus, [
            'created',
            'booked',
            'pending',
            'in_review',
            'hold',
            'picked',
            'picked_up',
            'in_transit',
            'on_the_way',
            'shipped',
            'received_at_hub',
            'transferred',
            'pending_delivery',
        ], true)) {
            return $this->result('handover', 'handover', true);
        }

        if (in_array($normalizedStatus, $this->configuredStatuses('delivered'), true)) {
            return $this->result('delivered', 'delivered', true);
        }

        if (in_array($normalizedStatus, $this->configuredStatuses('returned'), true)) {
            return $this->result('returned', 'returned', true);
        }

        if (in_array($normalizedStatus, $this->configuredStatuses('cancelled'), true)) {
            return $this->result('canceled', 'canceled', true);
        }

        return $this->result(null, 'manual_review_required', false);
    }

    private function result(
        ?string $internalStatus,
        string $mappingResult,
        bool $shouldUpdateOrder,
        bool $requiresRider = false
    ): array {
        return [
            'internal_status' => $internalStatus,
            'mapping_result' => $mappingResult,
            'should_update_order' => $shouldUpdateOrder,
            'requires_rider' => $requiresRider,
        ];
    }

    private function configuredStatuses(string $group): array
    {
        try {
            return app(CustomerQualityService::class)->statusesFor($group);
        } catch (\Throwable) {
            return match ($group) {
                'delivered' => ['delivered', 'delivered_approval_pending', 'partial_delivered', 'partial_delivered_approval_pending'],
                'returned' => ['returned', 'return_to_sender', 'return_to_merchant', 'returned_to_merchant', 'return_to_origin'],
                'cancelled' => ['cancelled', 'cancelled_approval_pending', 'canceled', 'failed'],
                default => [],
            };
        }
    }

    private function normalizeStatus(string $status): string
    {
        return trim(strtolower(str_replace([' ', '-'], '_', $status)));
    }
}
