<?php

namespace App\Libraries;

use CodeIgniter\Config\Services;

class CardyfieService
{
    private $encrypter;
    private $apiBaseUrl;
    private $encryptedApiKey;
    private $environment; // 'sandbox' or 'production'

    public function __construct()
    {
        try {
            $this->encrypter = Services::encrypter();
        } catch (\Exception $e) {
            log_message('error', 'Encryption service not available: ' . $e->getMessage());
            $this->encrypter = null;
        }
        
        // Get environment (sandbox or production)
        $this->environment = $_ENV['cardyfie.environment'] ?? 'sandbox';
        $this->apiBaseUrl = $_ENV['cardyfie.api_base_url'] ?? 'https://core.cardyfie.com/api';
        
        // Store the API key (encrypted if encryption is available)
        $apiKey = $_ENV['cardyfie.api_key'] ?? '';
        if ($this->encrypter && !empty($apiKey)) {
            $this->encryptedApiKey = $this->encrypter->encrypt($apiKey);
        } else {
            // Fallback: store as base64 encoded (not secure, but functional)
            $this->encryptedApiKey = base64_encode($apiKey);
        }
    }

    /**
     * Decrypt the API key for use in API calls
     */
    private function getDecryptedApiKey(): string
    {
        if (empty($this->encryptedApiKey)) {
            return '';
        }
        
        if ($this->encrypter) {
            return $this->encrypter->decrypt($this->encryptedApiKey);
        } else {
            // Fallback: decode from base64
            return base64_decode($this->encryptedApiKey);
        }
    }

    /**
     * Create a customer in Cardyfie
     * Simplified version - only requires essential fields
     */
    public function createCustomer(array $customerData): array
    {
        try {
            // Validate required fields
            $requiredFields = ['first_name', 'last_name', 'email', 'date_of_birth', 'id_type', 'id_number', 'id_front_image', 'user_image', 'house_number', 'address_line_1', 'city', 'zip_code', 'country'];
            foreach ($requiredFields as $field) {
                if (!isset($customerData[$field]) || empty($customerData[$field])) {
                    return [
                        'success' => false,
                        'message' => "Missing required field: {$field}"
                    ];
                }
            }

            // Validate email format
            if (!filter_var($customerData['email'], FILTER_VALIDATE_EMAIL)) {
                return [
                    'success' => false,
                    'message' => 'Invalid email format'
                ];
            }

            // Validate ID type
            $allowedIdTypes = ['passport', 'nid', 'bvn'];
            if (!in_array(strtolower($customerData['id_type']), $allowedIdTypes)) {
                return [
                    'success' => false,
                    'message' => 'Invalid ID type. Must be one of: ' . implode(', ', $allowedIdTypes)
                ];
            }

            // Validate date format (accepts YYYY-MM-DD or DD/MM/YYYY)
            $dateOfBirth = $this->normalizeDate($customerData['date_of_birth']);
            if (!$dateOfBirth) {
                return [
                    'success' => false,
                    'message' => 'Invalid date format. Use YYYY-MM-DD or DD/MM/YYYY'
                ];
            }

            // Prepare payload for Cardyfie API
            $payload = [
                'first_name' => $customerData['first_name'],
                'last_name' => $customerData['last_name'],
                'email' => $customerData['email'],
                'date_of_birth' => $dateOfBirth,
                'id_type' => strtolower($customerData['id_type']),
                'id_number' => $customerData['id_number'],
                'id_front_image' => $customerData['id_front_image'],
                'user_image' => $customerData['user_image'],
                'house_number' => $customerData['house_number'],
                'address_line_1' => $customerData['address_line_1'],
                'city' => $customerData['city'],
                'zip_code' => $customerData['zip_code'],
                'country' => $customerData['country']
            ];

            // Optional fields
            if (isset($customerData['id_back_image']) && !empty($customerData['id_back_image'])) {
                $payload['id_back_image'] = $customerData['id_back_image'];
            }

            if (isset($customerData['state']) && !empty($customerData['state'])) {
                $payload['state'] = $customerData['state'];
            }

            if (isset($customerData['reference_id']) && !empty($customerData['reference_id'])) {
                $payload['reference_id'] = $customerData['reference_id'];
            } else {
                // Auto-generate reference_id if not provided
                $payload['reference_id'] = 'CF_' . time() . '_' . bin2hex(random_bytes(4));
            }

            // Meta data (optional)
            if (isset($customerData['user_id']) && !empty($customerData['user_id'])) {
                $payload['meta[user_id]'] = $customerData['user_id'];
            }

            // Build API endpoint URL
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card-customer/create';

            // Make the API request
            $client = Services::curlrequest();
            $response = $client->post($endpoint, [
                'json' => $payload,
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false // Don't throw exceptions on HTTP errors
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Customer created successfully',
                    'customer' => $responseData['data']['customer'] ?? null,
                    'ulid' => $responseData['data']['customer']['ulid'] ?? null,
                    'reference_id' => $responseData['data']['customer']['reference_id'] ?? $payload['reference_id']
                ];
            } else {
                // Extract error message
                $errorMessage = 'Customer creation failed';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        // Check for error messages
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        } elseif (isset($responseData['message']['validation'])) {
                            $errorMessage = 'Validation error: ' . json_encode($responseData['message']['validation']);
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Create Customer Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Normalize date format to DD/MM/YYYY (Cardyfie format)
     * Accepts: YYYY-MM-DD, DD/MM/YYYY, or DD-MM-YYYY
     */
    private function normalizeDate(string $date): ?string
    {
        // Try to parse different date formats
        $formats = ['Y-m-d', 'd/m/Y', 'd-m-Y', 'm/d/Y'];
        
        foreach ($formats as $format) {
            $parsed = \DateTime::createFromFormat($format, $date);
            if ($parsed && $parsed->format($format) === $date) {
                // Convert to DD/MM/YYYY format (Cardyfie format)
                return $parsed->format('d/m/Y');
            }
        }
        
        return null;
    }

    /**
     * Get customer by ULID
     * Cardyfie API uses ULID as a path parameter: /card-customer/get/{ulid}
     */
    public function getCustomer(string $ulid): array
    {
        try {
            if (empty($ulid)) {
                return [
                    'success' => false,
                    'message' => 'Customer ULID is required'
                ];
            }

            // Build API endpoint URL with ULID as path parameter
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card-customer/get/' . $ulid;

            // Make the API request
            $client = Services::curlrequest();
            $response = $client->get($endpoint, [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Customer retrieved successfully',
                    'customer' => $responseData['data']['customer'] ?? null
                ];
            } else {
                // Extract error message
                $errorMessage = 'Customer not found';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Get Customer Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Update customer in Cardyfie
     * PUT /card-customer/update/{ulid}
     * 
     * Note: Email is not included in update endpoint (unlike create)
     * Image fields can be omitted to keep existing images
     */
    public function updateCustomer(string $ulid, array $customerData): array
    {
        try {
            if (empty($ulid)) {
                return [
                    'success' => false,
                    'message' => 'Customer ULID is required'
                ];
            }

            // Validate required fields (email is NOT required for update)
            $requiredFields = ['first_name', 'last_name', 'date_of_birth', 'id_type', 'id_number', 'id_front_image', 'user_image', 'house_number', 'address_line_1', 'city', 'zip_code'];
            foreach ($requiredFields as $field) {
                if (!isset($customerData[$field]) || empty($customerData[$field])) {
                    return [
                        'success' => false,
                        'message' => "Missing required field: {$field}"
                    ];
                }
            }

            // Validate ID type
            $allowedIdTypes = ['passport', 'nid', 'bvn'];
            if (!in_array(strtolower($customerData['id_type']), $allowedIdTypes)) {
                return [
                    'success' => false,
                    'message' => 'Invalid ID type. Must be one of: ' . implode(', ', $allowedIdTypes)
                ];
            }

            // Validate date format
            $dateOfBirth = $this->normalizeDate($customerData['date_of_birth']);
            if (!$dateOfBirth) {
                return [
                    'success' => false,
                    'message' => 'Invalid date format. Use YYYY-MM-DD or DD/MM/YYYY'
                ];
            }

            // Prepare payload for Cardyfie API
            $payload = [
                'first_name' => $customerData['first_name'],
                'last_name' => $customerData['last_name'],
                'date_of_birth' => $dateOfBirth,
                'id_type' => strtolower($customerData['id_type']),
                'id_number' => $customerData['id_number'],
                'id_front_image' => $customerData['id_front_image'],
                'user_image' => $customerData['user_image'],
                'house_number' => $customerData['house_number'],
                'address_line_1' => $customerData['address_line_1'],
                'city' => $customerData['city'],
                'zip_code' => $customerData['zip_code']
            ];

            // Optional fields
            if (isset($customerData['id_back_image']) && !empty($customerData['id_back_image'])) {
                $payload['id_back_image'] = $customerData['id_back_image'];
            }

            if (isset($customerData['state']) && !empty($customerData['state'])) {
                $payload['state'] = $customerData['state'];
            }

            // Meta data (optional) - can be an object or individual fields
            if (isset($customerData['meta']) && is_array($customerData['meta'])) {
                // If meta is provided as an object, we need to flatten it for the API
                // Cardyfie expects meta[user_id] format in the payload
                foreach ($customerData['meta'] as $key => $value) {
                    $payload["meta[{$key}]"] = $value;
                }
            } elseif (isset($customerData['user_id']) && !empty($customerData['user_id'])) {
                // Support direct user_id field for convenience
                $payload['meta[user_id]'] = $customerData['user_id'];
            }

            // Build API endpoint URL with ULID as path parameter
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card-customer/update/' . $ulid;

            // Make the API request (PUT method)
            $client = Services::curlrequest();
            $response = $client->put($endpoint, [
                'json' => $payload,
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Customer updated successfully',
                    'customer' => $responseData['data']['customer'] ?? null,
                    'ulid' => $ulid
                ];
            } else {
                // Extract error message
                $errorMessage = 'Customer update failed';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        } elseif (isset($responseData['message']['validation'])) {
                            $errorMessage = 'Validation error: ' . json_encode($responseData['message']['validation']);
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Update Customer Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Get available card currencies
     * GET /card/currencies
     * 
     * Returns list of currencies available for card issuance
     */
    public function getCardCurrencies(): array
    {
        try {
            // Build API endpoint URL
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/currencies';

            // Make the API request
            $client = Services::curlrequest();
            $response = $client->get($endpoint, [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Currencies retrieved successfully',
                    'currencies' => $responseData['data']['currencies'] ?? [],
                    'count' => count($responseData['data']['currencies'] ?? [])
                ];
            } else {
                // Extract error message
                $errorMessage = 'Failed to retrieve currencies';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Get Card Currencies Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Issue a card for a customer
     * POST /card/issue
     * 
     * Creates a virtual card for the specified customer
     */
    public function issueCard(array $cardData): array
    {
        try {
            // Validate required fields
            $requiredFields = ['customer_ulid', 'card_name', 'card_currency', 'card_type', 'card_provider'];
            foreach ($requiredFields as $field) {
                if (!isset($cardData[$field]) || empty($cardData[$field])) {
                    return [
                        'success' => false,
                        'message' => "Missing required field: {$field}"
                    ];
                }
            }

            // Validate card type
            $allowedCardTypes = ['universal', 'platinum'];
            if (!in_array(strtolower($cardData['card_type']), $allowedCardTypes)) {
                return [
                    'success' => false,
                    'message' => 'Invalid card type. Must be one of: ' . implode(', ', $allowedCardTypes)
                ];
            }

            // Validate card provider
            $allowedProviders = ['visa', 'mastercard'];
            if (!in_array(strtolower($cardData['card_provider']), $allowedProviders)) {
                return [
                    'success' => false,
                    'message' => 'Invalid card provider. Must be one of: ' . implode(', ', $allowedProviders)
                ];
            }

            // Prepare payload for Cardyfie API
            $payload = [
                'customer_ulid' => $cardData['customer_ulid'],
                'card_name' => $cardData['card_name'],
                'card_currency' => strtoupper($cardData['card_currency']), // Ensure uppercase
                'card_type' => strtolower($cardData['card_type']),
                'card_provider' => strtolower($cardData['card_provider'])
            ];

            // Optional meta reference_id
            if (isset($cardData['reference_id']) && !empty($cardData['reference_id'])) {
                $payload['meta[reference_id]'] = $cardData['reference_id'];
            } elseif (isset($cardData['meta']) && is_array($cardData['meta']) && isset($cardData['meta']['reference_id'])) {
                $payload['meta[reference_id]'] = $cardData['meta']['reference_id'];
            }

            // Build API endpoint URL
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/issue';

            // Make the API request (POST method)
            $client = Services::curlrequest();
            $response = $client->post($endpoint, [
                'json' => $payload,
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Card issued successfully',
                    'card' => $responseData['data']['virtual_card'] ?? null,
                    'card_ulid' => $responseData['data']['virtual_card']['ulid'] ?? null
                ];
            } else {
                // Extract error message
                $errorMessage = 'Card issuance failed';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        } elseif (isset($responseData['message']['validation'])) {
                            $errorMessage = 'Validation error: ' . json_encode($responseData['message']['validation']);
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Issue Card Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Get all cards
     * GET /card/get-all
     * 
     * Returns paginated list of all cards
     * Supports optional pagination parameters
     */
    public function getCards(int $page = 1, int $perPage = 10): array
    {
        try {
            // Build API endpoint URL
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/get-all';

            // Prepare query parameters for pagination
            $queryParams = [];
            if ($page > 1) {
                $queryParams['page'] = $page;
            }
            if ($perPage !== 10) {
                $queryParams['per_page'] = $perPage;
            }

            // Make the API request
            $client = Services::curlrequest();
            $response = $client->get($endpoint, [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'query' => $queryParams,
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                $cardsData = $responseData['data']['cards'] ?? [];
                
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Cards retrieved successfully',
                    'cards' => $cardsData['data'] ?? [],
                    'pagination' => [
                        'current_page' => $cardsData['current_page'] ?? 1,
                        'per_page' => $cardsData['per_page'] ?? 10,
                        'total' => $cardsData['total'] ?? 0,
                        'last_page' => $cardsData['last_page'] ?? 1,
                        'from' => $cardsData['from'] ?? null,
                        'to' => $cardsData['to'] ?? null,
                        'first_page_url' => $cardsData['first_page_url'] ?? null,
                        'last_page_url' => $cardsData['last_page_url'] ?? null,
                        'next_page_url' => $cardsData['next_page_url'] ?? null,
                        'prev_page_url' => $cardsData['prev_page_url'] ?? null,
                        'path' => $cardsData['path'] ?? null,
                        'links' => $cardsData['links'] ?? []
                    ],
                    'count' => count($cardsData['data'] ?? [])
                ];
            } else {
                // Extract error message
                $errorMessage = 'Failed to retrieve cards';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Get Cards Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Get card details by ULID
     * GET /card/details/{ulid}
     * 
     * Returns detailed information about a specific card including sensitive data (CVV, real PAN)
     */
    public function getCardDetails(string $cardUlid): array
    {
        try {
            if (empty($cardUlid)) {
                return [
                    'success' => false,
                    'message' => 'Card ULID is required'
                ];
            }

            // Build API endpoint URL with ULID as path parameter
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/details/' . $cardUlid;

            // Make the API request
            $client = Services::curlrequest();
            $response = $client->get($endpoint, [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Card details retrieved successfully',
                    'card' => $responseData['data']['virtual_card'] ?? null
                ];
            } else {
                // Extract error message
                $errorMessage = 'Card not found';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Get Card Details Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Deposit funds to a card
     * POST /card/deposit/{ulid}
     * 
     * Adds funds to a card balance
     */
    public function depositToCard(string $cardUlid, float $amount): array
    {
        try {
            if (empty($cardUlid)) {
                return [
                    'success' => false,
                    'message' => 'Card ULID is required'
                ];
            }

            if ($amount <= 0) {
                return [
                    'success' => false,
                    'message' => 'Amount must be greater than zero'
                ];
            }

            // Prepare payload for Cardyfie API
            // Cardyfie requires amount to be a string, not a number
            $payload = [
                'amount' => (string) $amount
            ];

            // Build API endpoint URL with ULID as path parameter
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/deposit/' . $cardUlid;

            // Make the API request (POST method)
            $client = Services::curlrequest();
            $response = $client->post($endpoint, [
                'json' => $payload,
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Card deposited successfully',
                    'card_ulid' => $cardUlid,
                    'amount' => $amount
                ];
            } else {
                // Extract error message
                $errorMessage = 'Card deposit failed';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        } elseif (isset($responseData['message']['validation'])) {
                            $errorMessage = 'Validation error: ' . json_encode($responseData['message']['validation']);
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Card Deposit Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Withdraw funds from a card
     * POST /card/withdraw/{ulid}
     * 
     * Removes funds from a card balance
     */
    public function withdrawFromCard(string $cardUlid, float $amount): array
    {
        try {
            if (empty($cardUlid)) {
                return [
                    'success' => false,
                    'message' => 'Card ULID is required'
                ];
            }

            if ($amount <= 0) {
                return [
                    'success' => false,
                    'message' => 'Amount must be greater than zero'
                ];
            }

            // Prepare payload for Cardyfie API
            // Cardyfie requires amount to be a string, not a number
            $payload = [
                'amount' => (string) $amount
            ];

            // Build API endpoint URL with ULID as path parameter
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/withdraw/' . $cardUlid;

            // Make the API request (POST method)
            $client = Services::curlrequest();
            $response = $client->post($endpoint, [
                'json' => $payload,
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                // Extract success message (may say "Card Deposited Successfully!" in docs but should be withdrawal)
                $successMessage = $responseData['message']['success'][0] ?? 'Card withdrawal completed successfully';
                
                return [
                    'success' => true,
                    'message' => $successMessage,
                    'card_ulid' => $cardUlid,
                    'amount' => $amount
                ];
            } else {
                // Extract error message
                $errorMessage = 'Card withdrawal failed';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        } elseif (isset($responseData['message']['validation'])) {
                            $errorMessage = 'Validation error: ' . json_encode($responseData['message']['validation']);
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Card Withdraw Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Get card transactions
     * GET /card/transactions
     * 
     * Returns transactions for a specific card or all cards
     * If card_ulid is provided, returns transactions for that card only
     * If card_ulid is not provided, returns all card transactions
     */
    public function getCardTransactions(?string $cardUlid = null): array
    {
        try {
            // Build API endpoint URL
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/transactions';

            // Prepare query parameters
            $queryParams = [];
            if (!empty($cardUlid)) {
                $queryParams['card_ulid'] = $cardUlid;
            }

            // Make the API request
            $client = Services::curlrequest();
            $response = $client->get($endpoint, [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'query' => $queryParams,
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                $transactions = $responseData['data']['transactions'] ?? [];
                
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Transactions retrieved successfully',
                    'transactions' => $transactions,
                    'count' => count($transactions),
                    'card_ulid' => $cardUlid // Include card_ulid in response for reference
                ];
            } else {
                // Extract error message
                $errorMessage = 'Failed to retrieve transactions';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Get Card Transactions Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Freeze a card
     * POST /card/freeze/{ulid}
     * 
     * Freezes a card, preventing it from being used for transactions
     */
    public function freezeCard(string $cardUlid): array
    {
        try {
            if (empty($cardUlid)) {
                return [
                    'success' => false,
                    'message' => 'Card ULID is required'
                ];
            }

            // Build API endpoint URL with ULID as path parameter
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/freeze/' . $cardUlid;

            // Make the API request (POST method with empty body)
            $client = Services::curlrequest();
            $response = $client->post($endpoint, [
                'json' => [], // Empty body as per API documentation
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Card freeze successfully!',
                    'card_ulid' => $cardUlid
                ];
            } else {
                // Extract error message
                $errorMessage = 'Card freeze failed';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        } elseif (isset($responseData['message']['validation'])) {
                            $errorMessage = 'Validation error: ' . json_encode($responseData['message']['validation']);
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Card Freeze Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Unfreeze a card
     * POST /card/unfreeze/{ulid}
     * 
     * Unfreezes a card, allowing it to be used for transactions again
     */
    public function unfreezeCard(string $cardUlid): array
    {
        try {
            if (empty($cardUlid)) {
                return [
                    'success' => false,
                    'message' => 'Card ULID is required'
                ];
            }

            // Build API endpoint URL with ULID as path parameter
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/unfreeze/' . $cardUlid;

            // Make the API request (POST method with empty body)
            $client = Services::curlrequest();
            $response = $client->post($endpoint, [
                'json' => [], // Empty body as per API documentation
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Card unfreeze successfully!',
                    'card_ulid' => $cardUlid
                ];
            } else {
                // Extract error message
                $errorMessage = 'Card unfreeze failed';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        } elseif (isset($responseData['message']['validation'])) {
                            $errorMessage = 'Validation error: ' . json_encode($responseData['message']['validation']);
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Card Unfreeze Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Close a card
     * POST /card/close/{ulid}
     * 
     * Permanently closes a card. This action is irreversible.
     */
    public function closeCard(string $cardUlid): array
    {
        try {
            if (empty($cardUlid)) {
                return [
                    'success' => false,
                    'message' => 'Card ULID is required'
                ];
            }

            // Build API endpoint URL with ULID as path parameter
            $endpoint = $this->apiBaseUrl . '/' . $this->environment . '/v1/card/close/' . $cardUlid;

            // Make the API request (POST method with empty body)
            $client = Services::curlrequest();
            $response = $client->post($endpoint, [
                'json' => [], // Empty body as per API documentation
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->getDecryptedApiKey(),
                    'Accept' => 'application/json',
                    'Content-Type' => 'application/json'
                ],
                'timeout' => 30,
                'verify' => ($_ENV['cardyfie.verify_ssl'] ?? 'true') === 'true',
                'http_errors' => false
            ]);

            $responseData = json_decode($response->getBody(), true);
            $statusCode = $response->getStatusCode();

            if ($statusCode === 200 && isset($responseData['type']) && $responseData['type'] === 'success') {
                return [
                    'success' => true,
                    'message' => $responseData['message']['success'][0] ?? 'Card closed successfully!',
                    'card_ulid' => $cardUlid
                ];
            } else {
                // Extract error message
                $errorMessage = 'Card close failed';
                if (isset($responseData['message'])) {
                    if (is_array($responseData['message'])) {
                        if (isset($responseData['message']['error'])) {
                            $errorMessage = is_array($responseData['message']['error']) 
                                ? implode(', ', $responseData['message']['error'])
                                : $responseData['message']['error'];
                        } elseif (isset($responseData['message']['validation'])) {
                            $errorMessage = 'Validation error: ' . json_encode($responseData['message']['validation']);
                        }
                    } else {
                        $errorMessage = $responseData['message'];
                    }
                }

                return [
                    'success' => false,
                    'message' => $errorMessage,
                    'error_code' => $statusCode,
                    'raw_response' => $responseData
                ];
            }

        } catch (\Exception $e) {
            log_message('error', 'Cardyfie Card Close Error: ' . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Internal server error occurred',
                'error' => $e->getMessage()
            ];
        }
    }

    /**
     * Get the API base URL
     */
    public function getApiBaseUrl(): string
    {
        return $this->apiBaseUrl;
    }

    /**
     * Get the current environment
     */
    public function getEnvironment(): string
    {
        return $this->environment;
    }
}

