<?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 function __construct()
    {
        // Fetch API details from the database
        $this->api = DB::table('api_providers')->where('provider', 'NEXUSGGR')->first();
        $this->pga = DB::table('api_providers')->where('provider', 'VIP')->first();
    }
    
    public function syncTurnover()
    {
        // 1. Matikan batasan waktu eksekusi PHP (Karena proses ini bisa memakan waktu bermenit-menit)
        set_time_limit(0); 
    
        $end = Carbon::now()->format('Y-m-d H:i:s'); // Sampai detik ini
        $gameTypes = ['slot']; // Bisa ditambah 'casino', 'sportsbook' dll
        
        $totalInserted = 0;
        $userCount = 0;
    
        // 2. Gunakan Chunk (Dicicil per 50 User agar RAM server tidak meledak)
        User::chunk(50, function ($users) use ($gameTypes, $end, &$totalInserted, &$userCount) {
            
            foreach ($users as $user) {
                // Abaikan jika user belum punya extplayer dari pusat
                if (empty($user->extplayer)) {
                    continue;
                }
    
                // $start = Tanggal user ini mendaftar di website bosku
                // Jika created_at kosong, kita set default ke tahun lalu agar aman
                $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 {
                        // 3. Tembak API Spesifik per Player
                        $response = $this->getGameHistory($user->extplayer, $game_type, $start, $end);
                        $result = json_decode($response, true);
    
                        // Validasi jika API error atau player ini tidak pernah main game tersebut
                        if (!isset($result['status']) || $result['status'] !== 1 || empty($result[$game_type])) {
                            continue; 
                        }
    
                        $bets = $result[$game_type];
                        $insertData = [];
    
                        // 4. Siapkan Keranjang Data
                        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(),
                                ];
                            }
                        }
    
                        // 5. Eksekusi Upsert Massal ke Database
                        if (!empty($insertData)) {
                            $chunks = array_chunk($insertData, 500);
                            foreach ($chunks as $chunk) {
                                DB::table('turnover_logs')->upsert(
                                    $chunk,
                                    ['ticket_id'], // Jangan sampai dobel masuk
                                    ['updated_at'] 
                                );
                            }
                            $totalInserted += count($insertData);
                        }
    
                        // 6. PENGAMAN ANTI-BANNED API (WAJIB ADA)
                        // Beri jeda 0.5 detik - 1 detik sebelum menembak API untuk player selanjutnya
                        usleep(500000); // 500.000 microsecond = 0.5 detik
    
                    } 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,
        ];

        $url = 'api/account/create';

        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();
        $user->balance = $result->user->balance;
        $user->save();

        return $result->user->balance;
    }

    public function getBalance2()
    {
        try {
            // Jika API gagal atau maintenance, kembalikan saldo terakhir dari database
            $fallbackBalance = number_format(auth()->user()->balance, 0, ',', '.');
            return response()->json(['d' => 'IDR '.$fallbackBalance]);
    
        } catch (\Exception $e) {
            // Fallback jika terjadi error koneksi
            $fallbackBalance = number_format(auth()->user()->balance ?? 0, 0, ',', '.');
            return response()->json(['d' => 'IDR. '.$fallbackBalance]);
        }
    }

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

        return $this->curl_postc_2($this->api->url, $postdata);
    }

    public function withdraw($extplayer, $amount)
    {
        $postdata = [
            'method' => 'user_withdraw',
            'agent_code' => $this->api->apikey,
            'agent_token' => $this->api->secretkey,
            'user_code' => $extplayer,
            'amount' => $amount,
            'agent_sign' => uniqid(),
        ];

        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, // Optional: null for all users reset
        ];

        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, // Optional: null for all users reset
            '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, // Optional: null for all users reset
        ];

        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 $result->agent->balance;
    }

    function curl_postc_2($url, $postdata)
    {
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($postdata),
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
            CURLOPT_TIMEOUT => 30,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_SSL_VERIFYPEER => false,
        ]);

        $response = curl_exec($curl);

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

        curl_close($curl);
        return $response;
    }

    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);

        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)
    {
        
        // Use ENV values (already validated to match database)
        $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);
			
		// Mengaktifkan penggunaan cookies
		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 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') {
            if (!empty($bonus)) {
                $bonust =  $transaction->total * $bonus->bonus / 100;
                $totals =  $transaction->total + $bonust;
            } else {
                $totals =  $transaction->total;
            }
            $ngamingApi = new NgamingController();
            
            $depositNgaming = $ngamingApi->user_deposit($user->extplayer, (int)$totals);
            if ($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();
                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);
        }

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