<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Order;
use App\Models\Setting;
use Illuminate\Http\Request;
use Razorpay\Api\Api as RazorpayApi;

class PaymentController extends Controller
{
    private function razorpay(): RazorpayApi
    {
        $keyId     = Setting::get('razorpay_key_id')     ?: env('RAZORPAY_KEY_ID');
        $keySecret = Setting::get('razorpay_key_secret') ?: env('RAZORPAY_KEY_SECRET');
        return new RazorpayApi($keyId, $keySecret);
    }

    // ─── RAZORPAY ─────────────────────────────────────────────────────────────

    public function razorpayCreateOrder(Request $request)
    {
        $request->validate(['amount' => 'required|numeric|min:1']);

        $amountPaise = (int) round($request->amount * 100);

        $order = $this->razorpay()->order->create([
            'amount'          => $amountPaise,
            'currency'        => 'INR',
            'receipt'         => 'receipt_' . uniqid(),
            'payment_capture' => 1,
        ]);

        return response()->json([
            'success'   => true,
            'order_id'  => $order->id,
            'amount'    => $amountPaise,
            'currency'  => 'INR',
            'key'       => Setting::get('razorpay_key_id') ?: env('RAZORPAY_KEY_ID'),
        ]);
    }

    public function razorpayVerify(Request $request)
    {
        $request->validate([
            'razorpay_order_id'   => 'required|string',
            'razorpay_payment_id' => 'required|string',
            'razorpay_signature'  => 'required|string',
            'order_id'            => 'required|integer|exists:orders,id',
        ]);

        $keySecret = Setting::get('razorpay_key_secret') ?: env('RAZORPAY_KEY_SECRET');
        $expectedSignature = hash_hmac(
            'sha256',
            $request->razorpay_order_id . '|' . $request->razorpay_payment_id,
            $keySecret
        );

        if ($expectedSignature !== $request->razorpay_signature) {
            return response()->json(['success' => false, 'message' => 'Payment verification failed'], 422);
        }

        $order = Order::findOrFail($request->order_id);
        $order->update([
            'payment_status'     => 'paid',
            'payment_id'         => $request->razorpay_payment_id,
            'payment_gateway'    => 'razorpay',
            'status'             => 'processing',
        ]);

        return response()->json(['success' => true, 'message' => 'Payment verified']);
    }

    // ─── PHONEPE ──────────────────────────────────────────────────────────────

    public function phonepayInitiate(Request $request)
    {
        $request->validate([
            'amount'    => 'required|numeric|min:1',
            'order_id'  => 'required|integer|exists:orders,id',
        ]);

        $merchantId        = Setting::get('phonepe_merchant_id')  ?: env('PHONEPE_MERCHANT_ID');
        $saltKey           = Setting::get('phonepe_salt_key')     ?: env('PHONEPE_SALT_KEY');
        $saltIndex         = Setting::get('phonepe_salt_index')   ?: env('PHONEPE_SALT_INDEX', 1);
        $amountPaise       = (int) round($request->amount * 100);
        $merchantTxnId     = 'TXN_' . $request->order_id . '_' . time();
        $callbackUrl       = env('FRONTEND_URL') . '/order-confirmation?order=' . $request->order_id;
        $redirectUrl       = env('FRONTEND_URL') . '/order-confirmation?order=' . $request->order_id;

        $payload = [
            'merchantId'            => $merchantId,
            'merchantTransactionId' => $merchantTxnId,
            'merchantUserId'        => 'USER_' . ($request->user()?->id ?? 'guest'),
            'amount'                => $amountPaise,
            'redirectUrl'           => $redirectUrl,
            'redirectMode'          => 'REDIRECT',
            'callbackUrl'           => $callbackUrl,
            'paymentInstrument'     => ['type' => 'PAY_PAGE'],
        ];

        $base64Payload = base64_encode(json_encode($payload));
        $checksum      = hash('sha256', $base64Payload . '/pg/v1/pay' . $saltKey) . '###' . $saltIndex;

        $phonepeEnv = Setting::get('phonepe_env') ?: env('PHONEPE_ENV', 'sandbox');
        $apiUrl = $phonepeEnv === 'production'
            ? 'https://api.phonepe.com/apis/hermes/pg/v1/pay'
            : 'https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/pay';

        $ch = curl_init($apiUrl);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode(['request' => $base64Payload]),
            CURLOPT_HTTPHEADER     => [
                'Content-Type: application/json',
                'X-VERIFY: ' . $checksum,
                'X-MERCHANT-ID: ' . $merchantId,
            ],
            CURLOPT_TIMEOUT        => 15,
        ]);
        $response = curl_exec($ch);
        curl_close($ch);

        $data = json_decode($response, true);

        if (!isset($data['success']) || !$data['success']) {
            return response()->json(['success' => false, 'message' => $data['message'] ?? 'PhonePe initiation failed'], 422);
        }

        $redirectUrl = $data['data']['instrumentResponse']['redirectInfo']['url'] ?? null;

        // Store txn id on order for callback verification
        Order::findOrFail($request->order_id)->update([
            'payment_id'      => $merchantTxnId,
            'payment_gateway' => 'phonepe',
        ]);

        return response()->json([
            'success'      => true,
            'redirect_url' => $redirectUrl,
            'txn_id'       => $merchantTxnId,
        ]);
    }

    public function phonepayCallback(Request $request)
    {
        $saltKey   = Setting::get('phonepe_salt_key')   ?: env('PHONEPE_SALT_KEY');
        $saltIndex = Setting::get('phonepe_salt_index') ?: env('PHONEPE_SALT_INDEX', 1);
        $xVerify   = $request->header('X-VERIFY');

        $base64Response = $request->input('response');
        $expectedChecksum = hash('sha256', $base64Response . $saltKey) . '###' . $saltIndex;

        if ($xVerify !== $expectedChecksum) {
            return response()->json(['success' => false, 'message' => 'Invalid callback signature'], 422);
        }

        $decoded = json_decode(base64_decode($base64Response), true);
        $txnId   = $decoded['data']['merchantTransactionId'] ?? null;
        $code    = $decoded['code'] ?? '';

        if ($txnId) {
            $orderId = explode('_', $txnId)[1] ?? null;
            if ($orderId) {
                $order = Order::find($orderId);
                if ($order) {
                    $order->update([
                        'payment_status' => $code === 'PAYMENT_SUCCESS' ? 'paid' : 'failed',
                        'status'         => $code === 'PAYMENT_SUCCESS' ? 'processing' : 'pending',
                    ]);
                }
            }
        }

        return response()->json(['success' => true]);
    }
}
