<?php

namespace App\Services;

use App\Contracts\PaymentGatewayInterface;
use App\Models\PaymentProvider;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class EcocashService implements PaymentGatewayInterface
{
    protected $provider;
    protected $config;

    public function __construct()
    {
        $this->provider = PaymentProvider::where('code', 'ECOCASH')->first();
        $this->config = $this->provider ? $this->provider->configuration : [];
    }

    /**
     * Initialize a payment transaction
     */
    public function initiatePayment(array $data): array
    {
        try {
            // Validate required data
            $this->validatePaymentData($data);

            // Prepare Ecocash API request
            $requestData = [
                'merchant_code' => $this->config['merchant_code'] ?? '',
                'merchant_secret' => $this->config['merchant_secret'] ?? '',
                'amount' => $data['amount'],
                'currency' => $data['currency'] ?? 'USD',
                'phone_number' => $this->formatPhoneNumber($data['phone']),
                'reference' => $data['reference'],
                'callback_url' => $data['callback_url'] ?? route('payments.callback', ['provider' => 'ecocash']),
                'description' => $data['description'] ?? 'Payment',
            ];

            // Make API call to Ecocash
            $response = Http::timeout(30)
                ->post($this->provider->base_url . '/api/initiate', $requestData);

            if ($response->successful()) {
                $responseData = $response->json();

                Log::info('Ecocash payment initiated', [
                    'reference' => $data['reference'],
                    'transaction_id' => $responseData['transaction_id'] ?? null,
                    'status' => 'initiated'
                ]);

                return [
                    'success' => true,
                    'transaction_id' => $responseData['transaction_id'],
                    'reference' => $data['reference'],
                    'status' => 'pending',
                    'message' => 'Payment initiated successfully',
                    'gateway_response' => $responseData
                ];
            }

            Log::error('Ecocash payment initiation failed', [
                'reference' => $data['reference'],
                'response' => $response->body()
            ]);

            return [
                'success' => false,
                'message' => 'Payment initiation failed',
                'error' => $response->json()
            ];

        } catch (\Exception $e) {
            Log::error('Ecocash payment initiation error', [
                'reference' => $data['reference'] ?? null,
                'error' => $e->getMessage()
            ]);

            return [
                'success' => false,
                'message' => 'Payment initiation error: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Check the status of a payment transaction
     */
    public function checkPaymentStatus(string $transactionId): array
    {
        try {
            $response = Http::timeout(30)
                ->get($this->provider->base_url . '/api/status/' . $transactionId, [
                    'merchant_code' => $this->config['merchant_code'],
                    'merchant_secret' => $this->config['merchant_secret'],
                ]);

            if ($response->successful()) {
                $statusData = $response->json();

                return [
                    'success' => true,
                    'transaction_id' => $transactionId,
                    'status' => $this->mapStatus($statusData['status']),
                    'gateway_response' => $statusData
                ];
            }

            return [
                'success' => false,
                'message' => 'Status check failed',
                'error' => $response->json()
            ];

        } catch (\Exception $e) {
            Log::error('Ecocash status check error', [
                'transaction_id' => $transactionId,
                'error' => $e->getMessage()
            ]);

            return [
                'success' => false,
                'message' => 'Status check error: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Process a callback from Ecocash
     */
    public function processCallback(array $callbackData): array
    {
        try {
            // Validate callback authenticity
            if (!$this->validateCallback($callbackData)) {
                return [
                    'success' => false,
                    'message' => 'Invalid callback signature'
                ];
            }

            $transactionId = $callbackData['transaction_id'];
            $status = $this->mapStatus($callbackData['status']);
            $reference = $callbackData['reference'];

            Log::info('Ecocash callback processed', [
                'transaction_id' => $transactionId,
                'reference' => $reference,
                'status' => $status
            ]);

            return [
                'success' => true,
                'transaction_id' => $transactionId,
                'reference' => $reference,
                'status' => $status,
                'callback_data' => $callbackData
            ];

        } catch (\Exception $e) {
            Log::error('Ecocash callback processing error', [
                'error' => $e->getMessage(),
                'callback_data' => $callbackData
            ]);

            return [
                'success' => false,
                'message' => 'Callback processing error: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Validate callback data authenticity
     */
    public function validateCallback(array $callbackData): bool
    {
        // Implement HMAC signature validation
        $expectedSignature = hash_hmac(
            'sha256',
            json_encode($callbackData),
            $this->config['webhook_secret'] ?? ''
        );

        return hash_equals($expectedSignature, $callbackData['signature'] ?? '');
    }

    /**
     * Get the gateway name
     */
    public function getGatewayName(): string
    {
        return 'Ecocash';
    }

    /**
     * Check if the gateway is available/active
     */
    public function isAvailable(): bool
    {
        return $this->provider && $this->provider->status === 'active';
    }

    /**
     * Validate payment data
     */
    private function validatePaymentData(array $data): void
    {
        $required = ['amount', 'phone', 'reference'];
        foreach ($required as $field) {
            if (!isset($data[$field]) || empty($data[$field])) {
                throw new \InvalidArgumentException("Missing required field: {$field}");
            }
        }

        if (!is_numeric($data['amount']) || $data['amount'] <= 0) {
            throw new \InvalidArgumentException('Invalid amount');
        }
    }

    /**
     * Format phone number for Ecocash
     */
    private function formatPhoneNumber(string $phone): string
    {
        // Remove any non-numeric characters
        $phone = preg_replace('/\D/', '', $phone);

        // Add country code if missing (assuming Zimbabwe +263)
        if (strlen($phone) === 9 && $phone[0] === '7') {
            $phone = '263' . $phone;
        }

        return $phone;
    }

    /**
     * Map Ecocash status to internal status
     */
    private function mapStatus(string $ecocashStatus): string
    {
        $statusMap = [
            'PENDING' => 'pending',
            'PROCESSING' => 'processing',
            'COMPLETED' => 'completed',
            'FAILED' => 'failed',
            'CANCELLED' => 'cancelled',
            'TIMEOUT' => 'timeout'
        ];

        return $statusMap[strtoupper($ecocashStatus)] ?? 'unknown';
    }
}
