package com.kolobochki.memory;

import static com.kolobochki.memory.R.*;

import android.os.Bundle;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import com.kolobochki.memory.AppDatabase;
import com.kolobochki.memory.LevelRecord;
import com.kolobochki.memory.LevelRecordDao;

public class fragment_task2 extends Fragment {

    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private static final int LEVEL_ID = 2; // ID для второго уровня

    private String mParam1;
    private String mParam2;
    private String previousTitle;
    private boolean isGameComplete = false;

    private List<Integer> sequence = new ArrayList<>();
    private int currentStep = 0;
    private int round = 1;
    private int lives = 3;
    private boolean isShowingSequence = false;
    private boolean isWaitingForInput = false;

    private Button redButton, greenButton, blueButton, yellowButton;
    private ImageView centerImage;
    private TextView roundText, livesText;
    private GridLayout buttonsGrid;

    // Database
    private AppDatabase database;
    private LevelRecordDao levelRecordDao;
    private Executor executor = Executors.newSingleThreadExecutor();

    private final int[] colorImages = {
            R.drawable.simon_red,
            R.drawable.simon_green,
            R.drawable.simon_blue,
            R.drawable.simon_yellow,
            R.drawable.simon_off
    };

    public fragment_task2() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }

        database = AppDatabase.getDatabase(requireContext());
        levelRecordDao = database.levelRecordDao();

        OnBackPressedCallback backPressedCallback = new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() {
                if (!isGameComplete) {
                    showExitConfirmationDialog();
                } else {
                    setEnabled(false);
                    navigateHome();
                }
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, backPressedCallback);

        executor.execute(() -> {
            LevelRecord existingRecord = levelRecordDao.getRecordForLevel(LEVEL_ID);
            if (existingRecord != null) {
                existingRecord.attemptsCount++;
                levelRecordDao.update(existingRecord);
            }
        });

        if (getActivity() instanceof AppCompatActivity) {
            ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
            if (actionBar != null) {
                actionBar.setTitle("Упражнение 2");
            }
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_task2, container, false);

        redButton = view.findViewById(R.id.redButton);
        greenButton = view.findViewById(R.id.greenButton);
        blueButton = view.findViewById(R.id.blueButton);
        yellowButton = view.findViewById(R.id.yellowButton);
        centerImage = view.findViewById(R.id.centerImage);
        roundText = view.findViewById(R.id.roundText);
        livesText = view.findViewById(R.id.livesText);
        buttonsGrid = view.findViewById(R.id.buttonsGrid);

        redButton.setOnClickListener(v -> onColorClicked(0));
        greenButton.setOnClickListener(v -> onColorClicked(1));
        blueButton.setOnClickListener(v -> onColorClicked(2));
        yellowButton.setOnClickListener(v -> onColorClicked(3));

        startNewGame();

        return view;
    }

    private void startNewGame() {
        sequence.clear();
        round = 1;
        lives = 3;
        currentStep = 0;
        isGameComplete = false;
        updateUI();

        for (int i = 0; i < 3; i++) {
            generateNextSequence();
        }

        showSequence();
    }

    private void generateNextSequence() {
        Random random = new Random();
        sequence.add(random.nextInt(4));
    }

    private void showSequence() {
        isShowingSequence = true;
        isWaitingForInput = false;
        buttonsGrid.setVisibility(View.INVISIBLE);

        Handler handler = new Handler();
        for (int i = 0; i < sequence.size(); i++) {
            final int colorIndex = sequence.get(i);
            handler.postDelayed(() -> showColor(colorIndex), i * 1000L);
            handler.postDelayed(() -> resetCenterImage(), i * 1000L + 800L);
        }

        handler.postDelayed(() -> {
            isShowingSequence = false;
            isWaitingForInput = true;
            currentStep = 0;
            buttonsGrid.setVisibility(View.VISIBLE);
            centerImage.setImageResource(R.drawable.simon_off);
        }, sequence.size() * 1000L);
    }

    private void highlightButton(int colorIndex) {
        switch (colorIndex) {
            case 0:
                redButton.setBackgroundResource(R.drawable.simon_red);
                break;
            case 1:
                greenButton.setBackgroundResource(R.drawable.simon_green);
                break;
            case 2:
                blueButton.setBackgroundResource(R.drawable.simon_blue);
                break;
            case 3:
                yellowButton.setBackgroundResource(R.drawable.simon_yellow);
                break;
        }
    }

    private void showColor(int colorIndex) {
        centerImage.setImageResource(colorImages[colorIndex]);
    }

    private void resetCenterImage() {
        centerImage.setImageResource(R.drawable.simon_off);
    }

    private void resetButtons() {
        redButton.setBackgroundResource(R.drawable.simon_off);
        greenButton.setBackgroundResource(R.drawable.simon_off);
        blueButton.setBackgroundResource(R.drawable.simon_off);
        yellowButton.setBackgroundResource(R.drawable.simon_off);
    }

    private void onColorClicked(int colorIndex) {
        if (!isWaitingForInput || isShowingSequence) return;

        showColor(colorIndex);
        new Handler().postDelayed(this::resetCenterImage, 300);

        if (colorIndex == sequence.get(currentStep)) {
            currentStep++;
            if (currentStep == sequence.size()) {
                round++;
                currentStep = 0;
                updateUI();

                checkAndUpdateRecord(round);

                generateNextSequence();
                new Handler().postDelayed(() -> {
                    if (!isGameComplete) {
                        showSequence();
                    }
                }, 1000);
            }
        } else {
            lives--;
            updateUI();
            if (lives <= 0) {
                gameOver();
            } else {
                new Handler().postDelayed(() -> {
                    if (!isGameComplete) {
                        currentStep = 0;
                        showSequence();
                    }
                }, 1000);
            }
        }
    }

    private void checkAndUpdateRecord(int currentRound) {
        executor.execute(() -> {
            LevelRecord record = levelRecordDao.getRecordForLevel(LEVEL_ID);
            if (record != null && currentRound > record.bestScore) {
                record.bestScore = currentRound;
                levelRecordDao.update(record);
                showNewRecordToast(currentRound);
            }
        });
    }

    private void updateUI() {
        roundText.setText("Раунд: " + round);

        StringBuilder hearts = new StringBuilder();
        for (int i = 0; i < lives; i++) {
            hearts.append("❤️");
        }
        livesText.setText(hearts.toString());
    }

    private void gameOver() {
        isGameComplete = true;
        isWaitingForInput = false;

        new AlertDialog.Builder(requireContext())
                .setTitle("Игра окончена")
                .setMessage("Вы прошли " + round + " раундов!")
                .setPositiveButton("Играть снова", (dialog, which) -> {
                    isGameComplete = false;
                    startNewGame();
                })
                .setNegativeButton("Выход", (dialog, which) -> navigateHome())
                .setCancelable(false)
                .show();
    }

    private void saveGameResult(int roundsCompleted) {
        executor.execute(() -> {
            try {
                LevelRecord existingRecord = levelRecordDao.getRecordForLevel(LEVEL_ID);

                if (existingRecord == null) {
                    LevelRecord newRecord = new LevelRecord(LEVEL_ID, roundsCompleted, 1);
                    levelRecordDao.insert(newRecord);
                    showNewRecordToast(roundsCompleted);
                } else {
                    boolean isNewRecord = false;

                    if (roundsCompleted > existingRecord.bestScore) {
                        existingRecord.bestScore = roundsCompleted;
                        isNewRecord = true;
                    }

                    existingRecord.attemptsCount++;
                    levelRecordDao.update(existingRecord);

                    if (isNewRecord) {
                        showNewRecordToast(roundsCompleted);
                    }
                }
            } catch (Exception e) {
                requireActivity().runOnUiThread(() ->
                        Toast.makeText(requireContext(), "Ошибка сохранения: " + e.getMessage(), Toast.LENGTH_SHORT).show()
                );
            }
        });
    }

    private void showNewRecordToast(int score) {
        requireActivity().runOnUiThread(() -> {
            Toast.makeText(requireContext(),
                    "Новый рекорд: " + score + " раундов", Toast.LENGTH_SHORT).show();
        });
    }

    private void showExitConfirmationDialog() {
        new AlertDialog.Builder(requireContext())
                .setTitle("Закончить упражнение?")
                .setMessage("Вы точно хотите закончить упражнение?")
                .setPositiveButton("Да", (dialog, which) -> {
                    NavController navController = Navigation.findNavController(requireView());
                    navController.popBackStack();
                })
                .setNegativeButton("Нет", null)
                .show();
    }

    private void navigateHome() {
        NavController navController = Navigation.findNavController(requireView());
        navController.popBackStack();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (getActivity() != null && ((AppCompatActivity)getActivity()).getSupportActionBar() != null) {
            ((AppCompatActivity)getActivity()).getSupportActionBar().hide();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (getActivity() != null && ((AppCompatActivity)getActivity()).getSupportActionBar() != null) {
            ((AppCompatActivity)getActivity()).getSupportActionBar().show();
        }

        if (getActivity() instanceof AppCompatActivity) {
            ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
            if (actionBar != null && previousTitle != null) {
                actionBar.setTitle(previousTitle);
            }
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (database != null) {
            database.close();
        }
    }
}