<?php

namespace classes;

/**
 * Builds stable, UI-friendly summaries for collected-invoice transfer queue jobs.
 */
class economic_transfer_queue_details_summary
{
    public static function buildCollectedInvoiceSummary(array $job): array
    {
        $payload = self::toArray($job['payload'] ?? null);
        $result = self::toArray($job['result'] ?? null);

        $collected_invoice_id = self::toPositiveInt(
            $payload['collected_invoice_id'] ?? $job['collected_invoice_id'] ?? $job['invoice_collection_id'] ?? null
        );

        $summary = [
            'message' => self::resolveMessage($job, $result),
            'target' => [
                'collected_invoice_id' => $collected_invoice_id,
                'send_as_is' => self::toNullableBool($payload['send_as_is'] ?? null),
                'requested_by' => self::toNonNegativeInt($payload['requested_by'] ?? $job['created_by'] ?? null),
            ],
            'customer' => [
                'customer_number' => self::toPositiveInt(
                    $result['customer_number']
                    ?? $result['user']['customer_number']
                    ?? $payload['customer_number']
                    ?? $payload['customer']['customer_number']
                    ?? null
                ),
                'name' => self::toNonEmptyString(
                    $result['customer_name']
                    ?? $result['user']['customer_name']
                    ?? $result['user']['display_name']
                    ?? $result['user']['name']
                    ?? $result['user']['company_name']
                    ?? $payload['customer_name']
                    ?? $payload['customer']['customer_name']
                    ?? $payload['customer']['display_name']
                    ?? $payload['customer']['name']
                    ?? null
                ),
            ],
            'outcome' => [
                'economic_invoice_draft_id' => self::toPositiveInt(
                    $result['economic_invoice_draft_id']
                    ?? $result['draft_invoice_id']
                    ?? null
                ),
                'economic_invoice_booked_id' => self::toPositiveInt(
                    $result['economic_invoice_booked_id']
                    ?? $result['booked_invoice_id']
                    ?? null
                ),
                'external_id' => self::toNonEmptyString($result['external_id'] ?? null),
                'total_net_amount' => self::toNullableFloat($result['total_net_amount'] ?? null),
                'order_count' => self::toOrderCount($result['orders'] ?? null),
            ],
            'raw_available' => [
                'payload' => self::hasRawValue($job['payload'] ?? null),
                'result' => self::hasRawValue($job['result'] ?? null),
            ],
        ];

        return $summary;
    }

    private static function resolveMessage(array $job, array $result): ?string
    {
        $error_message = self::toNonEmptyString($job['error_message'] ?? null);
        if ($error_message !== null) {
            return $error_message;
        }

        $result_message = self::toNonEmptyString($result['message'] ?? null);
        if ($result_message !== null) {
            return $result_message;
        }

        $progress_message = self::toNonEmptyString($job['progress_message'] ?? null);
        if ($progress_message !== null) {
            return $progress_message;
        }

        $status = strtoupper(trim((string)($job['status'] ?? '')));

        return match ($status) {
            economic_transfer_queue::STATUS_COMPLETED => 'Completed',
            economic_transfer_queue::STATUS_FAILED => 'Failed',
            economic_transfer_queue::STATUS_PROCESSING => 'Processing',
            economic_transfer_queue::STATUS_QUEUED => 'Queued',
            default => null,
        };
    }

    private static function toArray(mixed $value): array
    {
        if (is_array($value)) {
            return $value;
        }

        if (is_object($value)) {
            $decoded = json_decode(json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), true);
            return is_array($decoded) ? $decoded : [];
        }

        return [];
    }

    private static function toPositiveInt(mixed $value): ?int
    {
        if ($value === null || $value === '') {
            return null;
        }

        if (!is_numeric($value)) {
            return null;
        }

        $parsed = (int)$value;
        return $parsed > 0 ? $parsed : null;
    }

    private static function toNonNegativeInt(mixed $value): ?int
    {
        if ($value === null || $value === '') {
            return null;
        }

        if (!is_numeric($value)) {
            return null;
        }

        $parsed = (int)$value;
        return $parsed >= 0 ? $parsed : null;
    }

    private static function toNullableBool(mixed $value): ?bool
    {
        if (is_bool($value)) {
            return $value;
        }

        if ($value === null) {
            return null;
        }

        if (is_int($value) || is_float($value) || (is_string($value) && is_numeric($value))) {
            $numeric = (int)$value;
            if ($numeric === 0 || $numeric === 1) {
                return $numeric === 1;
            }
            return null;
        }

        if (is_string($value)) {
            $normalized = strtolower(trim($value));
            if (in_array($normalized, ['true', '1'], true)) {
                return true;
            }
            if (in_array($normalized, ['false', '0'], true)) {
                return false;
            }
        }

        return null;
    }

    private static function toNonEmptyString(mixed $value): ?string
    {
        if (!is_string($value)) {
            return null;
        }

        $trimmed = trim($value);
        return $trimmed !== '' ? $trimmed : null;
    }

    private static function toNullableFloat(mixed $value): ?float
    {
        if ($value === null || $value === '') {
            return null;
        }

        if (!is_numeric($value)) {
            return null;
        }

        return (float)$value;
    }

    private static function toOrderCount(mixed $orders): ?int
    {
        if (!is_array($orders)) {
            return null;
        }

        return count($orders);
    }

    private static function hasRawValue(mixed $value): bool
    {
        if ($value === null) {
            return false;
        }

        if (is_string($value)) {
            return trim($value) !== '';
        }

        if (is_array($value) || is_object($value)) {
            return true;
        }

        return true;
    }
}
