package com.example.memorymaster;

import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.Collections;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import android.content.Intent;

import nl.dionsegijn.konfetti.KonfettiView;
import nl.dionsegijn.konfetti.models.Shape;
import nl.dionsegijn.konfetti.models.Size;

public class PairMatchingGame extends AppCompatActivity {

    private GridLayout gridLayout;
    private ArrayList<Button> cardButtons;
    private MemoryCard[] cardValues;
    private Button firstSelectedCard = null;
    private boolean isFlipping = false;
    private int matchedPairs = 0;
    private int currentLevel = 1;
    private int totalMoves = 0;
    private int moves = 0;
    private long totalTime = 0;
    private TextView movesTextView;
    private long startTime;
    private Handler timerHandler = new Handler();
    private TextView timerTextView;
    private String nickname;
    private SoundManager soundManager;
    private KonfettiView konfettiView;
    private String playerUserId;
    private FirebaseHelper firebaseHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pair_matching_game);
        konfettiView = findViewById(R.id.konfettiView);
        soundManager = SoundManager.getInstance(this);

        gridLayout = findViewById(R.id.gridLayout);
        cardButtons = new ArrayList<>();
        movesTextView = findViewById(R.id.movesTextView);
        timerTextView = findViewById(R.id.timerTextView);

        SharedPreferences preferences = getSharedPreferences("game_prefs", MODE_PRIVATE);
        nickname = preferences.getString("nickname", "");

        firebaseHelper = new FirebaseHelper();

        FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
        if (currentUser != null) {
            playerUserId = currentUser.getUid();
        } else {
            Intent intent = new Intent(PairMatchingGame.this, LoginActivity.class);
            startActivity(intent);
            finish();
            return;
        }

        setupGameForLevel(currentLevel);
        startTimer();
    }

    private void setupGameForLevel(int level) {
        int numberOfCards;
        switch (level) {
            case 1:
                numberOfCards = 6;  // Easy level (6 cards)
                break;
            case 2:
                numberOfCards = 12; // Medium level (12 cards)
                break;
            default:
                numberOfCards = 16; // Hard level (16 cards)
        }

        cardValues = new MemoryCard[numberOfCards];
        for (int i = 0; i < numberOfCards / 2; i++) {
            cardValues[i] = new MemoryCard(i + 1);
            cardValues[i + numberOfCards / 2] = new MemoryCard(i + 1);
        }

        setupGameGrid(numberOfCards);
        updateMovesDisplay();

        // Reset matchedPairs and moves for the new level
        matchedPairs = 0;
        moves = 0;
    }

    private void setupGameGrid(int numberOfCards) {
        gridLayout.removeAllViews();
        cardButtons.clear();

        int columnCount = (int) Math.sqrt(numberOfCards);
        gridLayout.setColumnCount(columnCount);

        ArrayList<MemoryCard> cardList = new ArrayList<>();
        Collections.addAll(cardList, cardValues);
        Collections.shuffle(cardList);

        for (MemoryCard card : cardList) {
            Button button = new Button(this);
            button.setTag(card);
            button.setText("");
            button.setBackgroundResource(R.drawable.card_back);

            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.width = 0;
            params.height = GridLayout.LayoutParams.WRAP_CONTENT;
            params.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f);
            params.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, 1f);
            button.setLayoutParams(params);

            button.setOnClickListener(this::onCardClick);
            cardButtons.add(button);
            gridLayout.addView(button);
        }
    }

    private void onCardClick(View view) {
        if (isFlipping) return;

        Button selectedButton = (Button) view;
        MemoryCard selectedCard = (MemoryCard) selectedButton.getTag();

        soundManager.playButtonClickSound();

        if (!selectedButton.getText().toString().isEmpty()) {
            return; // Already matched
        }

        selectedButton.setText(String.valueOf(selectedCard.getValue()));
        selectedButton.setBackgroundResource(R.drawable.card_front);

        if (firstSelectedCard == null) {
            firstSelectedCard = selectedButton;
        } else {
            moves++;
            totalMoves++;
            updateMovesDisplay();

            MemoryCard firstCard = (MemoryCard) firstSelectedCard.getTag();
            if (firstCard.getValue() == selectedCard.getValue()) {
                soundManager.playCorrectSound();
                firstSelectedCard.setEnabled(false);
                selectedButton.setEnabled(false);
                matchedPairs++;

                if (matchedPairs == cardValues.length / 2) {
                    onGameWon();
                }
                firstSelectedCard = null;
            } else {
                soundManager.playWrongSound();
                isFlipping = true;
                new Handler().postDelayed(() -> {
                    firstSelectedCard.setText("");
                    selectedButton.setText("");
                    firstSelectedCard.setBackgroundResource(R.drawable.card_back);
                    selectedButton.setBackgroundResource(R.drawable.card_back);
                    firstSelectedCard = null;
                    isFlipping = false;
                }, 1000);
            }
        }
    }

    private void updateMovesDisplay() {
        movesTextView.setText("Ходы: " + moves + " (Всего: " + totalMoves + ")");
    }

    private void startTimer() {
        startTime = System.currentTimeMillis() - totalTime * 1000;
        timerHandler.postDelayed(timerRunnable, 0);
    }

    private Runnable timerRunnable = new Runnable() {
        @Override
        public void run() {
            long millis = System.currentTimeMillis() - startTime;
            totalTime = millis / 1000;
            int seconds = (int) (totalTime % 60);
            int minutes = (int) (totalTime / 60);

            timerTextView.setText(String.format("%d:%02d", minutes, seconds));
            timerHandler.postDelayed(this, 500);
        }
    };

    private void onGameWon() {
        timerHandler.removeCallbacks(timerRunnable);

        if (currentLevel >= 3) {
            gameCompleted();
            return;
        }

        currentLevel++;
        soundManager.playLevelUpSound();
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Уровень " + (currentLevel - 1) + " пройден!")
                .setMessage("Готовы к Уровню " + currentLevel + "?\nХоды: " + moves + "\nВремя: " + formatTime(totalTime))
                .setPositiveButton("Продолжить", (dialog, which) -> {
                    soundManager.playButtonClickSound();
                    setupGameForLevel(currentLevel);
                    startTimer();
                })
                .setCancelable(false)
                .show();
    }

    private String formatTime(long totalSeconds) {
        long minutes = totalSeconds / 60;
        long seconds = totalSeconds % 60;
        return String.format("%d:%02d", minutes, seconds);
    }

    private void gameCompleted() {
        firebaseHelper.updatePairMatchingStats(playerUserId, totalMoves, totalTime, new FirebaseHelper.UpdateStatsCallback() {
            @Override
            public void onUpdateCompleted(boolean newRecord) {
                if (newRecord) {
                    soundManager.playNewRecordSound();
                    showConfetti();
                } else {
                    soundManager.playVictorySound();
                }

                AlertDialog.Builder builder = new AlertDialog.Builder(PairMatchingGame.this);
                builder.setTitle("Поздравляем!")
                        .setMessage("Вы прошли все уровни!\nВсего ходов: " + totalMoves + "\nВремя: " + formatTime(totalTime))
                        .setPositiveButton("Играть снова", (dialog, which) -> {
                            soundManager.playButtonClickSound();
                            resetGame();
                        })
                        .setNegativeButton("Выйти", (dialog, which) -> {
                            soundManager.playButtonClickSound();
                            finish();
                        })
                        .show();
            }

            @Override
            public void onUpdateFailed(Exception e) {
                Toast.makeText(PairMatchingGame.this, "Ошибка обновления статистики: " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }

    private void resetGame() {
        currentLevel = 1;
        totalMoves = 0;
        totalTime = 0;
        matchedPairs = 0;
        moves = 0;
        setupGameForLevel(currentLevel);
        startTimer();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        timerHandler.removeCallbacks(timerRunnable);
        soundManager.release();
    }

    private void showConfetti() {
        konfettiView.build()
                .addColors(Color.YELLOW, Color.GREEN, Color.MAGENTA)
                .setDirection(0.0, 359.0)
                .setSpeed(1f, 5f)
                .setFadeOutEnabled(true)
                .setTimeToLive(2000L)
                .addShapes(Shape.Square.INSTANCE, Shape.Circle.INSTANCE)
                .addSizes(new Size(12, 5f))
                .setPosition(-50f, konfettiView.getWidth() + 50f, -50f, -50f)
                .streamFor(300, 5000L);
    }
}



расскажи кратко и четко как здесь генерируются пары и как в общем работает игра?