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

import p.studio.workspaces.assets.messages.AssetWorkspaceBankCompositionFile;

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

public record AssetDetailsPaletteOverhaulingDraft(
        List<AssetWorkspaceBankCompositionFile> previewTileFiles,
        List<AssetWorkspaceBankCompositionFile> allFiles,
        List<AssetWorkspaceBankCompositionFile> availableFiles,
        List<AssetWorkspaceBankCompositionFile> selectedFiles,
        String previewTilePath,
        String previewPalettePath) {
    private static final int MIN_SELECTED = 1;
    private static final int MAX_SELECTED = 64;

    public AssetDetailsPaletteOverhaulingDraft {
        previewTileFiles = List.copyOf(Objects.requireNonNull(previewTileFiles, "previewTileFiles"));
        allFiles = List.copyOf(Objects.requireNonNull(allFiles, "allFiles"));
        availableFiles = List.copyOf(Objects.requireNonNull(availableFiles, "availableFiles"));
        selectedFiles = List.copyOf(Objects.requireNonNull(selectedFiles, "selectedFiles"));
        previewTilePath = normalize(previewTilePath);
        previewPalettePath = normalize(previewPalettePath);
    }

    public AssetDetailsPaletteOverhaulingDraft moveToSelected(List<AssetWorkspaceBankCompositionFile> files) {
        final List<AssetWorkspaceBankCompositionFile> accepted = new ArrayList<>();
        for (AssetWorkspaceBankCompositionFile file : files) {
            if (file == null || !availableFiles.contains(file) || selectedFiles.contains(file)) {
                continue;
            }
            if (selectedFiles.size() + accepted.size() >= MAX_SELECTED) {
                break;
            }
            accepted.add(file);
        }
        if (accepted.isEmpty()) {
            return this;
        }

        final List<AssetWorkspaceBankCompositionFile> nextAvailable = new ArrayList<>(availableFiles);
        nextAvailable.removeAll(accepted);
        final List<AssetWorkspaceBankCompositionFile> nextSelected = new ArrayList<>(selectedFiles);
        nextSelected.addAll(accepted);
        final String nextPreviewPalettePath = previewPalettePath == null ? accepted.getFirst().path() : previewPalettePath;
        return new AssetDetailsPaletteOverhaulingDraft(previewTileFiles, allFiles, nextAvailable, nextSelected, previewTilePath, nextPreviewPalettePath);
    }

    public AssetDetailsPaletteOverhaulingDraft moveToAvailable(List<AssetWorkspaceBankCompositionFile> files) {
        final List<AssetWorkspaceBankCompositionFile> removed = new ArrayList<>();
        for (AssetWorkspaceBankCompositionFile file : files) {
            if (file != null && selectedFiles.contains(file)) {
                removed.add(file);
            }
        }
        if (removed.isEmpty() || selectedFiles.size() - removed.size() < MIN_SELECTED) {
            return this;
        }

        final List<AssetWorkspaceBankCompositionFile> nextSelected = new ArrayList<>(selectedFiles);
        nextSelected.removeAll(removed);
        final List<AssetWorkspaceBankCompositionFile> nextAvailable = new ArrayList<>(availableFiles);
        nextAvailable.addAll(removed);
        final String nextPreviewPalettePath = removed.stream().anyMatch(file -> file.path().equals(previewPalettePath))
                ? nextSelected.getFirst().path()
                : previewPalettePath;
        return new AssetDetailsPaletteOverhaulingDraft(previewTileFiles, allFiles, nextAvailable, nextSelected, previewTilePath, nextPreviewPalettePath);
    }

    public AssetDetailsPaletteOverhaulingDraft selectPreviewTile(String path) {
        final String normalized = normalize(path);
        if (normalized == null || previewTileFiles.stream().noneMatch(file -> file.path().equals(normalized))) {
            return this;
        }
        return new AssetDetailsPaletteOverhaulingDraft(previewTileFiles, allFiles, availableFiles, selectedFiles, normalized, previewPalettePath);
    }

    public AssetDetailsPaletteOverhaulingDraft selectPreviewPalette(String path) {
        final String normalized = normalize(path);
        if (normalized == null || allFiles.stream().noneMatch(file -> file.path().equals(normalized))) {
            return this;
        }
        return new AssetDetailsPaletteOverhaulingDraft(previewTileFiles, allFiles, availableFiles, selectedFiles, previewTilePath, normalized);
    }

    private static String normalize(String path) {
        if (path == null) {
            return null;
        }
        final String trimmed = path.trim();
        return trimmed.isBlank() ? null : trimmed;
    }
}
