package com.kolobochki.memory;

import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.fragment.app.Fragment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AlertDialog;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Room;

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class fragment_task1 extends Fragment {

    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private String mParam1;
    private String mParam2;
    private OnBackPressedCallback backPressedCallback;
    private String previousTitle;

    // Game constants
    private static final int PAIRS_COUNT = 6;
    private static final int GRID_COLUMNS = 4;
    private static final int PREVIEW_TIME = 5000;
    private static final int SUCCESS_DELAY = 4000;
    private static final int INITIAL_LIVES = 3;
    private static final int LEVEL_ID = 1; // ID для первого уровня

    // Game variables
    private int score = 0;
    private int lives = INITIAL_LIVES;
    private ImageView firstFlipped = null;
    private boolean isPreview = true;
    private boolean isGameComplete = false;

    // Views
    private GridLayout gridLayout;
    private ProgressBar progressBar;
    private List<Integer> tileImages = new ArrayList<>();
    private List<ImageView> tiles = new ArrayList<>();
    private LinearLayout livesLayout;

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

    public fragment_task1() {}

    @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();

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

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

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

        gridLayout = view.findViewById(R.id.gridLayout);
        progressBar = view.findViewById(R.id.progressBar);
        livesLayout = view.findViewById(R.id.livesLayout);

        setupGame();

        return view;
    }

    private void setupGame() {
        gridLayout.removeAllViews();
        tiles.clear();
        tileImages.clear();
        livesLayout.removeAllViews();

        score = 0;
        lives = INITIAL_LIVES;
        firstFlipped = null;
        isPreview = true;
        isGameComplete = false;

        progressBar.setProgress(0);
        updateHearts();

        List<Integer> imageResources = new ArrayList<>();
        imageResources.add(R.drawable.tile1);
        imageResources.add(R.drawable.tile2);
        imageResources.add(R.drawable.tile3);
        imageResources.add(R.drawable.tile4);
        imageResources.add(R.drawable.tile5);
        imageResources.add(R.drawable.tile6);

        Collections.shuffle(imageResources);
        for (int i = 0; i < PAIRS_COUNT; i++) {
            tileImages.add(imageResources.get(i));
            tileImages.add(imageResources.get(i));
        }
        Collections.shuffle(tileImages);

        gridLayout.setColumnCount(GRID_COLUMNS);
        for (int i = 0; i < tileImages.size(); i++) {
            ImageView tile = new ImageView(getContext());
            GridLayout.LayoutParams params = new GridLayout.LayoutParams();
            params.width = 191;
            params.height = 209;
            params.setMargins(8, 8, 8, 8);
            tile.setLayoutParams(params);

            tile.setImageResource(tileImages.get(i));
            tile.setTag(i);
            tile.setOnClickListener(this::onTileClicked);

            tiles.add(tile);
            gridLayout.addView(tile);
        }

        new Handler().postDelayed(() -> {
            isPreview = false;
            flipAllTiles();
        }, PREVIEW_TIME);
    }

    private void flipAllTiles() {
        for (ImageView tile : tiles) {
            tile.setImageResource(R.drawable.tile_back);
        }
    }

    private void onTileClicked(View view) {
        if (isPreview || isGameComplete) return;

        ImageView clickedTile = (ImageView) view;
        int position = (int) clickedTile.getTag();

        if (clickedTile.getDrawable().getConstantState() ==
                getResources().getDrawable(tileImages.get(position)).getConstantState()) {
            return;
        }

        clickedTile.setImageResource(tileImages.get(position));

        if (firstFlipped == null) {
            firstFlipped = clickedTile;
        } else {
            if (tileImages.get((int)firstFlipped.getTag()).equals(tileImages.get(position))) {
                score++;
                progressBar.setProgress(score * 100 / PAIRS_COUNT);
                firstFlipped = null;

                if (score == PAIRS_COUNT) {
                    gameComplete();
                }
            } else {
                lives--;
                updateHearts();

                new Handler().postDelayed(() -> {
                    firstFlipped.setImageResource(R.drawable.tile_back);
                    clickedTile.setImageResource(R.drawable.tile_back);
                    firstFlipped = null;

                    if (lives <= 0) {
                        gameOver();
                    }
                }, 1000);
            }
        }
    }

    private void updateHearts() {
        livesLayout.removeAllViews();
        for (int i = 0; i < lives; i++) {
            ImageView heart = new ImageView(getContext());
            heart.setImageResource(R.drawable.ic_heart);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT
            );
            params.setMargins(4, 0, 4, 0);
            heart.setLayoutParams(params);
            livesLayout.addView(heart);
        }
    }

    private void gameComplete() {
        isGameComplete = true;
        saveGameResult(true);
        new Handler().postDelayed(this::navigateHome, 1500);
    }

    private void gameOver() {
        isGameComplete = true;
        saveGameResult(false);
        new AlertDialog.Builder(requireContext())
                .setTitle("Игра окончена")
                .setMessage("Вы проиграли. Попробуйте еще раз!")
                .setPositiveButton("OK", (dialog, which) -> navigateHome())
                .setCancelable(false)
                .show();
    }

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

                if (existingRecord == null) {
                    // Первая запись для этого уровня
                    LevelRecord newRecord = new LevelRecord(LEVEL_ID, isWin ? score : 0, 1);
                    levelRecordDao.insert(newRecord);

                    if (isWin) {
                        showNewRecordToast(score);
                    }
                } else {
                    boolean isNewRecord = false;

                    if (isWin && score > existingRecord.bestScore) {
                        existingRecord.bestScore = score;
                        isNewRecord = true;
                    }

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

                    if (isNewRecord) {
                        showNewRecordToast(score);
                    }
                }
            } 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 navigateHome() {
        NavController navController = Navigation.findNavController(requireView());
        navController.popBackStack();
    }

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

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

    @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);
            }
        }
    }
}