package p.studio.workspaces.assets.details.bank;

import p.studio.controls.forms.StudioFormMode;
import p.studio.controls.forms.StudioFormSession;
import p.studio.workspaces.assets.messages.AssetWorkspaceAssetDetails;
import p.studio.workspaces.assets.messages.AssetWorkspaceBankCompositionFile;

import java.util.List;
import java.util.Objects;

public final class AssetDetailsBankCompositionCoordinator {
    private final List<AssetDetailsBankCompositionFamilySupport> familySupports = List.of(
            new AssetDetailsGlyphBankCompositionFamilySupport(),
            new AssetDetailsSoundBankCompositionFamilySupport(),
            new AssetDetailsFallbackBankCompositionFamilySupport());

    private AssetDetailsBankCompositionFamilySupport familySupport;
    private StudioFormSession<AssetDetailsBankCompositionDraft> formSession;

    public void replaceDetails(AssetWorkspaceAssetDetails details) {
        if (details == null) {
            familySupport = null;
            formSession = null;
            return;
        }

        familySupport = familySupports.stream()
                .filter(candidate -> candidate.supports(details.summary().assetFamily()))
                .findFirst()
                .orElseThrow();
        final AssetDetailsBankCompositionDraft source = familySupport.createDraft(details);
        if (formSession == null) {
            formSession = new StudioFormSession<>(source);
            return;
        }
        if (!Objects.equals(formSession.source(), source)) {
            formSession.replaceSource(source);
        }
    }

    public boolean ready() {
        return formSession != null && familySupport != null;
    }

    public void beginEdit() {
        if (ready()) {
            formSession.beginEdit();
        }
    }

    public void apply() {
        if (ready()) {
            formSession.apply();
        }
    }

    public void reset() {
        if (ready()) {
            formSession.resetDraft();
        }
    }

    public void cancel() {
        if (ready()) {
            formSession.cancelEdit();
        }
    }

    public void moveToSelected(List<AssetWorkspaceBankCompositionFile> files) {
        if (!ready() || formSession.mode() != StudioFormMode.EDITING) {
            return;
        }
        formSession.updateDraft(current -> familySupport.moveToSelected(current, files));
    }

    public void moveToAvailable(List<AssetWorkspaceBankCompositionFile> files) {
        if (!ready() || formSession.mode() != StudioFormMode.EDITING) {
            return;
        }
        formSession.updateDraft(current -> familySupport.moveToAvailable(current, files));
    }

    public void moveUp(int selectedIndex) {
        if (!ready() || formSession.mode() != StudioFormMode.EDITING) {
            return;
        }
        formSession.updateDraft(current -> familySupport.moveUp(current, selectedIndex));
    }

    public void moveDown(int selectedIndex) {
        if (!ready() || formSession.mode() != StudioFormMode.EDITING) {
            return;
        }
        formSession.updateDraft(current -> familySupport.moveDown(current, selectedIndex));
    }

    public AssetDetailsBankCompositionViewModel viewModel() {
        if (!ready()) {
            return new AssetDetailsBankCompositionViewModel(
                    false,
                    false,
                    List.of(),
                    List.of(),
                    new AssetDetailsBankCompositionCapacityState(0.0d, null, false, "", ""));
        }

        final AssetDetailsBankCompositionDraft draft = formSession.draft();
        return new AssetDetailsBankCompositionViewModel(
                formSession.mode() == StudioFormMode.EDITING,
                formSession.isDirty(),
                draft.availableFiles(),
                draft.selectedFiles(),
                familySupport.evaluate(draft));
    }
}
