<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\CcService;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
use App\Models\Deposit;
use App\Models\User;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\DB;

class WebhookController extends Controller
{
    protected string $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36';

    public function handleDepositWebhook(Request $request, CcService $CcService)
    {
        $allowedIPs = ["54.150.123.157", "35.72.150.75", "18.176.186.244"];
        $remoteIP = $request->header('CF-Connecting-IP', $request->ip());

        if (!in_array($remoteIP, $allowedIPs)) {
            Log::warning("Unauthorized IP: $remoteIP tried to access webhook.");
            return response("Access Denied.", Response::HTTP_MULTIPLE_CHOICES);
        }

        $appID = get_setting('cc_app_id');
        $appSecret = get_setting('cc_app_secret');

        $headers = $request->headers->all();
        $timestamp = $headers['timestamp'][0] ?? null;
        $signature = $headers['sign'][0] ?? null;

        if ($timestamp && $signature) {
            $body = $request->getContent();
            $webhook = json_decode($body, true);

            if (!$timestamp || !$signature || !$webhook) {
                Log::warning("Invalid Request");
                return response("Invalid Request", Response::HTTP_BAD_REQUEST);
            }

            $computedSignature = hash_hmac('sha256', $appID . $timestamp . $body, $appSecret);
            if ($signature !== $computedSignature) {
                Log::error("Invalid signature: Received $signature, Computed $computedSignature");
                return response("Invalid Signature", Response::HTTP_UNAUTHORIZED);
            }

            $recordId = $webhook['msg']['recordId'] ?? null;

            if ($webhook['type'] === 'DirectDeposit') {
                if (!$recordId) {
                    return response("Invalid Data", Response::HTTP_BAD_REQUEST);
                }
                if ($webhook['msg']['status'] === 'Success') {
                    return $CcService->processTransaction($recordId, $webhook['msg']['coinSymbol']);
                }
                if ($webhook['msg']['status'] === 'Processing') {
                    Log::info("Processing deposit for recordId: $recordId");

                    $exists = Deposit::where('txn_id', $recordId)->exists();
                    if (!$exists) {
                        $referenceId = $webhook['msg']['referenceId'] ?? null;
                        $userId = explode('-', $referenceId)[1] ?? null;

                        if ($userId) {
                            Deposit::create([
                                'user_id'    => $userId,
                                'method'     => $webhook['msg']['coinSymbol'] . ' Direct',
                                'amount'     => 0,
                                'status'     => 'pending',
                                'txn_id'     => $recordId,
                                'created_at' => now()
                            ]);
                        } else {
                            Log::warning("Invalid referenceId format: $referenceId");
                        }
                    }
                }
            }
        }

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

    public function faucetpay(Request $request)
    {
        $token = $request->input('token');
        $url   = "https://faucetpay.io/merchant/get-payment/{$token}";

        try {
            $response = Http::withHeaders([
                'User-Agent' => $this->userAgent,
                'Accept'     => 'application/json',
            ])->get($url);

            $paymentInfo = $response->json();

            $this->processPayment($paymentInfo);
        } catch (\Exception $e) {
            $context = stream_context_create([
                'http' => [
                    'header' => "User-Agent: {$this->userAgent}\r\nAccept: application/json\r\n",
                ]
            ]);

            $fileContents = file_get_contents($url, false, $context);
            $paymentInfo  = json_decode($fileContents, true);

            $this->processPayment($paymentInfo);
        }
    }

    private function processPayment($paymentInfo)
    {
        $tokenStatus       = $paymentInfo['valid'] ?? false;
        $merchantUsername  = strtolower($paymentInfo['merchant_username'] ?? '');
        $amount1           = $paymentInfo['amount1'] ?? 0;
        $currency1         = $paymentInfo['currency1'] ?? '';
        $amount2           = $paymentInfo['amount2'] ?? 0;
        $currency2         = $paymentInfo['currency2'] ?? '';
        $custom            = $paymentInfo['custom'] ?? '';
        $trans             = $paymentInfo['transaction_id'] ?? '';
        $username          = strtolower(get_setting('faucetpay_username'));

        if ($tokenStatus && $merchantUsername == $username && $currency1 == 'USDT' && $amount1 >= get_setting('faucetpay_minimum_deposit')) {
            $user = User::find($custom);

            if (!$user) {
                return response()->json(['error' => 'Invalid user ID'], 400);
            }

            Deposit::create([
                'user_id'    => $user->id,
                'method'     => strtoupper($currency2) . ' FaucetPay',
                'amount'     => $amount1,
                'status'     => 'completed',
                'txn_id'     => $trans,
                'created_at' => now(),
            ]);

            User::where('id', $user['id'])->update([
                'available_deposit' => DB::raw("available_deposit + $amount1"),
                'deposited'         => DB::raw("deposited + $amount1")
            ]);
        }
    }
}