<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\VipPackage;
use App\Models\UserSubscription;
use App\Models\TransactionFee;
use App\Services\SettingService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;
use Carbon\Carbon;

class SubscriptionController extends Controller
{
    /**
     * Create or renew a subscription for a given VIP package.
     * POST /api/subscriptions
     */
    public function store(Request $request)
    {
        $request->validate([
            'vip_package_id' => 'required|exists:vip_packages,id',
        ]);

        $user = $request->user();
        $packageId = $request->input('vip_package_id');
        $package = VipPackage::findOrFail($packageId);

        // Parse the USD price from the package (e.g. "$49.99" → 49.99)
        $amountUsd = (float) preg_replace('/[^\d.]/', '', $package->price ?? '0');
        $transactionRef = $request->input('transaction_ref') ?? $request->input('tx_ref');

        // Calculate subscription dates
        $startsAt = Carbon::now();
        $endsAt = Carbon::now()->addDays($package->duration_days ?? 28);

        // Check if there is an existing subscription
        $subscription = UserSubscription::where('user_id', $user->id)
            ->where('vip_package_id', $packageId)
            ->first();

        $paymentData = [
            'payment_method'  => 'card',
            'amount_usd'      => $amountUsd > 0 ? $amountUsd : null,
            'transaction_ref' => $transactionRef,
        ];

        if ($subscription) {
            // If already active, extend it. Otherwise start fresh.
            if ($subscription->isActive()) {
                $startsAt = $subscription->ends_at;
                $endsAt = $startsAt->copy()->addDays($package->duration_days ?? 28);
            }

            $subscription->update(array_merge([
                'starts_at' => $startsAt,
                'ends_at'   => $endsAt,
                'status'    => 'active',
            ], $paymentData));
        } else {
            $subscription = UserSubscription::create(array_merge([
                'user_id'        => $user->id,
                'vip_package_id' => $packageId,
                'starts_at'      => $startsAt,
                'ends_at'        => $endsAt,
                'status'         => 'active',
            ], $paymentData));
        }

        return response()->json([
            'message'      => 'Subscription activated successfully!',
            'subscription' => $subscription,
        ]);
    }

    /**
     * Initiate a Relworx Mobile Money payment prompt.
     * POST /api/payment/relworx/initiate
     */
    public function relworxInitiate(Request $request)
    {
        $request->validate([
            'vip_package_id' => 'required|exists:vip_packages,id',
            'phone'          => 'required|string',
        ]);

        $user = $request->user();
        $package = VipPackage::findOrFail($request->vip_package_id);

        // Sanitize phone
        $phone = preg_replace('/\D/', '', $request->phone);
        if (str_starts_with($phone, '0')) {
            $phone = substr($phone, 1);
        }
        if (strlen($phone) !== 9) {
            return response()->json(['message' => 'Invalid phone number format. Must be a 9-digit number.'], 400);
        }

        // Convert USD price to UGX
        $usdPrice = (float) preg_replace('/[^\d.]/', '', $package->price ?? '49.99');
        $usdToUgx = (float) (\App\Models\Setting::where('key', 'usd_to_ugx')->value('value') ?? '3700');
        $amountUgx = round($usdPrice * $usdToUgx);

        // Relworx keys — decrypted transparently by SettingService
        $apiKey    = SettingService::get('relworx_api_key', 'placeholder_key');
        $accountNo = SettingService::get('relworx_account_no', 'RELJH012BV45P');

        $reference = 'MM-' . time() . '-' . rand(1000, 9999);

        // Check if placeholder is used
        if ($apiKey === 'placeholder_key') {
            $internalReference = 'SIM-' . time() . '-' . rand(10000, 99999);
            
            Cache::put($internalReference, [
                'user_id'        => $user->id,
                'vip_package_id' => $package->id,
                'amount'         => $amountUgx,
                'checks'         => 0,
                'is_simulated'   => true,
            ], 600); // 10 minutes cache expiration

            return response()->json([
                'success'            => true,
                'message'            => 'Request payment in progress (simulated).',
                'internal_reference' => $internalReference,
                'amount_ugx'         => $amountUgx,
            ]);
        }

        try {
            $response = Http::withHeaders([
                'Accept'        => 'application/vnd.relworx.v2',
                'Authorization' => 'Bearer ' . $apiKey,
            ])->post('https://payments.relworx.com/api/mobile-money/request-payment', [
                'account_no'  => $accountNo,
                'reference'   => $reference,
                'msisdn'      => '+256' . $phone,
                'currency'    => 'UGX',
                'amount'      => $amountUgx,
                'description' => 'Match Metrix - ' . $package->title,
            ]);

            if ($response->successful()) {
                $data = $response->json();
                $internalReference = $data['internal_reference'] ?? null;

                if ($internalReference) {
                    Cache::put($internalReference, [
                        'user_id'        => $user->id,
                        'vip_package_id' => $package->id,
                        'amount'         => $amountUgx,
                        'is_simulated'   => false,
                    ], 1800); // 30 minutes cache expiration

                    return response()->json([
                        'success'            => true,
                        'message'            => $data['message'] ?? 'Request payment in progress.',
                        'internal_reference' => $internalReference,
                        'amount_ugx'         => $amountUgx,
                    ]);
                }
            }

            $errorMsg = $response->json()['message'] ?? 'Relworx payment request failed.';
            return response()->json(['message' => $errorMsg], 400);

        } catch (\Exception $e) {
            return response()->json(['message' => 'Connection to Relworx failed: ' . $e->getMessage()], 500);
        }
    }

    /**
     * Poll the status of a Relworx transaction.
     * GET /api/payment/relworx/status
     */
    public function relworxStatus(Request $request)
    {
        $request->validate([
            'internal_reference' => 'required|string',
        ]);

        $internalReference = $request->internal_reference;
        $tx = Cache::get($internalReference);

        if (!$tx) {
            return response()->json([
                'status'  => 'failed',
                'message' => 'Transaction not found or expired.',
            ], 404);
        }

        // If simulated transaction
        if (isset($tx['is_simulated']) && $tx['is_simulated']) {
            $checks = $tx['checks'] + 1;

            if ($checks >= 3) {
                // Activate subscription with mobile_money payment method
                $this->activateSubscription($tx['user_id'], $tx['vip_package_id'], [
                    'payment_method'  => 'mobile_money',
                    'amount_ugx'      => $tx['amount'] ?? null,
                    'transaction_ref' => $internalReference,
                ]);
                Cache::forget($internalReference);

                return response()->json([
                    'status'  => 'success',
                    'message' => 'Simulated payment completed successfully.',
                ]);
            }

            // Update checks counter in cache
            $tx['checks'] = $checks;
            Cache::put($internalReference, $tx, 600);

            return response()->json([
                'status'  => 'pending',
                'message' => 'Awaiting user PIN confirmation (simulated)...',
            ]);
        }

        // Real Relworx Status Check — decrypted transparently by SettingService
        $apiKey    = SettingService::get('relworx_api_key');
        $accountNo = SettingService::get('relworx_account_no');

        try {
            $response = Http::withHeaders([
                'Accept'        => 'application/vnd.relworx.v2',
                'Authorization' => 'Bearer ' . $apiKey,
            ])->get('https://payments.relworx.com/api/mobile-money/check-request-status', [
                'account_no'         => $accountNo,
                'internal_reference' => $internalReference,
            ]);

            if ($response->successful()) {
                $data = $response->json();
                $status = strtolower($data['request_status'] ?? 'pending');

                if ($status === 'success') {
                    // Activate subscription with mobile_money payment metadata
                    $this->activateSubscription($tx['user_id'], $tx['vip_package_id'], [
                        'payment_method'  => 'mobile_money',
                        'amount_ugx'      => $tx['amount'] ?? null,
                        'transaction_ref' => $internalReference,
                    ]);
                    Cache::forget($internalReference);

                    return response()->json([
                        'status'  => 'success',
                        'message' => 'Payment completed successfully.',
                    ]);
                } elseif ($status === 'failed' || $status === 'cancelled') {
                    Cache::forget($internalReference);

                    return response()->json([
                        'status'  => 'failed',
                        'message' => $data['message'] ?? 'Payment failed.',
                    ]);
                } else {
                    return response()->json([
                        'status'  => 'pending',
                        'message' => 'Payment is pending user approval.',
                    ]);
                }
            }

            return response()->json([
                'status'  => 'pending',
                'message' => 'Could not retrieve transaction status from Relworx.',
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'status'  => 'pending',
                'message' => 'Error checking Relworx status.',
            ]);
        }
    }

    /**
     * Helper method to activate subscription.
     * @param int   $userId
     * @param int   $packageId
     * @param array $paymentMeta  Optional payment metadata (method, amounts, ref)
     */
    private function activateSubscription(int $userId, int $packageId, array $paymentMeta = []): void
    {
        $package   = VipPackage::findOrFail($packageId);
        $amountUsd = (float) preg_replace('/[^\d.]/', '', $package->price ?? '0');

        $startsAt = Carbon::now();
        $endsAt   = Carbon::now()->addDays($package->duration_days ?? 28);

        $subscription = UserSubscription::where('user_id', $userId)
            ->where('vip_package_id', $packageId)
            ->first();

        // Default payment meta if not set
        $meta = array_merge([
            'payment_method'  => 'mobile_money',
            'amount_usd'      => $amountUsd > 0 ? $amountUsd : null,
            'amount_ugx'      => null,
            'transaction_ref' => null,
        ], $paymentMeta);

        if ($subscription) {
            if ($subscription->isActive()) {
                $startsAt = $subscription->ends_at;
                $endsAt   = $startsAt->copy()->addDays($package->duration_days ?? 28);
            }
            $subscription->update(array_merge([
                'starts_at' => $startsAt,
                'ends_at'   => $endsAt,
                'status'    => 'active',
            ], $meta));
            $saved = $subscription;
        } else {
            $saved = UserSubscription::create(array_merge([
                'user_id'        => $userId,
                'vip_package_id' => $packageId,
                'starts_at'      => $startsAt,
                'ends_at'        => $endsAt,
                'status'         => 'active',
            ], $meta));
        }

        // Record a 2% Relworx deposit processing fee (stored silently, not shown on admin panel)
        if (($meta['payment_method'] ?? '') === 'mobile_money' && !empty($meta['amount_ugx'])) {
            TransactionFee::recordDepositFee($saved);
        }
    }
}

