<?php
/**
 * Copyright © Simplyin. All rights reserved.
 */
declare(strict_types=1);

namespace Simplyin\Payment\Service;

/**
 * Maps payment API error codes/messages to user-friendly messages.
 */
class PaymentErrorMapper
{
    /**
     * Map a payment API error message to a user-friendly message.
     *
     * @param string $errorMessage
     * @return string
     */
    public function map($errorMessage): string
    {
        // Defensive: substring matching below requires a string; never TypeError on an array/object.
        $errorMessage = (string)$errorMessage;

        $blikErrorMap = [
            'AUTH_CODE_USED' => __('Authorization code has already been used'),
            'AUTH_CODE_EXPIRED' => __('Authorization code expired'),
            'AUTH_CODE_CANCEL' => __('Authorization code was cancelled'),
            'BLIK_CODE_INVALID' => __('Invalid BLIK code'),
            'BLIK_CODE_EXPIRED' => __('BLIK code has expired'),
        ];

        $currencyErrorMap = [
            'CURRENCY_NOT_SUPPORTED' => __('Currency not supported. SimplyIN payments work best with PLN.'),
            'INVALID_CURRENCY' => __('Invalid currency for this payment method.'),
        ];

        $cardErrorMap = [
            'CARD_DECLINED' => __('Card was declined. Please try another card.'),
            'CARD_EXPIRED' => __('Card has expired.'),
            'INSUFFICIENT_FUNDS' => __('Insufficient funds.'),
            'INVALID_CARD' => __('Invalid card details.'),
            '3DS_FAILED' => __('3D Secure verification failed.'),
            '3DS_TIMEOUT' => __('3D Secure verification timed out.'),
            'SIN.TOKEN' => __('Card payment was declined. Please re-enter your card details and try again.'),
            'token was declined' => __('Card payment was declined. Please re-enter your card details and try again.'),
            'declined' => __('Payment was declined. Please try again or use a different payment method.'),
        ];

        $generalErrorMap = [
            'PAYMENT_FAILED' => __('Payment failed. Please try again.'),
            'PAYMENT_CANCELLED' => __('Payment was cancelled.'),
            'PAYMENT_TIMEOUT' => __('Payment timed out. Please try again.'),
            'TRANSACTION_FAILED' => __('Transaction failed. Please try again.'),
        ];

        $allErrorMaps = array_merge($blikErrorMap, $currencyErrorMap, $cardErrorMap, $generalErrorMap);

        foreach ($allErrorMaps as $errorCode => $userMessage) {
            if (stripos($errorMessage, $errorCode) !== false) {
                return (string) $userMessage;
            }
        }

        // Do not surface the raw underlying error to the shopper — the detail is in the server logs.
        return (string) __('Payment processing failed. Please try again or use a different payment method.');
    }

    /**
     * Collect human-readable validation issue messages from an API response.
     *
     * @param array $issues
     * @return array
     */
    public function collectOrderIssueMessages($issues): array
    {
        $issueMessages = [];
        foreach ($issues as $issue) {
            $msg = $issue['message'] ?? '';
            $path = isset($issue['path']) ? implode('.', $issue['path']) : '';
            if ($msg) {
                $issueMessages[] = $path ? "{$path}: {$msg}" : $msg;
            }
        }

        return $issueMessages;
    }
}
