package io.xpipe.ext.system.podman;

import io.xpipe.app.comp.BaseRegionBuilder;
import io.xpipe.app.ext.*;
import io.xpipe.app.hub.comp.*;
import io.xpipe.app.platform.BindingsHelper;
import io.xpipe.app.platform.OptionsBuilder;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.util.*;
import io.xpipe.ext.base.service.FixedServiceGroupStore;
import io.xpipe.ext.base.store.ShellStoreProvider;

import javafx.beans.property.Property;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;

import java.util.List;

public class PodmanContainerStoreProvider implements ShellStoreProvider {

    @Override
    public DocumentationLink getHelpLink() {
        return DocumentationLink.PODMAN;
    }

    @Override
    public boolean shouldShow(StoreEntryWrapper w) {
        PodmanContainerStore s = w.getEntry().getStore().asNeeded();
        var state = s.getState();
        return Boolean.TRUE.equals(state.getRunning())
                || s.getCmd().getStore().getState().isShowNonRunning();
    }

    public void onParentRefresh(DataStoreEntry entry) {
        var services = FixedServiceGroupStore.builder().parent(entry.ref()).build();
        var servicesEntry = DataStorage.get().getStoreEntryIfPresent(services, false);
        if (servicesEntry.isPresent()) {
            DataStorage.get().refreshChildren(servicesEntry.get());
        }
    }

    @Override
    public boolean shouldShowScan() {
        return false;
    }

    @Override
    public DataStoreEntry getDisplayParent(DataStoreEntry store) {
        PodmanContainerStore s = store.getStore().asNeeded();
        return s.getCmd().get();
    }

    @Override
    public GuiDialog guiDialog(StoreCreationModel model, Property<DataStore> store) {
        PodmanContainerStore st = (PodmanContainerStore) store.getValue();

        return new OptionsBuilder()
                .name("host")
                .description("podmanHostDescription")
                .addComp(new StoreChoiceComp<>(
                        model.getExistingEntry(),
                        new ReadOnlyObjectWrapper<>(
                                st.getCmd() != null ? st.getCmd().getStore().getHost() : null),
                        ShellStore.class,
                        null,
                        StoreViewState.get().getAllConnectionsCategory(),
                        DataStoreCreationCategory.HOST))
                .disable()
                .name("container")
                .description("podmanContainerDescription")
                .addStaticString(st.getContainerName())
                .buildDialog();
    }

    @Override
    public String getDisplayIconFileName(DataStore store) {
        return "system:podman_icon.svg";
    }

    @Override
    public String getId() {
        return "podman";
    }

    @Override
    public List<Class<?>> getStoreClasses() {
        return List.of(PodmanContainerStore.class);
    }

    public BaseRegionBuilder<?, ?> stateDisplay(StoreSection section) {
        return new OsLogoComp(
                section.getWrapper(), BindingsHelper.map(section.getWrapper().getPersistentState(), o -> {
                    var state = (ContainerStoreState) o;
                    var cs = state.getContainerState();
                    if (cs != null && cs.toLowerCase().contains("exited")) {
                        return SystemStateComp.State.FAILURE;
                    } else if (cs != null && cs.toLowerCase().contains("up")) {
                        return SystemStateComp.State.SUCCESS;
                    } else {
                        return SystemStateComp.State.OTHER;
                    }
                }));
    }

    @Override
    public ObservableValue<String> informationString(StoreSection section) {
        var c = (PodmanContainerStoreState)
                section.getWrapper().getPersistentState().getValue();
        var missing = c.getShellMissing() != null && c.getShellMissing() ? "No shell available" : null;
        return StoreStateFormat.shellStore(
                section,
                (ContainerStoreState s) -> new String[] {missing, s.getContainerState(), c.getSystemdUnit()},
                null);
    }
}
