package cz.kamma.kfmanager.service;

import java.awt.Toolkit;
import java.awt.datatransfer.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ClipboardService {

    public enum ClipboardAction {
        COPY, CUT
    }

    public static void copyToClipboard(List<File> files, ClipboardAction action) {
        if (files == null || files.isEmpty()) return;

        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        FileTransferable transferable = new FileTransferable(files, action);
        clipboard.setContents(transferable, null);
    }

    @SuppressWarnings("unchecked")
    public static List<File> getFilesFromClipboard() {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        if (clipboard.isDataFlavorAvailable(DataFlavor.javaFileListFlavor)) {
            try {
                return (List<File>) clipboard.getData(DataFlavor.javaFileListFlavor);
            } catch (UnsupportedFlavorException | IOException e) {
                e.printStackTrace();
            }
        }
        return new ArrayList<>();
    }

    public static ClipboardAction getClipboardAction() {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        
        // Check for GNOME/KDE flavored cut/copy
        try {
            for (DataFlavor flavor : clipboard.getAvailableDataFlavors()) {
                if ("x-special/gnome-copied-files".equals(flavor.getSubType())) {
                    String data = (String) clipboard.getData(flavor);
                    if (data != null && data.startsWith("cut")) {
                        return ClipboardAction.CUT;
                    }
                    return ClipboardAction.COPY;
                }
            }
        } catch (Exception ignore) {}

        // Check for Windows "Preferred DropEffect"
        try {
            for (DataFlavor flavor : clipboard.getAvailableDataFlavors()) {
                if ("application/x-java-remote-object".equals(flavor.getPrimaryType()) &&
                    Integer.class.isAssignableFrom(flavor.getRepresentationClass()) &&
                    "Preferred DropEffect".equals(flavor.getHumanPresentableName())) {
                    Integer effect = (Integer) clipboard.getData(flavor);
                    if (effect != null && (effect & 2) != 0) { // 2 = MOVE
                        return ClipboardAction.CUT;
                    }
                }
            }
        } catch (Exception ignore) {}

        // Internal fallback (if we set it ourselves)
        if (clipboard.isDataFlavorAvailable(FileTransferable.ACTION_FLAVOR)) {
            try {
                return (ClipboardAction) clipboard.getData(FileTransferable.ACTION_FLAVOR);
            } catch (UnsupportedFlavorException | IOException e) {
                e.printStackTrace();
            }
        }

        return ClipboardAction.COPY;
    }

    private static class FileTransferable implements Transferable {
        public static final DataFlavor ACTION_FLAVOR = new DataFlavor(ClipboardAction.class, "Clipboard Action");
        private final List<File> files;
        private final ClipboardAction action;

        public FileTransferable(List<File> files, ClipboardAction action) {
            this.files = files;
            this.action = action;
        }

        @Override
        public DataFlavor[] getTransferDataFlavors() {
            try {
                return new DataFlavor[]{
                    DataFlavor.javaFileListFlavor,
                    ACTION_FLAVOR,
                    new DataFlavor("x-special/gnome-copied-files;class=java.lang.String")
                };
            } catch (ClassNotFoundException e) {
                return new DataFlavor[]{
                    DataFlavor.javaFileListFlavor,
                    ACTION_FLAVOR
                };
            }
        }

        @Override
        public boolean isDataFlavorSupported(DataFlavor flavor) {
            for (DataFlavor f : getTransferDataFlavors()) {
                if (f.equals(flavor)) return true;
            }
            return false;
        }

        @Override
        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
            if (DataFlavor.javaFileListFlavor.equals(flavor)) {
                return files;
            } else if (ACTION_FLAVOR.equals(flavor)) {
                return action;
            } else if ("x-special".equals(flavor.getPrimaryType()) && "gnome-copied-files".equals(flavor.getSubType())) {
                StringBuilder sb = new StringBuilder();
                sb.append(action == ClipboardAction.CUT ? "cut" : "copy");
                for (File f : files) {
                    sb.append("\n").append(f.toURI().toString());
                }
                return sb.toString();
            }
            throw new UnsupportedFlavorException(flavor);
        }
    }
}
