package com.example.quiz;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

import com.example.quiz.data.adapter.TypeOfBetAdapter;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.PariMise;
import com.example.quiz.data.model.TypeOfBet;
import com.example.quiz.data.model.dtos.NotifPayload;
import com.example.quiz.data.remote.StompManager;
import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding;
import com.example.quiz.utils.AuthNavigator;
import com.example.quiz.utils.LoaderDialog;
import com.example.quiz.utils.MessageDialog;
import com.example.quiz.utils.Result;
import com.example.quiz.utils.SessionManager;
import com.example.quiz.utils.SharedPrefsHelper;
import com.example.quiz.viewModel.AgentViewModel;
import com.example.quiz.viewModel.LoginViewModel;
import com.example.quiz.viewModel.LogsViewModel;
import com.example.quiz.viewModel.PariMiseViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import javax.inject.Inject;

import dagger.hilt.android.AndroidEntryPoint;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link ListOfTypeOfBets#newInstance} factory method to
 * create an instance of this fragment.
 */

@AndroidEntryPoint
public class ListOfTypeOfBets extends Fragment {

    private FragmentListOfTypeOfBetsBinding binding;


    SessionManager sessionManager;
    AuthNavigator authNavigator;

    @Inject
    StompManager stompManager;

    private SharedViewModel shared;


    private TypeOfBetAdapter adapter;

    private SharedPrefsHelper prefsHelper;

    private AgentViewModel agentViewModel;

    private LoaderDialog loaderDialog;


    public ListOfTypeOfBets() {
        // Required empty public constructor
    }
    public static ListOfTypeOfBets newInstance() {
        ListOfTypeOfBets fragment = new ListOfTypeOfBets();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sessionManager = SessionManager.newInstance(getContext());
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentListOfTypeOfBetsBinding.inflate(inflater, container, false);
        authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
        prefsHelper = SharedPrefsHelper.getInstance(getContext());
        loaderDialog = new LoaderDialog(getContext());
        agentViewModel = new ViewModelProvider(this).get(AgentViewModel.class);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if(prefsHelper.get("id") == null){
            MessageDialog.showError(getContext(), "Veuillez vous connecter");
            return;
        }
        agentViewModel.getAvailableBets(prefsHelper.get("id")).observe(getViewLifecycleOwner(), new Observer<Result<List<Course.TypeParis>>>() {
            @Override
            public void onChanged(Result<List<Course.TypeParis>> listResult) {
                switch (listResult.status){
                    case LOADING:{
                        loaderDialog.show("Chargement des types de paris");
                        break;
                    }
                    case ERROR:{
                        loaderDialog.dismiss();
                        MessageDialog.showError(getContext(), listResult.message);
                        break;
                    }
                    case SUCCESS:{
                        loaderDialog.dismiss();
                        syncAuthorizedBets(listResult.data);
                        break;
                    }
                }
            }
        });
    }

    public void syncAuthorizedBets(List<Course.TypeParis> authorizedBets){
        binding.typeOfBetRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        // Observers
        if(shared.selectedCourse.getValue() == null){
            return;
        }
        Course sCourse = shared.selectedCourse.getValue();
        if(sCourse != null){
            stompManager.subscribe("courses/"+sCourse.getId(), json->{
                requireActivity().runOnUiThread(()->{
                    Type type = new TypeToken<NotifPayload<Course>>(){}.getType();
                    NotifPayload<Course> notif = new Gson().fromJson(json, type);
                    Course updatedCourse = notif.getPayload();
                    if(sCourse.getId() == updatedCourse.getId()){
                        shared.setSelectedCourse(updatedCourse);
                    }
                });
            });
        }

        // ⚡ Initialiser l’adapter UNE SEULE FOIS
        adapter = new TypeOfBetAdapter(new ArrayList<>());
        binding.typeOfBetRecyclerView.setAdapter(adapter);
        List<Course.TypeParis> betType = sCourse.getTypesParisOuverts();
        List<TypeOfBet>  useList = new ArrayList<>();
        if(betType.contains(Course.TypeParis.QUINTE)){
            useList.add(new TypeOfBet("Quinte", Course.TypeParis.QUINTE, 5));
        }
        if(betType.contains(Course.TypeParis.QUARTE)){
            useList.add(new TypeOfBet("Quarte", Course.TypeParis.QUARTE, 4));
        }
        if(betType.contains(Course.TypeParis.TIERCE)){
            useList.add(new TypeOfBet("Tierce", Course.TypeParis.TIERCE, 3));
        }
        if(betType.contains(Course.TypeParis.COUPLE_PLACE)){
            useList.add(new TypeOfBet("Couple Place", Course.TypeParis.COUPLE_PLACE, 2));
        }
        if(betType.contains(Course.TypeParis.COUPLE_PLACE)){
            useList.add(new TypeOfBet("Couple Gagnant", Course.TypeParis.COUPLE_GAGNANT, 2));
        }
        AtomicReference<TypeOfBet> typeOfBet = new AtomicReference<>();
        List<TypeOfBet> availableTypeOfBets = useList.stream().filter(type -> authorizedBets.contains(type.getName())).collect(Collectors.toList());
        adapter.setTypes(availableTypeOfBets);
        adapter.setOnItemClickListener(type -> {
            typeOfBet.set(type);
        });
        Button btnValidate = binding.btnValidate;
        btnValidate.setOnClickListener(v->{
            if(typeOfBet.get() == null){
                Toast.makeText(getContext(),"Aucun Type de jeu choisi", Toast.LENGTH_SHORT).show();
                return;
            }
            shared.setTypeOfBet(typeOfBet.get());

            BetValidation betValidation = BetValidation.newInstance();
            authNavigator.navigate(betValidation);
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        AppCompatActivity activity = (AppCompatActivity) getActivity();
        if(activity != null){
            MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
            activity.setSupportActionBar(toolbar);
            if(activity.getSupportActionBar() != null){
                activity.getSupportActionBar().setTitle("Liste des jeux");
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stompManager.disconnect();
    }
}