<?php
namespace WalletUpPro\Core\Config;

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Centralized configuration for all payment methods
 * Single source of truth to eliminate repetition across the codebase
 */
class PaymentMethodsConfig
{
    const PAYMENT_METHODS = [
        'cashapp' => [
            'name' => 'Cash App',
            'type' => 'traditional',
            'class' => 'WalletUpPro\Payments\CashApp',
            'icon_color' => 'green-600',
            'validation_pattern' => '/^\$?[a-zA-Z0-9]{1,20}$/'
        ],
        'paypal' => [
            'name' => 'PayPal.me',
            'type' => 'traditional',
            'class' => 'WalletUpPro\Payments\PayPal',
            'icon_color' => 'blue-600',
            'validation_pattern' => '/^[a-zA-Z0-9._-]{1,}$/'
        ],
        'venmo' => [
            'name' => 'Venmo',
            'type' => 'traditional',
            'class' => 'WalletUpPro\Payments\Venmo',
            'icon_color' => 'blue-600',
            'validation_pattern' => '/^@?[a-zA-Z0-9_-]{1,20}$/'
        ],
        'zelle' => [
            'name' => 'Zelle',
            'type' => 'traditional',
            'class' => 'WalletUpPro\Payments\Zelle',
            'icon_color' => 'purple-600',
            'validation_pattern' => '/^([^\s@]+@[^\s@]+\.[^\s@]+|\+?[\d\s-]{10,})$/',
            'has_deep_linking' => true,
            'has_bank_selector' => true
        ],
        'fbpay' => [
            'name' => 'Meta Pay',
            'type' => 'traditional',
            'class' => 'WalletUpPro\Payments\FacebookPay',
            'icon_color' => 'blue-600',
            'validation_pattern' => '/^[a-zA-Z0-9.]{4,}$/'
        ],
        'waluppay' => [
            'name' => 'WalUp Pay',
            'type' => 'traditional',
            'class' => 'WalletUpPro\Payments\WalupPay',
            'icon_color' => 'purple-600',
            'validation_pattern' => '/^@?([a-zA-Z0-9_][a-zA-Z0-9_-]*[a-zA-Z0-9_]){3,30}$/'
        ],

        'bitcoin' => [
            'name' => 'Bitcoin',
            'type' => 'crypto',
            'class' => 'WalletUpPro\Payments\Bitcoin',
            'icon_color' => 'orange-500',
            'validation_pattern' => '/^([13][a-km-zA-HJ-NP-Z1-9]{25,34}|bc1([02-9ac-hj-np-z]){7,87}|sp1([02-9ac-hj-np-z]){8,87})$/i',
            'address_formats' => [
                'legacy' => 'Legacy (1...)',
                'script' => 'Script Hash (3...)',
                'segwit' => 'Native SegWit (bc1q...)',
                'taproot' => 'Taproot (bc1p...)',
                'silent' => 'Silent Payments (sp1q...)'
            ]
        ],
        'ethereum' => [
            'name' => 'Ethereum',
            'type' => 'crypto',
            'class' => 'WalletUpPro\Payments\Ethereum',
            'icon_color' => 'indigo-600',
            'validation_pattern' => '/^0x[a-fA-F0-9]{40}$/'
        ],
        'usdt' => [
            'name' => 'USDT (Tether)',
            'type' => 'crypto',
            'class' => 'WalletUpPro\Payments\Usdt',
            'icon_color' => 'green-500',
            'validation_pattern' => '/^(0x[a-fA-F0-9]{40}|T[1-9A-HJ-NP-Za-km-z]{33})$/',
            'supports_networks' => ['ethereum', 'tron']
        ],
        'usdc' => [
            'name' => 'USDC',
            'type' => 'crypto',
            'class' => 'WalletUpPro\Payments\Usdc',
            'icon_color' => 'blue-500',
            'validation_pattern' => '/^0x[a-fA-F0-9]{40}$/'
        ],
        'bnb' => [
            'name' => 'BNB',
            'type' => 'crypto',
            'class' => 'WalletUpPro\Payments\Bnb',
            'icon_color' => 'yellow-500',
            'validation_pattern' => '/^(0x[a-fA-F0-9]{40}|bnb[a-z0-9]{39})$/',
            'address_formats' => [
                'bep20' => 'BEP-20 (BSC) (0x...)',
                'bep2' => 'BEP-2 (Binance Chain) (bnb...)'
            ],
            'warning' => 'BEP-2 and BEP-20 addresses are NOT interoperable'
        ],
        'dogecoin' => [
            'name' => 'Dogecoin',
            'type' => 'crypto',
            'class' => 'WalletUpPro\Payments\Dogecoin',
            'icon_color' => 'yellow-600',
            'validation_pattern' => '/^[DA9][1-9A-HJ-NP-Za-km-z]{32,46}$/',
            'address_formats' => [
                'standard' => 'Standard (D...)',
                'multisig' => 'Multisig (A... or 9...)'
            ]
        ],

        'mpesa_ke' => [
            'name' => 'M-Pesa',
            'full_name' => 'M-Pesa (Kenya)',
            'type' => 'mobile_money',
            'class' => 'WalletUpPro\Payments\MPesa',
            'icon_color' => 'green-600',
            'country' => 'KE',
            'country_code' => '+254',
            'currency' => 'KES',
            'provider' => 'safaricom',
            'requires_phone' => true,
            'validation_pattern' => '/^(\+?254|0)?[17]\d{8}$/'
        ],
        'orange_money_ci' => [
            'name' => 'Orange Money',
            'full_name' => 'Orange Money (Côte d\'Ivoire)',
            'type' => 'mobile_money',
            'class' => 'WalletUpPro\Payments\OrangeMoney',
            'icon_color' => 'orange-500',
            'country' => 'CI',
            'country_code' => '+225',
            'currency' => 'XOF',
            'provider' => 'orange',
            'requires_phone' => true,
            'validation_pattern' => '/^(\+?225)?[0-9]{10}$/'
        ],
        'mtn_momo_ci' => [
            'name' => 'MTN MoMo',
            'full_name' => 'MTN Mobile Money (Côte d\'Ivoire)',
            'type' => 'mobile_money',
            'class' => 'WalletUpPro\Payments\MtnMomoCi',
            'icon_color' => 'yellow-500',
            'country' => 'CI',
            'country_code' => '+225',
            'currency' => 'XOF',
            'provider' => 'mtn',
            'requires_phone' => true,
            'validation_pattern' => '/^(\+?225)?[0-9]{10}$/'
        ],
        'moov_money_ci' => [
            'name' => 'Moov Money',
            'full_name' => 'Moov Money (Côte d\'Ivoire)',
            'type' => 'mobile_money',
            'class' => 'WalletUpPro\Payments\MoovMoney',
            'icon_color' => 'blue-600',
            'country' => 'CI',
            'country_code' => '+225',
            'currency' => 'XOF',
            'provider' => 'moov',
            'requires_phone' => true,
            'validation_pattern' => '/^(\+?225)?[0-9]{10}$/'
        ],
        'mtn_momo_zm' => [
            'name' => 'MTN MoMo',
            'full_name' => 'MTN Mobile Money (Zambia)',
            'type' => 'mobile_money',
            'class' => 'WalletUpPro\Payments\MtnMomoZm',
            'icon_color' => 'yellow-500',
            'country' => 'ZM',
            'country_code' => '+260',
            'currency' => 'ZMW',
            'provider' => 'mtn',
            'requires_phone' => true,
            'validation_pattern' => '/^(\+?260)?[0-9]{9}$/'
        ],
        'airtel_money_zm' => [
            'name' => 'Airtel Money',
            'full_name' => 'Airtel Money (Zambia)',
            'type' => 'mobile_money',
            'class' => 'WalletUpPro\Payments\AirtelMoney',
            'icon_color' => 'red-600',
            'country' => 'ZM',
            'country_code' => '+260',
            'currency' => 'ZMW',
            'provider' => 'airtel',
            'requires_phone' => true,
            'validation_pattern' => '/^(\+?260)?[0-9]{9}$/'
        ],
        'zamtel_kwacha' => [
            'name' => 'Zamtel Kwacha',
            'full_name' => 'Zamtel Kwacha (Zambia)',
            'type' => 'mobile_money',
            'class' => 'WalletUpPro\Payments\ZamtelKwacha',
            'icon_color' => 'green-500',
            'country' => 'ZM',
            'country_code' => '+260',
            'currency' => 'ZMW',
            'provider' => 'zamtel',
            'requires_phone' => true,
            'validation_pattern' => '/^(\+?260)?[0-9]{9}$/'
        ],
        'wave_ci' => [
            'name' => 'Wave',
            'full_name' => 'Wave (Côte d\'Ivoire)',
            'type' => 'mobile_money',
            'class' => 'WalletUpPro\Payments\WaveCi',
            'icon_color' => 'blue-500',
            'country' => 'CI',
            'country_code' => '+225',
            'currency' => 'XOF',
            'provider' => 'wave',
            'requires_phone' => true,
            'validation_pattern' => '/^(\+?225)?[0-9]{10}$/'
        ]
    ];

    const ADDITIONAL_FIELDS = [
        'holder_owner' => 'Full Name',
        'holder_email' => 'Email Address',
        'holder_no' => 'Phone Number'
    ];

    public const FREE_METHOD_IDS = ['cashapp', 'paypal', 'venmo'];

    public static function getAllMethodIds(): array
    {
        return array_keys(self::PAYMENT_METHODS);
    }

    public static function getAvailableMethodIds(): array
    {
        // Detection: if premium class files exist on disk, this is the pro version.
        // In the free ZIP, Freemius strips these files so class_exists fails.
        if (class_exists('WalletUpPro\\Payments\\Bitcoin') || class_exists('WalletUpPro\\Payments\\Zelle')) {
            return self::getAllMethodIds();
        }

        return self::FREE_METHOD_IDS;
    }

    public static function getPaymentHolderFields(): array
    {
        return array_map(fn($id) => $id . '_holder', self::getAllMethodIds());
    }

    public static function getAllHolderFields(): array
    {
        return array_merge(
            array_keys(self::ADDITIONAL_FIELDS),
            self::getPaymentHolderFields()
        );
    }

    public static function getMethodConfig(string $methodId): ?array
    {
        return self::PAYMENT_METHODS[$methodId] ?? null;
    }

    public static function getMethodName(string $methodId): string
    {
        return self::PAYMENT_METHODS[$methodId]['name'] ?? ucfirst($methodId);
    }

    public static function getMethodFullName(string $methodId): string
    {
        return self::PAYMENT_METHODS[$methodId]['full_name']
            ?? self::PAYMENT_METHODS[$methodId]['name']
            ?? ucfirst($methodId);
    }

    public static function getMethodsByType(string $type): array
    {
        return array_filter(
            self::PAYMENT_METHODS,
            fn($config) => $config['type'] === $type,
            ARRAY_FILTER_USE_BOTH
        );
    }

    public static function getMethodClass(string $methodId): ?string
    {
        return self::PAYMENT_METHODS[$methodId]['class'] ?? null;
    }

    public static function getValidationPattern(string $methodId): ?string
    {
        return self::PAYMENT_METHODS[$methodId]['validation_pattern'] ?? null;
    }

    public static function methodHasFeature(string $methodId, string $feature): bool
    {
        return !empty(self::PAYMENT_METHODS[$methodId][$feature]);
    }

    public static function getFieldLabel(string $field): string
    {
        if (isset(self::ADDITIONAL_FIELDS[$field])) {
            return self::ADDITIONAL_FIELDS[$field];
        }

        $methodId = str_replace('_holder', '', $field);
        if (isset(self::PAYMENT_METHODS[$methodId])) {
            return self::PAYMENT_METHODS[$methodId]['name'];
        }

        return ucfirst(str_replace('_', ' ', $field));
    }

    public static function isCryptocurrency(string $methodId): bool
    {
        return (self::PAYMENT_METHODS[$methodId]['type'] ?? '') === 'crypto';
    }

    public static function isMobileMoney(string $methodId): bool
    {
        return (self::PAYMENT_METHODS[$methodId]['type'] ?? '') === 'mobile_money';
    }

    public static function requiresPhoneNumber(string $methodId): bool
    {
        return !empty(self::PAYMENT_METHODS[$methodId]['requires_phone']);
    }

    public static function getCountryCode(string $methodId): ?string
    {
        return self::PAYMENT_METHODS[$methodId]['country_code'] ?? null;
    }

    public static function getCurrency(string $methodId): ?string
    {
        return self::PAYMENT_METHODS[$methodId]['currency'] ?? null;
    }

    public static function getMobileMoneyMethods(): array
    {
        return self::getMethodsByType('mobile_money');
    }

    public static function getMobileMoneyByCountry(string $countryCode): array
    {
        return array_filter(
            self::PAYMENT_METHODS,
            fn($config) => ($config['type'] ?? '') === 'mobile_money'
                && ($config['country'] ?? '') === strtoupper($countryCode)
        );
    }
}
