<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Models\Transaction;
use App\Models\Bonus;
use Carbon\Carbon;

class SeamlesWsController extends Controller
{
    public $api;
    public $pga;

    public function __construct()
    {
        $this->api = DB::table('api_providers')->where('provider', 'NEXUSGGR')->first();
        $this->pga = DB::table('api_providers')->where('provider', 'VIP')->first();
    }
    
    public function syncTurnover()
    {
        set_time_limit(0); 
        $end = Carbon::now()->format('Y-m-d H:i:s'); 
        $gameTypes = ['slot','casino','sportsbook']; 
        
        $totalInserted = 0;
        $userCount = 0;
    
        User::chunk(50, function ($users) use ($gameTypes, $end, &$totalInserted, &$userCount) {
            foreach ($users as $user) {
                if (empty($user->extplayer)) {
                    continue;
                }
    
                $start = $user->created_at ? $user->created_at->format('Y-m-d H:i:s') : Carbon::now()->subYear()->format('Y-m-d H:i:s');
    
                foreach ($gameTypes as $game_type) {
                    try {
                        $response = $this->getGameHistory($user->extplayer, $game_type, $start, $end);
                        $result = json_decode($response, true);
    
                        if (!isset($result['status']) || $result['status'] !== 1 || empty($result[$game_type])) {
                            continue; 
                        }
    
                        $bets = $result[$game_type];
                        $insertData = [];
    
                        foreach ($bets as $bet) {
                            if ($bet['bet_money'] > 0) {
                                $insertData[] = [
                                    'user_id'          => $user->id,
                                    'game_type'        => strtolower($game_type),
                                    'ticket_id'        => $bet['txn_id'], 
                                    'valid_bet_amount' => (float) $bet['bet_money'],
                                    'is_calculated'    => 0,
                                    'bet_time'         => Carbon::parse($bet['created_at'])->format('Y-m-d H:i:s'),
                                    'created_at'       => now(),
                                    'updated_at'       => now(),
                                ];
                            }
                        }
    
                        if (!empty($insertData)) {
                            $chunks = array_chunk($insertData, 500);
                            foreach ($chunks as $chunk) {
                                DB::table('turnover_logs')->upsert($chunk, ['ticket_id'], ['updated_at']);
                            }
                            $totalInserted += count($insertData);
                        }
                        usleep(500000); 
                    } catch (\Exception $e) {
                        Log::error("Gagal Sync History User {$user->extplayer} - Game {$game_type}: " . $e->getMessage());
                    }
                }
                $userCount++;
            }
        });
    
        return response()->json([
            'success' => true, 
            'message' => 'Proses Penarikan Raksasa Selesai!', 
            'total_user_scanned' => $userCount,
            'total_bet_inserted' => $totalInserted
        ]);
    }
    
    public function create($extplayer)
    {
        $postdata = [
            'method' => 'user_create',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'user_code' => $extplayer,
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }
    
    public function agentBalance()
    {
        $postdata = [
            'method' => 'money_info',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? ''
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }

    public function getBalance($extplayer)
    {
        $postdata = [
            'method' => 'money_info',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'user_code' => $extplayer,
        ];

        $response = $this->curl_postc_2($this->api->url ?? '', $postdata);
        $result = json_decode($response);
        $user = User::where('extplayer', $extplayer)->first();

        if ($user && isset($result->user->balance)) {
            $user->balance = $result->user->balance;
            $user->save();
            return $result->user->balance;
        }

        return $user ? $user->balance : 0;
    }

    public function getBalance2()
    {
        if (!auth()->check()) {
            return response()->json(['d' => 'IDR 0']);
        }
        
        $extplayer = auth()->user()->extplayer;
        $saldoTerbaru = $this->getBalance($extplayer);
        
        return response()->json([
            'd' => 'IDR ' . number_format((float)$saldoTerbaru, 0, ',', '.')
        ]);
    }

    public function deposit($extplayer, $amount, $trx_id)
    {
        $postdata = [
            'method' => 'user_deposit',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'user_code' => $extplayer,
            'amount' => $amount,
            'agent_sign' => $trx_id,
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }

    public function withdraw($extplayer, $amount, $trx_id)
    {
        $postdata = [
            'method' => 'user_withdraw',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'user_code' => $extplayer,
            'amount' => $amount,
            'agent_sign' => $trx_id,
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }
    
    public function call_players()
    {
        $postdata = [
            'method' => 'call_players',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? ''
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }
    
    public function call_list($providerCode, $gameCode)
    {
        $postdata = [
            'method' => 'call_list',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'provider_code' => $providerCode,
            'game_code' => $gameCode
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }
    
    public function call_apply($providerCode, $gameCode, $extplayer, $callRtp, $callType)
    {
        $postdata = [
            'method' => 'call_apply',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'provider_code' => $providerCode,
            'game_code' => $gameCode,
            'user_code' => $extplayer,
            'call_rtp' => $callRtp,
            'call_type' => $callType
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }
    
    public function control_rtp($providerCode, $extplayer, $rtp)
    {
        $postdata = [
            'method' => 'control_rtp',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'provider_code' => $providerCode,
            'user_code' => $extplayer,
            'rtp' => $rtp
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }
    
    public function getGamelist($provider)
    {
        $postdata = [
            'method' => 'game_list',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'provider_code' => $provider,
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }
    
    public function getProvider()
    {
        $postdata = [
            'method' => 'provider_list',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? ''
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }
    
    public function getGameHistory($extplayer, $game_type, $start, $end)
    {
        $postdata = [
            'method' => 'get_game_log',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'user_code' => $extplayer,
            'game_type' => $game_type,
            'start' => $start,
            'end' => $end,
            'page' => 0,
            'perPage' => 1000
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }

    public function resetBalance($extplayer = null)
    {
        $postdata = [
            'method' => 'user_withdraw_reset',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'user_code' => $extplayer ?? null,
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }

    public function launchGame($extplayer, $provider_code, $game_code)
    {
        $postdata = [
            'method' => 'game_launch',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? '',
            'user_code' => $extplayer,
            'provider_code' => $provider_code,
            'game_code' => $game_code,
            'lang' => 'id',
        ];
        return $this->curl_postc_2($this->api->url ?? '', $postdata);
    }

    public function getBalanceAgent()
    {
        $postdata = [
            'method' => 'user_withdraw_reset',
            'agent_code' => $this->api->apikey ?? '',
            'agent_token' => $this->api->secretkey ?? ''
        ];
        $response = $this->curl_postc_2($this->api->url ?? '', $postdata);
        $result = json_decode($response);
        return isset($result->agent->balance) ? $result->agent->balance : 0;
    }

    public function curl_postc_2($url, $postData)
    {
        if (empty($url)) return json_encode(['error' => 'URL is empty']);

        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Mozilla/5.0';
        $protocol  = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || ($_SERVER['SERVER_PORT'] ?? 80) == 443 ? 'https://' : 'http://';
        $host      = rtrim($_SERVER['HTTP_HOST'] ?? '', '/');
        $domain    = $protocol . $host;

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_IPRESOLVE      => CURL_IPRESOLVE_V4,
            CURLOPT_AUTOREFERER    => true,
            CURLOPT_USERAGENT      => $userAgent,
            CURLOPT_HEADER         => 0,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_URL            => $url,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_CONNECTTIMEOUT => 5,
            CURLOPT_TIMEOUT        => 30,
            CURLOPT_TCP_KEEPALIVE  => 1,
            CURLOPT_TCP_KEEPIDLE   => 2,
            CURLOPT_TCP_KEEPINTVL  => 3,
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => json_encode($postData),
            CURLOPT_HTTPHEADER     => [
                'Content-Type: application/json',
                'X-Client-Domain: ' . $domain,
            ],
        ]);

        $output = curl_exec($ch);

        if ($output === false) {
            $error = curl_error($ch);
            curl_close($ch);
            return json_encode(['error' => $error]);
        }

        curl_close($ch);
        return $output;
    }

    public function user_list(Request $request)
    {
        $user = User::orderBy('created_at', 'desc')->get(['username', 'extplayer']);
        return response()->json(['status' => 1, 'data' => $user]);
    }

    public function luckywheel(Request $request)
    {
        $user = User::where('username', $request->username)->first();
        if (empty($user)) {
            return response()->json(['status' => 0, 'message' => 'Invalid username']);
        }

        $user->balance = $user->balance + $request->amount;
        $this->deposit($user->extplayer, $request->amount, 'LW-' . time());

        DB::table('trans_balls')->insert([
            'user_id' => $user->id,
            'username' => $user->username,
            'amount' => $request->amount,
            'type' => 3,
            'operator' => 'LuckyWheel',
            'created_at' => date("Y-m-d H:i:s"),
            'updated_at' => date("Y-m-d H:i:s"),
        ]);

        $user->save();
        return response()->json(['status' => 1, 'message' => 'Success']);
    }
    
    function pgadeposit($user, $amount, $trx_id)
    {
        $postdata = [
            'username' => $user, 
            'amount' => (int)$amount, 
            'uuid' => $this->pga->secretkey ?? '',
            'bonus' => 0,
            'custom_ref' => $trx_id
		];
		$url = $this->pga->url ?? '';
		$jsonData = json_encode($postdata);
		$headerArray = ['Content-Type: application/json'];
			
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_POST, 1);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_COOKIEFILE, '');
		$res = curl_exec($ch);
			
		if ($res === false) {
			$error = curl_error($ch);
			curl_close($ch);
			throw new \Exception("Kesalahan cURL: " . $error);
		}
			
		curl_close($ch);
		$decodedResponse = json_decode($res, true);
			
		if (json_last_error() !== JSON_ERROR_NONE) {
			throw new \Exception("Kesalahan dalam mendekode JSON: " . json_last_error_msg());
		}
		return $decodedResponse;
    }
    
    public function pgaxpay($user, $amount, $trx_id)
    {
        $apiKey = $this->pga->apikey ?? '';
        $secretKey = $this->pga->secretkey ?? '';
        $baseUrl = $this->pga->url ?? '';

        try {
            $pga = new \App\Services\PGAClient($apiKey, $secretKey, $baseUrl);
            $options = [
                'order_id' => $trx_id,
                'description' => 'Top Up Deposit a.n ' . $user
            ];

            $result = $pga->createQrisPayment((int)$amount, $user, $options);

            if (!$result['success']) {
                $errorMsg = $result['error'] ?? 'Unknown error from PGA';
                throw new \Exception("PGA API Error: " . $errorMsg);
            }
            return $result;
        } catch (\Exception $e) {
            throw new \Exception("Kesalahan Sistem PGA: " . $e->getMessage());
        }
    }

    public function payin_callback(Request $request)
    {
        $transaction = Transaction::where('trx_id', $request->trx_id)->where('status', 'Pending')->first();
        $user = User::where('username', $request->terminal_id)->first();
        
        if (!$user) {
            return response()->json(['status' => false, 'msg' => 'User Not Found.'], 500);
        }

        if (!($transaction)) {
            return response()->json(['status' => false, 'msg' => 'Transaction Approved or Not Found.'], 500);
        }

        if ($request->status == 'success') {
            $totals =  $transaction->total;
            
            if (class_exists('App\Http\Controllers\Api\NgamingController')) {
                $ngamingApi = new \App\Http\Controllers\Api\NgamingController();
                $depositNgaming = $ngamingApi->user_deposit($user->extplayer, (int)$totals);
                
                if (isset($depositNgaming['status']) && $depositNgaming['status'] == 1) {
                    $transaction->status = 'Sukses';
                    $transaction->notes = 'Top Up Qris Otomatis';
                    $transaction->transaction_by = 'QRIS VIP';
                    $transaction->save();

                    $user->balance_freeze = $user->balance_freeze + $totals;
                    $user->save();
                    
                    if (function_exists('sendNotifDepo')) {
                        sendNotifDepo($transaction->trx_id, $user->username, $totals);
                    }
                } else {
                    return response()->json(['status' => false, 'msg' => 'error api.'], 500);
                }
            }

            return response()->json(['status' => true, 'msg' => 'Transaction Approved.'], 200);
        }

        $transaction->status = 'Ditolak';
        $transaction->notes = null;
        $transaction->transaction_by = 'By System';
        $transaction->save();
        return response()->json(['status' => true, 'msg' => 'Transaction Rejected.'], 200);
    }
}