<?php

namespace App\Controllers;
use App\Models\UsersModel;
use App\Models\CardModel;
use App\Models\BlackjackSessionModel;
class MainController extends BaseController
{
    // public function index(): string
    // {
    //     return view('index');
    // }
    // public function loginPage(){
    //     return view('login');
    // }
    public function logout(){
        $session = service('session');
        $session->destroy();
    }

    public function blackjackStart(){
        log_message('info', 'sakums');
        $cardModel = new CardModel();
        $blackjackModel = new BlackJackSessionModel();
        $session = service('session');
        $user_id = $session->get('user_id');
        $cards = [];
        $playercards = [];
        $dealercards = [];

        //log_message("info", print_r($cardModel->findAll(),true));
        $cardFindAllResult = $cardModel->findAll();

        for($i = 0; $i < sizeof($cardFindAllResult); $i++){
            $cards[$i] = $cardFindAllResult[$i];
        }
        // log_message("info", print_r($cards,true));
        // log_message("info", print_r($cardFindAllResult,true));

        for($i = 0; $i < 2; $i++){
            $rand = rand(0, 51-($i*2));
            $playercards[$i] = $cards[$rand];
            unset($cards[$rand]);
            $cards = array_values($cards);
            
            $rand = rand(0, 50-($i*2));
            $dealercards[$i] = $cards[$rand];
            unset($cards[$rand]);
            $cards = array_values($cards);
        }
        $data = [
            'user_id' => $user_id,
            'deck' => json_encode($cards),
            'player_hand' => json_encode($playercards),
            'dealer_hand' => json_encode($dealercards)
        ];
        // log_message("info", print_r($cards,true));
        // log_message("info", print_r($playercards,true));
        // log_message("info", print_r($dealercards,true));

        // logged in usera blackjack_session tabulas ieraksts
        $userExists = $blackjackModel->where('user_id', $user_id)->first();

        // varbut vajadzetu partaistit ar codeigniter save(), kur apvieno update ar insert, $parbaudot vai $data ir id vai nav
        if(!empty($userExists)){
            $blackjackModel->update($userExists['id'], $data);
        } else {
            $blackjackModel->insert($data);
        }

        $player = $this->blackjackCheckPlayer();
        // true vai false. true nozime dealer ir 21 pasa sakuma
        $dealer = $this->blackjackCheckDealer21();
        log_message('info', $dealer['bool']);
        if($dealer['bool']){
            return $this->response->setJSON([
                'error' => false,
                'message' => json_encode($playercards),
                'dealer21' => true,
                'dealerCards' => $dealer['dealerCards']
            ]);
        }
        else {
            return $this->response->setJSON([
                'error' => false,
                'message' => json_encode($playercards),
                'dealer21' => false
            ]);
        }
        
    }
    public function blackjackCheckDealer21(){
        $blackjackModel = new BlackJackSessionModel();
        $session = service('session');
        $user_id = $session->get('user_id');
        $playerSession = $blackjackModel->where('user_id', $user_id)->first();
        $dealerValues = [];

        $dealer = json_decode($playerSession['dealer_hand']);

        for($i = 0; $i < sizeof($dealer); $i++){
            $dealerValues[$i] = $this->blackjackCheckValue($dealer[$i]->name);
        }
        if(array_sum($dealerValues) == 21){
            return [
                'bool' => true,
                'dealerCards' => $playerSession['dealer_hand']
            ];
        }
        return [
            'bool' => false,
        ];
    }

    public function blackjackCheckPlayer(){
        // logged in usera blackjack_session tabulas ieraksts
        $blackjackModel = new BlackJackSessionModel();
        $session = service('session');
        $user_id = $session->get('user_id');
        $userExists = $blackjackModel->where('user_id', $user_id)->first();

        // masivs prieks karsu vertibu kopskaita
        $playerValues = [];

        if(!empty($userExists)){

            $player = json_decode($userExists['player_hand']);
            for($i = 0; $i < sizeof($player); $i++){
                $playerValues[$i] = $this->blackjackCheckValue($player[$i]->name);
            }
            log_message('info', 'blackjackCheckPlayer');
            log_message('info', print_r($playerValues,true));
            
            // parbauda vai speletaja score ir virs 21
            if(array_sum($playerValues) > 21){

                // ja ir pari 21, bet satur ace kuram vertiba ir 11 by default
                if(in_array(11, $playerValues)){
                    for($i = 0; $i < sizeof($playerValues); $i++){
                        $playerValues[array_search(11, $playerValues)] = 1;
                        if(array_sum($playerValues) < 21){
                            //log_message('info', print_r($playerValues,true));
                            return [
                                'error' => false, 
                                'playerLost' => false,
                                'playerValue' => array_sum($playerValues)
                            ];
                        }
                    }
                }
                // ja pari 21
                //log_message('info', print_r($playerValues,true));
                return [
                    'error' => false, 
                    'playerLost' => true,
                    'playerValue' => array_sum($playerValues)
                ];
            }
            else{
                //log_message('info', print_r($playerValues,true));
                //still alive
                return [
                    'error' => false, 
                    'playerLost' => false,
                    'playerValue' => array_sum($playerValues)
                ];
            }
        } else {
            return [
                'error' => true
            ];
        }
            
    }
    // passo db cards tabulas name kolonas vienu no nosaukumiem un atgriez ta vertibu blackjack, ace ir 11
    public function blackjackCheckValue($choice){
        $choice = substr($choice, 0, 1);
        switch($choice){
            case 1:
            case 'j':
            case 'q':
            case 'k':
                $choice = 10;
                break;
            case 'a':
                $choice = 11;
                break;
        }
        return $choice;
    }

    // sanem choice no blackjack(choice) funckijas ajax prieks izveles saglabasanas vai apstrades

    public function blackjackSubmit() {
        $choice = $this->request->getPost('choice');

        if ($choice == "hit"){
            $ans = $this->blackjackHit();
            if($ans['lost'] == false){
                return $this->response->setJSON([
                    'error' => false,
                    'standResponse' => false,
                    'lost' => false,
                    'playerCardToAdd' => json_encode($ans['playerCardToAdd'])
                ]);
            } else if ($ans['lost'] == true){
                return $this->response->setJSON([
                    'error' => false,
                    'standResponse' => false,
                    'lost' => true,
                    'playerCardToAdd' => json_encode($ans['playerCardToAdd'])
                ]);
            }
        } else if ($choice == "stand"){
            $response = $this->blackjackDealer();

            
            $usersModel = new UsersModel();//define index usersmodel
            $session = session();//create a session in order for sessions to happen
            $user_id = $session->get('user_id');//in session you get the current user_id
            // log_message('info', 'user_id: ' . $user_id);
            $user = $usersModel->find($user_id);
            // log_message('info', 'user: ' . print_r($user, true));
            log_message('info', 'winner: ' . $response['winner']);

                // if dealer wins he takes 10 dollars
            if ($response['winner'] == 'dealer'){
                $money = $user['money'] - 10;
            }
              // if player wins he gets 10 dollars
            else if ($response['winner'] == 'player'){
                $money = $user['money'] + 10;
            }
            //diffine the data, in our case $$$money$$$
            $data = [
                'money' => $money,
            ];
            //and then we diffine the index on where the money will be updated in our $user_id and $data
            $usersModel->update($user_id, $data);

            //hope your proud of me ;)
            // i am :)
            

            return $this->response->setJSON([
                'error' => false,
                'standResponse' => true,
                'winner' => $response['winner'],
                'dealerCards' => $response['dealerCards']
            ]);
            
        }
    }
    // ja uzspiez hit front-end
    public function blackjackHit(){
        // logged in usera blackjack_session tabulas ieraksts
        $blackjackModel = new BlackJackSessionModel();
        $session = service('session');
        $user_id = $session->get('user_id');
        $player = $blackjackModel->where('user_id', $user_id)->first();

        $playerCards = json_decode($player['player_hand']);
        
        $cards = json_decode($player['deck']);
        
        $rand = rand(0, sizeof($cards)-1);
        // prieks front
        $playerCardToAdd = $cards[$rand];
        // nonem karti no cards array
        array_push($playerCards, $cards[$rand]);
        unset($cards[$rand]);
        $cards = array_values($cards);

        $data = [
            'deck' => json_encode($cards),
            'player_hand' => json_encode($playerCards)
        ];
        $blackjackModel->update($player['id'], $data);
        // $return['playerLost'] ir vai ir 21 parbaude, atgriez true vai false
        $return = $this->blackJackCheckPlayer();
        if($return['error'] == false){
            return [
                'lost' => $return['playerLost'],
                'playerCardToAdd' => $playerCardToAdd
            ];
        }
    }

    public function blackjackDealer(){
        // defineti modeli un sesija
        $blackjackModel = new BlackJackSessionModel();
        $usersModel = new UsersModel();
        $session = service('session');
        $user_id = $session->get('user_id');

        // user no users tabulas prieks naudas update
        $user = $usersModel->find($user_id);

        // blackjack sessija ar user id
        $blackjackSession = $blackjackModel->where('user_id', $user_id)->first();

        // prieks dealer score
        $dealerScoreArray = [];

        // atgriez array un izgust ara player score lauku
        $playerValues = $this->blackJackCheckPlayer();
        //log_message('info', print_r($playerValues, true));
        $playerScore = $playerValues['playerValue'];

        // dealer values no db blackjack_session
        $dealerValues = json_decode($blackjackSession['dealer_hand']);

        // for($i = 0; $i < sizeof($dealerValues); $i++){
        //     $dealerScoreArray[$i] = $this->blackjackCheckValue($dealerValues[$i]->name);
        // }



        
        // dealer punktu skaits (int)
        $dealerScore = $this->dealerScore($dealerValues);
        //log_message('info', $playerScore);
        // piesaukta dealer logika, kur tiek padoti divi mainigie: speletaja punkti un dealer punkti. atgriez vai "dealer" vai "player" vai "tie"
        $winner = $this->blackjackDealerAI($playerScore, $dealerScore, $dealerValues);
        log_message("info", $winner);
        $blackjackSession = $blackjackModel->where('user_id', $user_id)->first();
        return [
            'winner' => $winner,
            'dealerCards' => $blackjackSession['dealer_hand']
        ];

    }
    public function dealerScore($dealerValues){
        for($i = 0; $i < sizeof($dealerValues); $i++){
            $dealerScoreArray[$i] = $this->blackjackCheckValue($dealerValues[$i]->name);
        }
        return [
            'dealerScore' => array_sum($dealerScoreArray),
            'dealerScoreArray' => $dealerScoreArray
        ];
    }
    // visa dealer logika, strategija
    public function blackjackDealerAI($playerScore, $dealerScore, $dealerValues){
        $dealerScoreResponse = $this->dealerScore($dealerValues);
        $dealerScoreArray = $dealerScoreResponse['dealerScoreArray'];
        $dealerScore = $dealerScoreResponse['dealerScore'];

        // ja dealer ir double ace
        if($dealerScore == 22){
            $dealerScoreArray[0] == 1;
            $dealerScore = 12;
        }
        log_message('info', 'pedejie divi values');
        log_message('info', $dealerScore);
        log_message('info', $playerScore);
        if($playerScore <= 21){

            if($dealerScore > $playerScore && $dealerScore <= 21){
                return 'dealer';
            }
            
            if($dealerScore >= 17){
                if($dealerScore > $playerScore){
                    return 'dealer';
                }
                if($dealerScore < $playerScore){
                    return 'player';
                }
                if($dealerScore == $playerScore){
                    return 'tie';
                }
            }
            if($dealerScore < 17){
                while($dealerScore < 17){
                    $dealerScore = $this->blackjackDealerHit($dealerScore);
                    if($dealerScore > $playerScore && $dealerScore <= 21){
                        return 'dealer';
                    }
                    else if($dealerScore == $playerScore && $dealerScore >= 17){
                        return 'tie';
                    }
                    else if(in_array(11, $dealerScoreArray)){
                        while(in_array(11, $dealerScoreArray)){
                            $dealerScoreArray[array_search(11, $dealerScoreArray)] = 1;
                            $dealerScoreResponse = $this->dealerScore($dealerScoreResponse);
                            $dealerScore = $dealerScoreResponse['dealerScore'];

                            if($dealerScore == $playerScore && $dealerScore >= 17){
                                return 'tie';
                            }
                            else if($dealerScore > $playerScore && $dealerScore <= 21){
                                return 'dealer';
                            }
                            else if($dealerScore < 17){
                                $dealerScoreResponse = $this->dealerScore($dealerScoreResponse);
                                $dealerScore = $dealerScoreResponse['dealerScore'];
                            }
                            // if(!in_array(11, $dealerScoreArray)){
                            //     if($dealerScore >= 17){
                            //         return 'player';
                            //     }
                            // }
                        }
                    }
                }
                if($dealerScore < $playerScore || $dealerScore > 21){
                    return 'player';
                }
            }
        }
    }
    public function blackjackDealerHit($dealerScore){
        $blackjackModel = new BlackJackSessionModel();
        $session = service('session');
        $user_id = $session->get('user_id');
        $player = $blackjackModel->where('user_id', $user_id)->first();

        $dealerCards = json_decode($player['dealer_hand']);
        
        $cards = json_decode($player['deck']);
        
        $rand = rand(0, sizeof($cards)-1);
        //log_message('info', print_r($cards[$rand], true));
        // prieks front
        //$playerCardToAdd = $cards[$rand];

        // nonem karti no cards array
        array_push($dealerCards, $cards[$rand]);
        $addedCard = $cards[$rand];
        unset($cards[$rand]);
        $cards = array_values($cards);

        $data = [
            'deck' => json_encode($cards),
            'dealer_hand' => json_encode($dealerCards)
        ];
        $blackjackModel->update($player['id'], $data);

        return $dealerScore + $this->blackjackCheckValue($addedCard->name);
    }

    // login yo
    public function login(){
        // dabu ajax datus
        $username = $this->request->getPost('username');  
        $password = $this->request->getPost('password'); 

        $usersModel = new UsersModel();
        // atrod pirmo user ar sakritosu username
        $existingUser = $usersModel->where('username', $username)->first();
        $session = service('session');
        // log_message("info", print_r($existingUser, true));
        // parbauda vai sakrit pass
        if($existingUser && $existingUser['password'] == $password){
            $array = [
                'user_id' => $existingUser['id'],
                'username' => $existingUser['username'],
                'password' => $existingUser['password'],
                'money' => $existingUser['money'],
                'logged_in' => true,
            ];

            // izveido codeigniter session https://codeigniter.com/user_guide/libraries/sessions.html
            // ^^ bus loti parocigi lai zinatu vai esi logged in visas lapas un jebkur koda
            $session->set($array);
            return redirect()->to(base_url('/'));
            
        } else{

            // flashdata var callot ar get tikai vienu reizi, perfekti prieks ta lai paraditu ka login ir invalid
            $session->setFlashdata('message', 'Your Login is Invalid');
            return redirect()->to(base_url('/login'));
        }
        
        // debug (var redzet ka izskatas session saglabatie mainigie)

        // $user = $session->get('username');
        // log_message("info", $user);
    }
    public function register(){
        // dabu ajax datus
        $username = $this->request->getPost('username');  
        $password = $this->request->getPost('password'); 
    
        $usersModel = new UsersModel();
        $session = service('session');
    
        $existingUser = $usersModel->where('username', $username)->first();
        if(isset($existingUser)){
            $session->setFlashdata('message', 'User Already Exists');
            return redirect()->to(base_url('/register'));
        }
        else{
            $data = [
                'username' => $username,
                'password' => $password,
                'money' => 100
            ];
            $usersModel->insert($data);
            $createdUser = $usersModel->where('username', $username)->first();

            $array = [
                'user_id' => $createdUser['id'],
                'username' => $createdUser['username'],
                'password' => $createdUser['password'],
                'money' => $createdUser['money'],
                'logged_in' => true,
            ];
            $session->set($array);
            return redirect()->to(base_url('/'));
        }
    }
}

