package com.example.petstoremobile.fragments.listfragments;

import android.os.Bundle;
import android.view.*;
import android.widget.*;
import androidx.annotation.NonNull;
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 com.example.petstoremobile.R;
import com.example.petstoremobile.adapters.EmployeeAdapter;
import com.example.petstoremobile.api.auth.TokenManager;
import com.example.petstoremobile.databinding.FragmentStaffBinding;
import com.example.petstoremobile.dtos.EmployeeDTO;
import com.example.petstoremobile.dtos.StoreDTO;
import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.StaffListViewModel;
import dagger.hilt.android.AndroidEntryPoint;
import java.util.*;

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

@AndroidEntryPoint
public class StaffFragment extends Fragment implements EmployeeAdapter.OnEmployeeClickListener {

    private FragmentStaffBinding binding;
    private StaffListViewModel viewModel;
    private List<EmployeeDTO> staffList = new ArrayList<>();
    private EmployeeAdapter adapter;

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

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentStaffBinding.inflate(inflater, container, false);
        viewModel = new ViewModelProvider(this).get(StaffListViewModel.class);

        setupRecyclerView();
        setupSearch();
        setupStatusFilter();
        setupStoreFilter();
        setupSwipeRefresh();
        observeViewModel();

        viewModel.loadStaff(true);
        viewModel.loadStores();

        binding.fabAddStaff.setOnClickListener(v -> openDetail(-1));

        UIUtils.setupHamburgerMenu(binding.btnHamburgerStaff, this);
        UIUtils.setupFilterToggle(binding.btnToggleFilterStaff, binding.layoutFilterStaff, binding.etSearchStaff,
                binding.spinnerStoreStaff, binding.spinnerStatusStaff);

        return binding.getRoot();
    }

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

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

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

    private void setupRecyclerView() {
        adapter = new EmployeeAdapter(staffList, this);
        adapter.setBaseUrl(baseUrl);
        adapter.setToken(tokenManager.getToken());
        binding.recyclerViewStaff.setLayoutManager(new LinearLayoutManager(getContext()));
        binding.recyclerViewStaff.setAdapter(adapter);

        binding.recyclerViewStaff.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                if (dy <= 0) return;
                LinearLayoutManager lm = (LinearLayoutManager) binding.recyclerViewStaff.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) {
                    viewModel.loadStaff(false);
                }
            }
        });
    }

    private void setupStatusFilter() {
        String[] statuses = {"All Statuses", "Active", "Inactive"};
        SpinnerUtils.setupStringFilterSpinner(requireContext(), binding.spinnerStatusStaff, statuses, this::applyFilters);
    }

    private void setupStoreFilter() {
        SpinnerUtils.setupFilterSpinner(binding.spinnerStoreStaff, this::applyFilters);
    }

    private void setupSearch() {
        UIUtils.attachSearch(binding.etSearchStaff, this::applyFilters);
    }

    private void applyFilters() {
        String query = binding.etSearchStaff.getText().toString().trim();
        String status = binding.spinnerStatusStaff.getSelectedItem() != null ?
                binding.spinnerStatusStaff.getSelectedItem().toString() : "All Statuses";

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

        viewModel.filter(query, storeId, status);
    }

    private void setupSwipeRefresh() {
        binding.swipeRefreshStaff.setOnRefreshListener(() -> viewModel.loadStaff(true));
    }

    private void openDetail(int position) {
        Bundle args = new Bundle();
        if (position != -1) {
            EmployeeDTO e = staffList.get(position);
            args.putLong("employeeId", e.getId());
            args.putString("username", e.getUsername() != null ? e.getUsername() : "");
            args.putString("firstName", e.getFirstName() != null ? e.getFirstName() : "");
            args.putString("lastName", e.getLastName() != null ? e.getLastName() : "");
            args.putString("email", e.getEmail() != null ? e.getEmail() : "");
            args.putString("phone", e.getPhone() != null ? e.getPhone() : "");
            args.putString("role", e.getRole() != null ? e.getRole() : "STAFF");
            args.putBoolean("active", Boolean.TRUE.equals(e.getActive()));
            args.putBoolean("isEditing", true);
        }
        NavHostFragment.findNavController(this).navigate(R.id.nav_staff_detail, args);
    }

    @Override
    public void onEmployeeClick(int position) {
        openDetail(position);
    }

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