<?php

namespace App\Http\Controllers\API\ChakriMatka;

# Models
use App\Models\AppDetail;
use App\Models\ChakriRates;
use App\Models\ChakriGames;
use App\Models\ChakriBets;
use App\Models\ChakriPeriods;
use App\Models\ChakriResults;
use App\Models\ChakriWinners;

use App\Traits\ChakriTrait;
# Other Classes
use DB;
use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Auth;
use App\Http\Controllers\API\BaseController as BaseController;

class ChakriGetController extends BaseController
{

    use ChakriTrait;

    #Bind AppDetail model
    protected $appDetail;

    #Bind ChakriRates model
    protected $chakriRate;

    #Bind ChakriGames model
    protected $chakriGame;

    #Bind ChakriBets model
    protected $chakriBet;

    #Bind ChakriPeriods model
    protected $chakriPeriod;

    #Bind ChakriResults model
    protected $chakriResult;

    #Bind ChakriWinners model
    protected $chakriWinner;

    /**
     * Defining the default constructor for controller
     *
     */
    public function __construct(
        AppDetail              $appDetail,
        ChakriRates            $chakriRate,
        ChakriGames            $chakriGame,
        ChakriBets             $chakriBet,
        ChakriResults          $chakriResult,
        ChakriWinners          $chakriWinner,
        ChakriPeriods          $chakriPeriod
    ) {
        $this->appDetail        = $appDetail;
        $this->chakriRate       = $chakriRate;
        $this->chakriGame       = $chakriGame;
        $this->chakriBet        = $chakriBet;
        $this->chakriResult     = $chakriResult;
        $this->chakriWinner     = $chakriWinner;
        $this->chakriPeriod     = $chakriPeriod;
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        try {
            #Stat get 
            $success['state'] = $this->state->where('status', 1)->get();

            #return response with active state
            return $this->sendResponse($success, 'State List.');
        } catch (\Exception $ex) {
            return $this->sendError('Validation Error.', $ex->getMessage());
        }
    }

    public function rateGet()
    {
        try {
            #Stat get 
            $success['list'] = $this->chakriRate->with('game')->where('status', 1)->get();

            #return response with active state
            return $this->sendResponse($success, 'State List.');
        } catch (\Exception $ex) {
            return $this->sendError('Validation Error.', $ex->getMessage());
        }
    }

    public function chakriOrder()
    {
        try {
            $user_id = Auth::user()->id;
            $success['list'] = [];

            $bets = $this->chakriBet->where('user_id', $user_id)->orderBy('id', 'DESC')->paginate(25);
            $count = 0;
            foreach ($bets as $key => $value) {
                $success['list'][$count] = new \stdClass();

                $success['list'][$count]->period = $value->period->period;

                $success['list'][$count]->win = false;

                if ($value->bet_place) {
                    $success['list'][$count]->bet_place = $value->bet_place;
                    $success['list'][$count]->amount = $value->amount;
                } else {
                    if ($value->game_id == 4) {
                        $success['list'][$count]->bet_place = 'Five Difference';
                    } else if ($value->game_id == 5) {
                        $success['list'][$count]->bet_place = 'Ten Difference';
                    } else {
                        $success['list'][$count]->bet_place = $value->game->name;
                    }

                    $success['list'][$count]->amount = $value->amount;
                }

                $win = $this->chakriWinner->where('bet_id', $value->id)->first();

                if ($win) {
                    $count++;

                    $success['list'][$count] = new \stdClass();
                    $success['list'][$count]->period = $value->period->period;

                    if ($value->bet_place) {
                        $success['list'][$count]->bet_place = $value->bet_place;
                    } else {
                        if ($value->game_id == 4) {
                            $success['list'][$count]->bet_place = 'Five Difference';
                        } else if ($value->game_id == 5) {
                            $success['list'][$count]->bet_place = 'Ten Difference';
                        } else {
                            $success['list'][$count]->bet_place = $value->game->name;
                        }
                    }

                    $success['list'][$count]->win = true;
                    $success['list'][$count]->amount = $win->amount;
                }
                $count++;
            }

            return $this->sendResponse($success, 'Order List.');
        } catch (\Exception $ex) {
            return $this->sendError('Validation Error.', $ex->getMessage());
        }
    }

    public function resultGet()
    {
        try {

            $success['list'] = [];
            $results = $this->chakriResult->orderBy('id', 'DESC')->paginate(25);

            // return $results;

            foreach ($results as $key => $value) {

                $success['list'][$key] = new \stdClass();

                $color = 'red';
                $diff = 'five';
                $bet = $value->bet_place;

                // Check if $bet is in the green array
                if (in_array($bet, $this->green)) {
                    $matchedArray = $this->green;
                    $matchedValue = $bet;
                    $color = 'green';
                }
                // Check if $bet is in the red array
                if (in_array($bet, $this->red)) {
                    $matchedArray = $this->red;
                    $matchedValue = $bet;
                    $color = 'red';
                }

                if (in_array($bet, $this->five)) {
                    $diff = 'five';
                }

                if (in_array($bet, $this->ten)) {
                    $diff = 'ten';
                }

                // Output the matched array and value (for debugging or further use)
                if (isset($matchedArray)) {
                    // You can return or use the array in whatever way you need here
                    // Example: log the matched array and value

                    //  $success['list'][$key]->numbers = $matchedArray;
                    $success['list'][$key]->period = $value->period->period;
                    $success['list'][$key]->bet_place = $bet;
                    $success['list'][$key]->color = $color;
                    $success['list'][$key]->diff = $diff;
                }
            }

            return $this->sendResponse($success, 'Result List.');
        } catch (\Exception $ex) {
            return $this->sendError('Validation Error.', $ex->getMessage());
        }
    }

    public function resultTenGet()
    {
        try {

            $success['list'] = [];
            $results = $this->chakriResult->orderBy('id', 'DESC')->paginate(10);

            foreach ($results as $key => $value) {

                $success['list'][$key] = new \stdClass();

                $bet = $value->bet_place;
                $color = 'red';

                // Check if $bet is in the green array
                if (in_array($bet, $this->green)) {
                    $matchedArray = $this->green;
                    $matchedValue = $bet;
                    $color = 'green';
                }
                // Check if $bet is in the red array
                if (in_array($bet, $this->red)) {
                    $matchedArray = $this->red;
                    $matchedValue = $bet;
                    $color = 'red';
                }
                // Output the matched array and value (for debugging or further use)
                if (isset($matchedArray)) {
                    // You can return or use the array in whatever way you need here
                    // Example: log the matched array and value

                    $success['list'][$key]->bet_place = $bet;
                    $success['list'][$key]->period = $value->period->period;
                    $success['list'][$key]->color = $color;
                }
            }

            return $this->sendResponse($success, 'Result List.');
        } catch (\Exception $ex) {
            return $this->sendError('Validation Error.', $ex->getMessage());
        }
    }

    public function periodBets()
    {
        try {

            $user_id = Auth::user()->id;

            $checkPeriod = $this->chakriPeriod->orderBy('id', 'DESC')->first();

            $success['list'] = [];
            if ($checkPeriod) {
                $bets = $this->chakriBet->where('period_id', $checkPeriod->id)->where('user_id', $user_id)->get();

                foreach ($bets as $key => $value) {
                    // Initialize each list element as an object if it's not already one
                    $success['list'][$key] = new \stdClass();

                    if ($value->bet_place) {
                        $success['list'][$key]->bet_place = $value->bet_place;
                        $success['list'][$key]->amount = $value->amount;
                    } else {
                        if ($value->game_id == 4) {
                            $success['list'][$key]->bet_place = 'Five Difference';
                        } else if ($value->game_id == 5) {
                            $success['list'][$key]->bet_place = 'Ten Difference';
                        } else {
                            $success['list'][$key]->bet_place = $value->game->name;
                        }

                        $success['list'][$key]->amount = $value->amount;
                    }
                }

                return $this->sendResponse($success, 'State List.');
            } else {
                return $this->sendError('Period Not Found', 'Period Not Found');
            }
        } catch (\Exception $ex) {
            return $this->sendError('Validation Error.', $ex->getMessage());
        }
    }




    public function result(Request $request)
    {
        DB::beginTransaction();
        // try {

        $appdetail = $this->appDetail->first();
        $checkPeriod = $this->chakriPeriod->orderBy('id', 'DESC')->first();
        $details['new_period'] = $checkPeriod;

        $details['totalBetAmount'] = 0;
        $details['adminAmount'] = 0;
        $details['distributedAmount'] = 0;
        $details['farakResult'] = rand(0, 1) == 0 ? 4 : 5;
        $details['farakResultData'] = "";
        $details['colourResult'] = rand(0, 1) == 0 ? 2 : 3;
        $details['colourResultData'] = null;
        $details['farakColourArray'] = null;
        $details['numberResult'] = "";
        $details['numberResultData'] = null;


        $gameBetsData = [];
        if ($checkPeriod) {
            $details['totalBetAmount'] = $this->chakriBet->where('period_id', $checkPeriod->id)->sum('amount');
            $details['adminAmount'] = $details['totalBetAmount'] * $appdetail->chakri_percent / 100;
            $details['distributedAmount'] = $details['totalBetAmount'] - $details['adminAmount'];
            $details['distributedAmountExact'] = $details['totalBetAmount'] - $details['adminAmount'];

            $games = $this->chakriGame->where('status', 1)->get();

            foreach ($games as $value) {
                $gamebets = $this->chakriBet->where('period_id', $checkPeriod->id)
                    ->where('game_id', $value->id)
                    ->get();

                $betsArray = [];

                $betPlaceTotals = [];
                foreach ($gamebets as $bet) {
                    $betPlace = str_pad((string)$bet->bet_place, 2, '0', STR_PAD_LEFT);

                    if (!isset($betPlaceTotals[$betPlace])) {
                        $betPlaceTotals[$betPlace] = 0;
                    }

                    $betPlaceTotals[$betPlace] += $bet->amount;
                }
                $bet_winning_amount = 0;

                foreach ($betPlaceTotals as $betPlace => $totalAmount) {
                    $bet_winning_amount = $this->resultPrediction($value->id, $value->name, $betPlace, $totalAmount);

                    $betsArray[] = [
                        'bet_place' => $betPlace,
                        'total_amount' => $totalAmount,
                        'game_id' => $value->id,
                        'winning_amount' => $bet_winning_amount
                    ];
                }

                $gameBetsData[] = [
                    'game_id' => $value->id,
                    'game_name' => $value->name,
                    'winning_amount' => $bet_winning_amount,
                    'bets' => $betsArray
                ];
            }

            $details['game_bets'] = $gameBetsData;

            $minWinningAmountColour = PHP_INT_MAX;
            $minWinningAmountFarak = PHP_INT_MAX;
            $minWinningAmountJodi = PHP_INT_MAX;

            foreach ($details['game_bets'] as $game) {
                // Check if the game_id is either 2 or 3
                if ($game['game_id'] == 2 || $game['game_id'] == 3) {
                    foreach ($game['bets'] as $bet) {
                        // Compare the winning_amount
                        if ($bet['winning_amount'] < $minWinningAmountColour) {
                            $minWinningAmountColour = $bet['winning_amount'];
                            $details['colourResultData'] = $game;
                            $details['colourResult'] = $game['game_id'];
                        }
                    }
                }
            }

            if ($details['colourResultData'])
                $details['distributedAmount'] -= $details['colourResultData']['winning_amount'];

            foreach ($details['game_bets'] as $game) {
                // Check if the game_id is either 2 or 3
                if ($game['game_id'] == 4 || $game['game_id'] == 5) {
                    foreach ($game['bets'] as $bet) {
                        // Compare the winning_amount
                        if ($bet['winning_amount'] < $minWinningAmountFarak) {
                            $minWinningAmountFarak = $bet['winning_amount'];
                            $details['farakResultData'] = $game;
                            $details['farakResult'] = $game['game_id'];
                        }
                    }
                }
            }

            if ($details['farakResultData'])
                $details['distributedAmount'] -= $details['farakResultData']['winning_amount'];


            if ($details['farakResult'] == 4 && $details['colourResult']  == 2) {
                $details['farakColourArray'] = $this->red5farak;
            }
            if ($details['farakResult'] == 5 && $details['colourResult']  == 2) {
                $details['farakColourArray'] = $this->red10farak;
            }
            if ($details['farakResult'] == 4 && $details['colourResult']  == 3) {
                $details['farakColourArray'] = $this->green5farak;
            }
            if ($details['farakResult'] == 5 && $details['colourResult']  == 3) {
                $details['farakColourArray'] = $this->green10farak;
            }

            foreach ($details['game_bets'] as $game) {
                if ($game['game_id'] == 1) {
                    foreach ($game['bets'] as $bet) {
                        // Compare the winning_amount
                        if (
                            $bet['winning_amount'] < $minWinningAmountJodi &&
                            in_array($bet['bet_place'], $details['farakColourArray']) &&
                            $bet['winning_amount'] <= $details['distributedAmount']
                        ) {
                            $minWinningAmountFarak = $bet['winning_amount'];
                            $details['numberResultData'] = $bet;
                            $details['numberResult'] = $bet['bet_place'];
                        }
                    }

                    // If no numberResult is found, pick a number from farakColourArray that is not in the game bets
                    if (!$details['numberResult']) {
                        // Get all bet places from the game
                        $betPlaces = array_map(function ($bet) {
                            return $bet['bet_place'];
                        }, $game['bets']);

                        // Find the numbers from farakColourArray that are not in the bet places
                        $availableNumbers = array_diff($details['farakColourArray'], $betPlaces);

                        // If there are any available numbers, find the one with the least winning amount
                        if (!empty($availableNumbers)) {
                            $minWinningAmount = PHP_INT_MAX; // Initialize to a very high number
                            $selectedNumber = null;

                            // Loop through each available number
                            foreach ($availableNumbers as $number) {
                                foreach ($game['bets'] as $bet) {
                                    // Compare the available number with bet places
                                    if ($bet['bet_place'] == $number && $bet['winning_amount'] < $minWinningAmount) {
                                        $minWinningAmount = $bet['winning_amount'];
                                        $selectedNumber = $number; // Set the number with the least winning amount
                                    }
                                }
                            }

                            // Set the result if a valid number is found
                            if ($selectedNumber !== null) {
                                $details['numberResult'] = str_pad((string)$selectedNumber, 2, '0', STR_PAD_LEFT);;
                            } else {
                                $details['numberResult'] =  str_pad((string)$availableNumbers[array_rand($availableNumbers)], 2, '0', STR_PAD_LEFT);;
                            }
                        }
                    }
                }
            }


            $data = [
                'period_id' => $checkPeriod->id,
                'game_id'   => $details['colourResult'],
                'bet_place' => $details['numberResult'],
                'admin_amount'  => $details['adminAmount'],
                'total_bet_amount' => $details['totalBetAmount'],
                'distributed_amount' => $details['distributedAmountExact'],
            ];

            $details['create'] = $this->chakriResult->create($data);

            $gameFinal = $this->chakriGame->where('id', $details['colourResult'])->first();

            $farakFinal = $this->chakriGame->where('id', $details['farakResult'])->first();


            $this->gameWinningsJodi($details['create']);
            $this->gameWinnings($details['create'], $gameFinal->name, $details['colourResult']);
            $this->gameWinnings($details['create'], $farakFinal->name, $details['farakResult']);


            $details['old_period'] = $checkPeriod;

            $newPeriod = str_pad((int)$checkPeriod->period + 1, 12, '0', STR_PAD_LEFT);
            $data = [
                'period' => $newPeriod,
                'status' => 1,
            ];
            $details['new_period'] = $this->chakriPeriod->create($data);
        } else {
            $data = [
                'period' => '000000000001',
                'status' => 1,
            ];
            $details['new_period'] = $this->chakriPeriod->create($data);
        }

        DB::commit();
        #return response with active state
        return $this->sendResponse($details, 'Result get successfully.');
        // } catch (\Exception $ex) {
        //     DB::rollback();
        //     return $this->sendError('Validation Error.', $ex->getMessage());
        // }
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */


    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}
