package com.friendvilla.bucksbuddy;

import static android.widget.Toast.LENGTH_SHORT;
import static android.widget.Toast.makeText;
import static com.friendvilla.bucksbuddy.MainActivity.USER;
import static com.friendvilla.bucksbuddy.Method.calWallet;
import static com.friendvilla.bucksbuddy.Method.taxCal;
import static com.friendvilla.bucksbuddy.Method.title;
import static com.friendvilla.bucksbuddy.Method.updateUser;

import android.animation.Animator;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Base64;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.lifecycle.MutableLiveData;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.airbnb.lottie.LottieAnimationView;
import com.friendvilla.bucksbuddy.adapter.AmountAdapter;
import com.friendvilla.bucksbuddy.model.User;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Random;

public class TictacActivity extends AppCompatActivity implements View.OnClickListener {

    private int winnerId = -1;
    private RecyclerView amtView;
    private boolean isShow = false;
    private LottieAnimationView anim;
    private final int PLAYER_ONE_ID = 1;
    private final int PLAYER_TWO_ID = 2;
    private int activePlayer = PLAYER_ONE_ID;
    private ArrayList<Integer> player1 = new ArrayList<>();
    private ArrayList<Integer> player2 = new ArrayList<>();
    private MediaPlayer winMediaPlayer,looseMediaPlayer;
    public static MutableLiveData<Integer> AmountTicTacToe = new MutableLiveData<>();

    @SuppressLint("SetTextI18n")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tictac);AmountTicTacToe.setValue(0);
        anim = findViewById(R.id.win);amtView = findViewById(R.id.amountView);
        ((TextView)findViewById(R.id.tvTitle)).setText(title(this,getString(R.string.tictactoe),5));
        findViewById(R.id.bal).setOnClickListener(view -> startActivity(new Intent(this,WalletActivity.class)));
        User user = USER.getValue(); assert user != null;
        BigDecimal bal = new BigDecimal(user.getDeposit()).add(new BigDecimal(user.getWithdraw()));
        ((TextView)findViewById(R.id.tvBal)).setText("₹ " + bal);
        findViewById(R.id.ivMenu).setOnClickListener(view -> {
            if(isShow) {
                assert AmountTicTacToe.getValue() != null;
                updateUser(this,calWallet(AmountTicTacToe.getValue())[0],calWallet(AmountTicTacToe.getValue())[1],String.valueOf(0));
            }
            if(winMediaPlayer != null && winMediaPlayer.isPlaying()) {
                winMediaPlayer.stop();
            }
            if(looseMediaPlayer != null && looseMediaPlayer.isPlaying()) {
                looseMediaPlayer.stop();
            }
            finish();
        });
        winMediaPlayer = MediaPlayer.create(this,R.raw.win);
        looseMediaPlayer = MediaPlayer.create(this,R.raw.wrong);
        findViewById(R.id.btn1).setOnClickListener(this);
        findViewById(R.id.btn2).setOnClickListener(this);
        findViewById(R.id.btn3).setOnClickListener(this);
        findViewById(R.id.btn4).setOnClickListener(this);
        findViewById(R.id.btn5).setOnClickListener(this);
        findViewById(R.id.btn6).setOnClickListener(this);
        findViewById(R.id.btn7).setOnClickListener(this);
        findViewById(R.id.btn8).setOnClickListener(this);
        findViewById(R.id.btn9).setOnClickListener(this);
        amtView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));
        amtView.setHasFixedSize(false); amtView.setAdapter(new AmountAdapter(false,3));
        AmountTicTacToe.observe(this,integer -> {
            int DEPOSIT = new BigDecimal(user.getDeposit()).intValue();
            int WITHDRAW = new BigDecimal(user.getWithdraw()).intValue();
            int TOTAL = DEPOSIT + WITHDRAW; int betAmt = integer;
            if (betAmt == 0) {
                makeText(this,"Select bet amount",LENGTH_SHORT).show();
            } else if(DEPOSIT < betAmt && WITHDRAW < betAmt && TOTAL < betAmt) {
                AmountTicTacToe.setValue(0);
                amtView.setAdapter(new AmountAdapter(false,3));
                makeText(this,"You have not enough money",LENGTH_SHORT).show();
            }
        });
        if(!new String(Base64.decode(BuildConfig.PACKAGE,Base64.DEFAULT)).equals(BuildConfig.APPLICATION_ID)) {
            finish();
        }
    }

    @SuppressLint("SetTextI18n")
    @Override
    protected void onResume() {
        super.onResume();
        USER.observe(this, user -> {
            BigDecimal bal = new BigDecimal(user.getDeposit()).add(new BigDecimal(user.getWithdraw()));
            ((TextView)findViewById(R.id.tvBal)).setText("₹ " + bal);
        });
    }

    private boolean isOdd(int val) {
        return val % 2 != 0;
    }

    private void setDefaultSetup() {
        activePlayer = PLAYER_ONE_ID; winnerId = -1;AmountTicTacToe.setValue(0);
        player1 = new ArrayList<>(); player2 = new ArrayList<>();
        amtView.setAdapter(new AmountAdapter(false,3));
        findViewById(R.id.btn1).setEnabled(true);findViewById(R.id.btn2).setEnabled(true);
        findViewById(R.id.btn3).setEnabled(true);findViewById(R.id.btn4).setEnabled(true);
        findViewById(R.id.btn5).setEnabled(true);findViewById(R.id.btn6).setEnabled(true);
        findViewById(R.id.btn7).setEnabled(true);findViewById(R.id.btn8).setEnabled(true);
        findViewById(R.id.btn9).setEnabled(true);((TextView)findViewById(R.id.btn9)).setText("");
        ((TextView)findViewById(R.id.btn8)).setText("");((TextView)findViewById(R.id.btn7)).setText("");
        ((TextView)findViewById(R.id.btn6)).setText("");((TextView)findViewById(R.id.btn5)).setText("");
        ((TextView)findViewById(R.id.btn4)).setText("");((TextView)findViewById(R.id.btn3)).setText("");
        ((TextView)findViewById(R.id.btn2)).setText("");((TextView)findViewById(R.id.btn1)).setText("");
        findViewById(R.id.btn1).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        findViewById(R.id.btn2).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        findViewById(R.id.btn3).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        findViewById(R.id.btn4).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        findViewById(R.id.btn5).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        findViewById(R.id.btn6).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        findViewById(R.id.btn7).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        findViewById(R.id.btn8).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        findViewById(R.id.btn9).setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
    }

    private void playGame(int cellId, TextView btn) {
        btn.setBackground(AppCompatResources.getDrawable(this,R.drawable.hole));
        if (activePlayer == PLAYER_ONE_ID) {
            btn.setText("X");
            btn.setBackground(AppCompatResources.getDrawable(this,R.drawable.right));
            player1.add(cellId);
            activePlayer = PLAYER_TWO_ID;
        } else if (activePlayer == PLAYER_TWO_ID) {
            btn.setText("0");
            btn.setBackground(AppCompatResources.getDrawable(this,R.drawable.wrong));
            player2.add(cellId);
            activePlayer = PLAYER_ONE_ID;
        }
        btn.setEnabled(false);
        checkWinner();
        if(activePlayer == PLAYER_TWO_ID) {
            assert AmountTicTacToe.getValue() != null;
            if(AmountTicTacToe.getValue() > 2) {
                artificialPlayer2();
            } else {
                if (isOdd(new Random().nextInt(100))) {
                    artificialPlayer1();
                } else {
                    artificialPlayer2();
                }
            }
        }
    }

    private void checkWinner() {
        if (player1.contains(1) && player1.contains(2) && player1.contains(3)) {
            winnerId = PLAYER_ONE_ID;
        }
        if (player2.contains(1) && player2.contains(2) && player2.contains(3)) {
            winnerId = PLAYER_TWO_ID;
        }
        if (player1.contains(4) && player1.contains(5) && player1.contains(6)) {
            winnerId = PLAYER_ONE_ID;
        }
        if (player2.contains(4) && player2.contains(5) && player2.contains(6)) {
            winnerId = PLAYER_TWO_ID;
        }
        if (player1.contains(7) && player1.contains(8) && player1.contains(9)) {
            winnerId = PLAYER_ONE_ID;
        }
        if (player2.contains(7) && player2.contains(8) && player2.contains(9)) {
            winnerId = PLAYER_TWO_ID;
        }
        if (player1.contains(1) && player1.contains(4) && player1.contains(7)) {
            winnerId = PLAYER_ONE_ID;
        }
        if (player2.contains(1) && player2.contains(4) && player2.contains(7)) {
            winnerId = PLAYER_TWO_ID;
        }
        if (player1.contains(2) && player1.contains(5) && player1.contains(8)) {
            winnerId = PLAYER_ONE_ID;
        }
        if (player2.contains(2) && player2.contains(5) && player2.contains(8)) {
            winnerId = PLAYER_TWO_ID;
        }
        if (player1.contains(3) && player1.contains(6) && player1.contains(9)) {
            winnerId = PLAYER_ONE_ID;
        }
        if (player2.contains(3) && player2.contains(6) && player2.contains(9)) {
            winnerId = PLAYER_TWO_ID;
        }
        if (player1.contains(1) && player1.contains(5) && player1.contains(9)) {
            winnerId = PLAYER_ONE_ID;
        }
        if (player2.contains(1) && player2.contains(5) && player2.contains(9)) {
            winnerId = PLAYER_TWO_ID;
        }
        if (player1.contains(3) && player1.contains(5) && player1.contains(7)) {
            winnerId = PLAYER_ONE_ID;
        }
        if (player2.contains(3) && player2.contains(5) && player2.contains(7)) {
            winnerId = PLAYER_TWO_ID;
        }
        if (winnerId != -1) {
            assert AmountTicTacToe.getValue() != null;
            int amt = AmountTicTacToe.getValue();
            if (winnerId == PLAYER_ONE_ID) {
                anim.addAnimatorListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) { }
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        anim.setVisibility(View.GONE);
                    }
                    @Override
                    public void onAnimationCancel(Animator animation) { }
                    @Override
                    public void onAnimationRepeat(Animator animation) { }
                });
                anim.setVisibility(View.VISIBLE); anim.playAnimation(); int w = amt * 2;
                updateUser(this,calWallet(amt)[0],calWallet(amt)[1],String.valueOf(taxCal(w)));
                playSound(winMediaPlayer); setDefaultSetup(); isShow = false;
                makeText(this,"Wow! You win the match",LENGTH_SHORT).show();
            } else if (winnerId == PLAYER_TWO_ID) {
                updateUser(this,calWallet(amt)[0],calWallet(amt)[1],String.valueOf(0));
                playSound(looseMediaPlayer); setDefaultSetup(); isShow = false;
                makeText(this,"Ops! You lose",LENGTH_SHORT).show();
            }
        }
    }

    private void playSound(MediaPlayer mp) {
        try {
            if (mp != null) {
                if (mp.isPlaying()) {
                    mp.pause();
                    mp.seekTo(0);
                }
                mp.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void artificialPlayer1() {
        ArrayList<Integer> unselectedCells = new ArrayList<>();
        int MAX_CELLS = 9;
        for (int cellId = 1; cellId <= MAX_CELLS; cellId++) {
            if (!(player1.contains(cellId) || player2.contains(cellId))) {
                unselectedCells.add(cellId);
            }
        }
        if(!unselectedCells.isEmpty()) {
            int randomIndex = new Random().nextInt(unselectedCells.size());
            int cellId = unselectedCells.get(randomIndex);
            playGame(cellId,getArtificialSelectedButton(cellId));
        } else {
            assert AmountTicTacToe.getValue() != null; int amt = AmountTicTacToe.getValue();
            updateUser(this,calWallet(amt)[0],calWallet(amt)[1],String.valueOf(0));
            playSound(looseMediaPlayer); setDefaultSetup(); isShow = false;
            makeText(this,"Ops! You lose",LENGTH_SHORT).show();
        }
    }

    private void artificialPlayer2() {
        ArrayList<Integer> unselectedCells = new ArrayList<>();
        int MAX_CELLS = 9;
        for (int cellId = 1; cellId <= MAX_CELLS; cellId++) {
            if (!(player1.contains(cellId) || player2.contains(cellId))) {
                unselectedCells.add(cellId);
            }
        }
        if(!unselectedCells.isEmpty()) {
            if(player1.contains(1) && player1.contains(4) && unselectedCells.contains(7)) {
                int cellId = 7;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(1) && player1.contains(7) && unselectedCells.contains(4)) {
                int cellId = 4;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(4) && player1.contains(7) && unselectedCells.contains(1)) {
                int cellId = 1;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(2) && player1.contains(5) && unselectedCells.contains(8)) {
                int cellId = 8;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(2) && player1.contains(8) && unselectedCells.contains(5)) {
                int cellId = 5;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(8) && player1.contains(5) && unselectedCells.contains(2)) {
                int cellId = 2;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(3) && player1.contains(6) && unselectedCells.contains(9)) {
                int cellId = 9;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(3) && player1.contains(9) && unselectedCells.contains(6)) {
                int cellId = 6;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(6) && player1.contains(9) && unselectedCells.contains(3)) {
                int cellId = 3;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(1) && player1.contains(2) && unselectedCells.contains(3)) {
                int cellId = 3;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(1) && player1.contains(3) && unselectedCells.contains(2)) {
                int cellId = 2;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(2) && player1.contains(3) && unselectedCells.contains(1)) {
                int cellId = 1;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(4) && player1.contains(5) && unselectedCells.contains(6)) {
                int cellId = 6;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(4) && player1.contains(6) && unselectedCells.contains(5)) {
                int cellId = 5;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(5) && player1.contains(6) && unselectedCells.contains(4)) {
                int cellId = 4;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(7) && player1.contains(8) && unselectedCells.contains(9)) {
                int cellId = 9;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(7) && player1.contains(9) && unselectedCells.contains(8)) {
                int cellId = 8;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(8) && player1.contains(9) && unselectedCells.contains(7)) {
                int cellId = 7;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(1) && player1.contains(5) && unselectedCells.contains(9)) {
                int cellId = 9;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(1) && player1.contains(9) && unselectedCells.contains(5)) {
                int cellId = 5;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(5) && player1.contains(9) && unselectedCells.contains(1)) {
                int cellId = 1;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(3) && player1.contains(5) && unselectedCells.contains(7)) {
                int cellId = 7;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(3) && player1.contains(7) && unselectedCells.contains(5)) {
                int cellId = 5;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else if(player1.contains(5) && player1.contains(7) && unselectedCells.contains(3)) {
                int cellId = 3;
                playGame(cellId,getArtificialSelectedButton(cellId));
            } else {
                int randomIndex = new Random().nextInt(unselectedCells.size());
                int cellId = unselectedCells.get(randomIndex);
                playGame(cellId, getArtificialSelectedButton(cellId));
            }
        } else {
            assert AmountTicTacToe.getValue() != null; int amt = AmountTicTacToe.getValue();
            updateUser(this,calWallet(amt)[0],calWallet(amt)[1],String.valueOf(0));
            playSound(looseMediaPlayer); setDefaultSetup();isShow = false;
            makeText(this,"Ops! You lose",LENGTH_SHORT).show();
        }
    }

    private TextView getArtificialSelectedButton(int cellId) {
        TextView btnSelected;
        if (cellId == 1) {
            btnSelected = findViewById(R.id.btn1);
        } else if (cellId == 2) {
            btnSelected = findViewById(R.id.btn2);
        } else if (cellId == 3) {
            btnSelected = findViewById(R.id.btn3);
        } else if (cellId == 4) {
            btnSelected = findViewById(R.id.btn4);
        } else if (cellId == 5) {
            btnSelected = findViewById(R.id.btn5);
        } else if (cellId == 6) {
            btnSelected = findViewById(R.id.btn6);
        } else if (cellId == 7) {
            btnSelected = findViewById(R.id.btn7);
        } else if (cellId == 8) {
            btnSelected = findViewById(R.id.btn8);
        } else if (cellId == 9) {
            btnSelected = findViewById(R.id.btn9);
        } else {
            btnSelected = findViewById(R.id.btn1);
        }
        return btnSelected;
    }

    @Override
    public void onClick(View v) {
        assert AmountTicTacToe.getValue() != null;
        if (AmountTicTacToe.getValue() == 0) {
            makeText(this,"Select bet amount",LENGTH_SHORT).show();
        } else {
            TextView btnSelected = (TextView) v;
            int cellId = 0;isShow = true;
            int id = btnSelected.getId();
            if (id == R.id.btn1) {
                cellId = 1;
            } else if (id == R.id.btn2) {
                cellId = 2;
            } else if (id == R.id.btn3) {
                cellId = 3;
            } else if (id == R.id.btn4) {
                cellId = 4;
            } else if (id == R.id.btn5) {
                cellId = 5;
            } else if (id == R.id.btn6) {
                cellId = 6;
            } else if (id == R.id.btn7) {
                cellId = 7;
            } else if (id == R.id.btn8) {
                cellId = 8;
            } else if (id == R.id.btn9) {
                cellId = 9;
            }
            playGame(cellId, btnSelected);
        }
    }

    @Override
    public void onBackPressed() {
        if(isShow) {
            assert AmountTicTacToe.getValue() != null;
            updateUser(this,calWallet(AmountTicTacToe.getValue())[0],calWallet(AmountTicTacToe.getValue())[1],String.valueOf(0));
        }
        if(winMediaPlayer != null && winMediaPlayer.isPlaying()) {
            winMediaPlayer.stop();
        }
        if(looseMediaPlayer != null && looseMediaPlayer.isPlaying()) {
            looseMediaPlayer.stop();
        }
        finish();
    }
}