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

import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import p.studio.controls.banks.StudioDualListView;
import p.studio.Container;
import p.studio.utilities.i18n.I18n;
import p.studio.workspaces.assets.messages.AssetWorkspaceBankCompositionFile;

import java.util.Collection;
import java.util.Map;
import java.nio.file.Files;
import java.nio.file.Path;

public final class AssetDetailsBankCompositionDualListView extends StudioDualListView<AssetWorkspaceBankCompositionFile> {
    private static final double THUMBNAIL_SIZE = 28.0d;

    private Path assetRoot;

    public AssetDetailsBankCompositionDualListView() {
        setLeftTitle(Container.i18n().text(I18n.ASSETS_DETAILS_BANK_COMPOSITION_AVAILABLE));
        setRightTitle(Container.i18n().text(I18n.ASSETS_DETAILS_BANK_COMPOSITION_SELECTED));
    }

    public void setAssetRoot(Path assetRoot) {
        this.assetRoot = assetRoot == null ? null : assetRoot.toAbsolutePath().normalize();
    }

    @Override
    protected String itemText(AssetWorkspaceBankCompositionFile item) {
        if (item.displayName().equals(item.path())) {
            return item.displayName();
        }
        return item.displayName() + " [" + item.path() + "]";
    }

    @Override
    protected Node itemGraphic(AssetWorkspaceBankCompositionFile item) {
        final String dimensions = tileDimensions(item.metadata());
        final String colors = tileColorCount(item.metadata());
        if (dimensions == null && colors == null) {
            return null;
        }

        final Node thumbnail = createThumbnail(item);
        final Label nameLabel = new Label(item.displayName());
        nameLabel.getStyleClass().add("assets-details-bank-file-name");
        nameLabel.setWrapText(true);
        nameLabel.setMaxWidth(Double.MAX_VALUE);

        final Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);

        final VBox metaColumn = new VBox(2);
        metaColumn.setAlignment(Pos.CENTER_RIGHT);
        metaColumn.getStyleClass().add("assets-details-bank-file-meta");

        if (dimensions != null) {
            final Label dimensionsLabel = new Label(dimensions);
            dimensionsLabel.getStyleClass().add("assets-details-bank-file-dimensions");
            metaColumn.getChildren().add(dimensionsLabel);
        }
        if (colors != null) {
            final Label colorsLabel = new Label(colors);
            colorsLabel.getStyleClass().add("assets-details-bank-file-colors");
            metaColumn.getChildren().add(colorsLabel);
        }

        final HBox root = thumbnail == null
                ? new HBox(10, nameLabel, spacer, metaColumn)
                : new HBox(10, nameLabel, spacer, thumbnail, metaColumn);
        root.setAlignment(Pos.CENTER_LEFT);
        root.getStyleClass().add("assets-details-bank-file-cell");
        return root;
    }

    private Node createThumbnail(AssetWorkspaceBankCompositionFile item) {
        final Path filePath = assetRoot == null ? null : assetRoot.resolve(item.path()).toAbsolutePath().normalize();
        if (filePath == null) {
            return null;
        }
        if (!Files.isRegularFile(filePath)) {
            return null;
        }
        try {
            final Image image = new Image(filePath.toUri().toString(), THUMBNAIL_SIZE, THUMBNAIL_SIZE, true, true, true);
            if (image.isError()) {
                return null;
            }
            final ImageView imageView = new ImageView(image);
            imageView.setFitWidth(THUMBNAIL_SIZE);
            imageView.setFitHeight(THUMBNAIL_SIZE);
            imageView.setPreserveRatio(true);
            imageView.getStyleClass().add("assets-details-bank-file-thumbnail");
            return imageView;
        } catch (RuntimeException ignored) {
            return null;
        }
    }

    private String tileDimensions(Map<String, Object> metadata) {
        final Map<String, Object> tile = nestedMap(metadata, "tile");
        if (tile == null) {
            return null;
        }
        final Integer width = asInteger(tile.get("width"));
        final Integer height = asInteger(tile.get("height"));
        if (width == null || height == null) {
            return null;
        }
        return width + "x" + height;
    }

    private String tileColorCount(Map<String, Object> metadata) {
        final Map<String, Object> palette = nestedMap(metadata, "palette");
        if (palette == null) {
            return null;
        }
        final Object originalArgb8888 = palette.get("originalArgb8888");
        if (originalArgb8888 instanceof Collection<?> colors) {
            return colors.size() + " colors";
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> nestedMap(Map<String, Object> metadata, String key) {
        final Object value = metadata.get(key);
        if (value instanceof Map<?, ?> nested) {
            return (Map<String, Object>) nested;
        }
        return null;
    }

    private Integer asInteger(Object value) {
        if (value instanceof Number number) {
            return number.intValue();
        }
        if (value instanceof String text) {
            try {
                return Integer.parseInt(text);
            } catch (NumberFormatException ignored) {
                return null;
            }
        }
        return null;
    }
}
