package de.renew.navigator.gui.actions;

import java.awt.Image;
import java.awt.event.ActionEvent;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;

import CH.ifa.draw.util.Iconkit;
import de.renew.navigator.FilesystemController;
import de.renew.navigator.gui.NavigatorIcons;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class OpenNetPathActionTest {

    @Mock
    FilesystemController filesystemController;
    @Mock
    Iconkit iconkit;
    @Mock
    Image originalImage;
    @Mock
    Image scaledImage;

    @Test
    void constructorSetsTooltipIconAndNoAccelerator() {
        try (MockedStatic<Iconkit> iconStatic = mockStatic(Iconkit.class)) {
            iconStatic.when(Iconkit::instance).thenReturn(iconkit);
            when(iconkit.loadImage(NavigatorIcons.ICON_NETPATH)).thenReturn(originalImage);
            when(originalImage.getScaledInstance(-1, 16, Image.SCALE_SMOOTH))
                .thenReturn(scaledImage);

            OpenNetPathAction action = new OpenNetPathAction(filesystemController);

            assertEquals(
                "Open NetPaths of simulator properties", action.getValue("ShortDescription"));
            assertNull(action.getValue(Action.ACCELERATOR_KEY));
            ImageIcon icon = (ImageIcon) action.getValue(Action.SMALL_ICON);
            assertSame(scaledImage, icon.getImage());
            assertEquals("Open Net Path", action.getActionName());
        }
    }

    @Test
    void actionPerformedCallsLoadFromNetPaths() {
        try (MockedStatic<Iconkit> iconStatic = mockStatic(Iconkit.class)) {
            iconStatic.when(Iconkit::instance).thenReturn(iconkit);
            when(iconkit.loadImage(anyString())).thenReturn(originalImage);
            when(originalImage.getScaledInstance(anyInt(), anyInt(), anyInt()))
                .thenReturn(scaledImage);

            OpenNetPathAction action = new OpenNetPathAction(filesystemController);
            action.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null));

            verify(filesystemController).loadFromNetPaths();
        }
    }

    @Test
    void actionPerformedOnExceptionShowsErrorDialog() {
        try (MockedStatic<Iconkit> iconStatic = mockStatic(Iconkit.class);
            MockedStatic<JOptionPane> paneStatic = mockStatic(JOptionPane.class)) {

            iconStatic.when(Iconkit::instance).thenReturn(iconkit);
            when(iconkit.loadImage(anyString())).thenReturn(originalImage);
            when(originalImage.getScaledInstance(anyInt(), anyInt(), anyInt()))
                .thenReturn(scaledImage);

            doThrow(new RuntimeException("boom")).when(filesystemController).loadFromNetPaths();

            OpenNetPathAction action = new OpenNetPathAction(filesystemController);
            action.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null));

            paneStatic.verify(
                () -> JOptionPane.showMessageDialog(
                    null, "boom", "Open Net Path failed", JOptionPane.ERROR_MESSAGE));
        }
    }
}
