package com.example.petstoremobile.fragments.listfragments;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.PetAdapter;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.databinding.FragmentPetBinding;
import com.example.petstoremobile.dtos.PetDTO;
import com.example.petstoremobile.dtos.StoreDTO;
import com.example.petstoremobile.utils.BulkDeleteHandler;
import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.PetListViewModel;

import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import dagger.hilt.android.AndroidEntryPoint;

@AndroidEntryPoint
public class PetFragment extends Fragment implements PetAdapter.OnPetClickListener {
    private FragmentPetBinding binding;
    private List<PetDTO> petList = new ArrayList<>();
    private PetAdapter adapter;
    private PetListViewModel viewModel;
    private BulkDeleteHandler bulkDeleteHandler;

    @Inject @Named("baseUrl") String baseUrl;
    @Inject TokenManager tokenManager;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModel = new ViewModelProvider(this).get(PetListViewModel.class);
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentPetBinding.inflate(inflater, container, false);

        setupRecyclerView();
        setupSearch();
        setupStatusFilter();
        setupSpeciesFilter();
        setupStoreFilter();
        setupSwipeRefresh();
        setupFilterToggle();
        setupBulkDelete();
        observeViewModel();

        binding.fabAddPet.setOnClickListener(v -> openPetDetails());

        UIUtils.setupHamburgerMenu(binding.btnHamburger, this);

        return binding.getRoot();
    }

    private void observeViewModel() {
        viewModel.getPets().observe(getViewLifecycleOwner(), list -> {
            petList.clear();
            petList.addAll(list);
            adapter.notifyDataSetChanged();
        });

        viewModel.getStores().observe(getViewLifecycleOwner(), list -> {
            SpinnerUtils.populateWhiteSpinner(requireContext(), binding.spinnerStore, list,
                    StoreDTO::getStoreName, "All Stores", -1L, StoreDTO::getStoreId);
        });

        viewModel.getIsLoading().observe(getViewLifecycleOwner(), loading -> {
            binding.swipeRefreshPet.setRefreshing(loading);
        });

        viewModel.getSpeciesOptions().observe(getViewLifecycleOwner(), options -> {
            String[] arr = options.toArray(new String[0]);
            SpinnerUtils.setupStringFilterSpinner(requireContext(), binding.spinnerSpecies, arr, () -> loadPetData(true));
        });
    }

    private void setupBulkDelete() {
        bulkDeleteHandler = new BulkDeleteHandler(
                this,
                binding.layoutBulkDelete,
                binding.tvSelectionCount,
                binding.btnBulkDelete,
                adapter,
                "pet",
                viewModel::bulkDeletePets,
                () -> loadPetData(true)
        );
    }

    @Override
    public void onResume() {
        super.onResume();
        loadPetData(true);
        viewModel.loadSpecies();
        if (!isStaff()) viewModel.loadStores();
    }

    private void setupFilterToggle() {
        if (isStaff()) {
            UIUtils.setupFilterToggle(binding.btnToggleFilter, binding.layoutFilter, binding.etSearchPet,
                    binding.spinnerStatus, binding.spinnerSpecies);
            binding.spinnerStore.setVisibility(View.GONE);
        } else {
            UIUtils.setupFilterToggle(binding.btnToggleFilter, binding.layoutFilter, binding.etSearchPet,
                    binding.spinnerStatus, binding.spinnerSpecies, binding.spinnerStore);
        }
    }

    private boolean isStaff() {
        return "STAFF".equalsIgnoreCase(tokenManager.getRole());
    }

    private void setupSearch() {
        UIUtils.attachSearch(binding.etSearchPet, () -> loadPetData(true));
    }

    private void setupStatusFilter() {
        String[] statuses = {"All Statuses", "Available", "Adopted", "Owned", "Pending"};
        SpinnerUtils.setupStringFilterSpinner(requireContext(), binding.spinnerStatus, statuses, () -> loadPetData(true));
    }

    private void setupSpeciesFilter() {
        String[] initial = {"All Species"};
        SpinnerUtils.setupStringFilterSpinner(requireContext(), binding.spinnerSpecies, initial, () -> loadPetData(true));
    }

    private void setupStoreFilter() {
        SpinnerUtils.setupFilterSpinner(binding.spinnerStore, () -> loadPetData(true));
    }

    private void setupSwipeRefresh() {
        binding.swipeRefreshPet.setOnRefreshListener(() -> loadPetData(true));
    }

    private void loadPetData(boolean reset) {
        String query = binding.etSearchPet.getText().toString().trim();
        String status = binding.spinnerStatus.getSelectedItem() != null ? binding.spinnerStatus.getSelectedItem().toString() : "All Statuses";
        String species = binding.spinnerSpecies.getSelectedItem() != null ? binding.spinnerSpecies.getSelectedItem().toString() : "All Species";

        Long storeId;
        if (isStaff()) {
            storeId = tokenManager.getPrimaryStoreId();
        } else {
            storeId = null;
            List<StoreDTO> stores = viewModel.getStores().getValue();
            if (binding.spinnerStore.getSelectedItemPosition() > 0 && stores != null && !stores.isEmpty()) {
                storeId = stores.get(binding.spinnerStore.getSelectedItemPosition() - 1).getStoreId();
            }
        }

        viewModel.loadPets(reset, query, status, species, storeId);
    }

    private void setupRecyclerView() {
        adapter = new PetAdapter(petList, this);
        adapter.setBaseUrl(baseUrl);
        adapter.setToken(tokenManager.getToken());
        binding.recyclerViewPets.setLayoutManager(new LinearLayoutManager(getContext()));
        binding.recyclerViewPets.setAdapter(adapter);

        binding.recyclerViewPets.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                if (dy <= 0) return;
                LinearLayoutManager lm = (LinearLayoutManager) binding.recyclerViewPets.getLayoutManager();
                if (lm == null) return;
                int visible = lm.getChildCount();
                int total = lm.getItemCount();
                int firstVis = lm.findFirstVisibleItemPosition();
                Boolean isLoading = viewModel.getIsLoading().getValue();
                if ((isLoading == null || !isLoading) && !viewModel.isLastPage() && (visible + firstVis) >= total - 3) {
                    loadPetData(false);
                }
            }
        });
    }

    private void openPetProfile(int position) {
        Bundle args = new Bundle();
        PetDTO pet = petList.get(position);
        args.putLong("petId", pet.getPetId());
        NavHostFragment.findNavController(this).navigate(R.id.nav_pet_profile, args);
    }

    private void openPetDetails() {
        NavHostFragment.findNavController(this).navigate(R.id.nav_pet_detail);
    }

    @Override
    public void onPetClick(int position) {
        openPetProfile(position);
    }

    @Override
    public void onSelectionChanged(int selectedCount) {
        if (bulkDeleteHandler != null) {
            bulkDeleteHandler.onSelectionChanged(selectedCount);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}
