package com.example.petstoremobile.viewmodels;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.example.petstoremobile.dtos.EmployeeDTO;
import com.example.petstoremobile.dtos.StoreDTO;
import com.example.petstoremobile.repositories.EmployeeRepository;
import com.example.petstoremobile.repositories.StoreRepository;
import com.example.petstoremobile.utils.Resource;

import androidx.lifecycle.Observer;

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

import javax.inject.Inject;

import dagger.hilt.android.lifecycle.HiltViewModel;

@HiltViewModel
public class StaffListViewModel extends ViewModel {
    private final EmployeeRepository repository;
    private final StoreRepository storeRepository;

    private final MutableLiveData<List<EmployeeDTO>> employees = new MutableLiveData<>(new ArrayList<>());
    private final MutableLiveData<List<EmployeeDTO>> filteredEmployees = new MutableLiveData<>(new ArrayList<>());
    private final MutableLiveData<List<StoreDTO>> stores = new MutableLiveData<>(new ArrayList<>());
    private final MutableLiveData<Boolean> isLoading = new MutableLiveData<>(false);

    private int currentPage = 0;
    private boolean isLastPage = false;
    private static final int PAGE_SIZE = 20;

    private String lastQuery = "";
    private Long lastStoreId = null;
    private String lastStatus = "All Statuses";

    @Inject
    public StaffListViewModel(EmployeeRepository repository, StoreRepository storeRepository) {
        this.repository = repository;
        this.storeRepository = storeRepository;
    }

    public LiveData<List<EmployeeDTO>> getFilteredEmployees() { return filteredEmployees; }
    public LiveData<List<StoreDTO>> getStores() { return stores; }
    public LiveData<Boolean> getIsLoading() { return isLoading; }
    public boolean isLastPage() { return isLastPage; }

    public void loadStaff(boolean reset) {
        if (isLoading.getValue() != null && isLoading.getValue() && !reset) return;

        if (reset) {
            currentPage = 0;
            isLastPage = false;
        }

        if (isLastPage) return;

        isLoading.setValue(true);
        observeOnce(repository.getAllEmployees(currentPage, PAGE_SIZE), resource -> {
            if (resource != null) {
                if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
                    List<EmployeeDTO> currentList = reset ? new ArrayList<>() : new ArrayList<>(employees.getValue());
                    currentList.addAll(resource.data.getContent());
                    employees.setValue(currentList);
                    isLastPage = resource.data.isLast();
                    if (!isLastPage) currentPage++;
                    applyFilter(currentList);
                    isLoading.setValue(false);
                } else if (resource.status == Resource.Status.ERROR) {
                    isLoading.setValue(false);
                }
            }
        });
    }

    public void loadStores() {
        observeOnce(storeRepository.getAllStores(0, 100), resource -> {
            if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
                stores.setValue(resource.data.getContent());
            }
        });
    }

    private <T> void observeOnce(LiveData<Resource<T>> liveData, Observer<Resource<T>> handler) {
        liveData.observeForever(new Observer<Resource<T>>() {
            @Override
            public void onChanged(Resource<T> resource) {
                if (resource == null || resource.status != Resource.Status.LOADING) {
                    liveData.removeObserver(this);
                }
                handler.onChanged(resource);
            }
        });
    }

    public void filter(String query, Long storeId, String status) {
        this.lastQuery = query;
        this.lastStoreId = storeId;
        this.lastStatus = status;
        applyFilter(employees.getValue());
    }

    private void applyFilter(List<EmployeeDTO> all) {
        if (all == null) return;

        List<EmployeeDTO> filtered = new ArrayList<>();
        String lowerQuery = lastQuery.toLowerCase();

        for (EmployeeDTO e : all) {
            boolean matchesQuery = lastQuery.isEmpty() ||
                    (e.getFullName() != null && e.getFullName().toLowerCase().contains(lowerQuery)) ||
                    (e.getUsername() != null && e.getUsername().toLowerCase().contains(lowerQuery)) ||
                    (e.getEmail() != null && e.getEmail().toLowerCase().contains(lowerQuery)) ||
                    (e.getPhone() != null && e.getPhone().toLowerCase().contains(lowerQuery));

            boolean matchesStore = lastStoreId == null || (e.getPrimaryStoreId() != null && e.getPrimaryStoreId().equals(lastStoreId));

            boolean matchesStatus = lastStatus.equals("All Statuses") ||
                    (lastStatus.equals("Active") && Boolean.TRUE.equals(e.getActive())) ||
                    (lastStatus.equals("Inactive") && Boolean.FALSE.equals(e.getActive()));

            if (matchesQuery && matchesStore && matchesStatus) {
                filtered.add(e);
            }
        }
        filteredEmployees.setValue(filtered);
    }
}
