package com.example.petstoremobile.viewmodels;

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

import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.repositories.ServiceRepository;
import com.example.petstoremobile.utils.Resource;

import androidx.lifecycle.Observer;

import javax.inject.Inject;

import dagger.hilt.android.lifecycle.HiltViewModel;

@HiltViewModel
public class ServiceDetailViewModel extends ViewModel {
    private final ServiceRepository repository;
    private final MutableLiveData<ViewState> viewState = new MutableLiveData<>(new ViewState());

    private long serviceId = -1;

    @Inject
    public ServiceDetailViewModel(ServiceRepository repository) {
        this.repository = repository;
    }

    public void setServiceId(long id) {
        this.serviceId = id;
        initMode(id != -1);
    }

    public long getServiceId() {
        return serviceId;
    }

    public boolean isEditing() {
        ViewState current = viewState.getValue();
        return current != null && current.isEditing;
    }

    public LiveData<ViewState> getViewState() {
        return viewState;
    }

    public void initMode(boolean isEditing) {
        updateViewState(state -> {
            state.isEditing = isEditing;
            state.modeTitle = isEditing ? "Edit Service" : "Add Service";
            state.saveButtonText = isEditing ? "Save" : "Add";
            state.isServiceIdVisible = isEditing;
            state.isDeleteVisible = isEditing;
            state.isFieldsEnabled = true;
        });
    }

    public LiveData<Resource<ServiceDTO>> loadService() {
        MutableLiveData<Resource<ServiceDTO>> result = new MutableLiveData<>();
        observeOnce(repository.getServiceById(serviceId), resource -> {
            if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
                ServiceDTO service = resource.data;
                updateViewState(state -> {
                    state.serviceName = safeText(service.getServiceName());
                    state.serviceDesc = safeText(service.getServiceDesc());
                    state.serviceDuration = service.getServiceDuration() != null ? String.valueOf(service.getServiceDuration()) : "";
                    state.servicePrice = service.getServicePrice() != null ? String.valueOf(service.getServicePrice()) : "";
                });
            }
            result.setValue(resource);
        });
        return result;
    }

    public LiveData<Resource<ServiceDTO>> saveService(ServiceDTO dto) {
        updateViewState(state -> {
            state.serviceName = safeText(dto.getServiceName());
            state.serviceDesc = safeText(dto.getServiceDesc());
            state.serviceDuration = dto.getServiceDuration() != null ? String.valueOf(dto.getServiceDuration()) : "";
            state.servicePrice = dto.getServicePrice() != null ? String.valueOf(dto.getServicePrice()) : "";
        });

        if (isEditing()) {
            dto.setServiceId(serviceId);
            return repository.updateService(serviceId, dto);
        }

        return repository.createService(dto);
    }

    public LiveData<Resource<Void>> deleteService() {
        return repository.deleteService(serviceId);
    }

    private String safeText(String value) {
        return value == null ? "" : value.trim();
    }

    private void updateViewState(Action<ViewState> action) {
        ViewState current = viewState.getValue();
        if (current != null) {
            action.run(current);
            viewState.setValue(current);
        }
    }

    private interface Action<T> {
        void run(T target);
    }

    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 static class ViewState {
        public boolean isEditing = false;
        public boolean isDeleteVisible = false;
        public boolean isServiceIdVisible = false;
        public boolean isFieldsEnabled = true;
        public String modeTitle = "Add Service";
        public String saveButtonText = "Add";
        public String serviceName = "";
        public String serviceDesc = "";
        public String serviceDuration = "";
        public String servicePrice = "";
    }
}
