package de.renew.draw.ui.api;

import java.io.File;
import java.lang.reflect.Field;
import javax.swing.JFrame;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import CH.ifa.draw.DrawPlugin;
import CH.ifa.draw.IOHelper;
import CH.ifa.draw.application.DrawApplication;
import CH.ifa.draw.io.SimpleFileFilter;
import de.renew.draw.ui.impl.services.DialogServiceImpl;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class DialogApiTest {

    private DialogServiceImpl _mockedService;

    @BeforeEach
    void setUp() throws IllegalAccessException, NoSuchFieldException {
        _mockedService = mock(DialogServiceImpl.class);
        Field serviceField = DialogApi.class.getDeclaredField("_service");
        serviceField.setAccessible(true);
        serviceField.set(null, _mockedService);
    }

    @AfterEach
    void tearDown() {
        _mockedService = null;
    }

    @Test
    void testShowSaveFileDialog() {
        //given
        File mockedFile = Mockito.mock(File.class);
        when(mockedFile.getPath()).thenReturn("Path/to/file");

        SimpleFileFilter mockedFilter = Mockito.mock(SimpleFileFilter.class);
        when(mockedFilter.getDescription()).thenReturn("DummyFilterDescription");
        when(mockedFilter.getExtension()).thenReturn(".pdf");

        IOHelper mockedIOHelper = Mockito.mock(IOHelper.class);
        DrawPlugin mockedDrawPlugin = Mockito.mock(DrawPlugin.class);
        when(mockedDrawPlugin.getIOHelper()).thenReturn(mockedIOHelper);

        try (MockedStatic<DrawPlugin> mockedDrawPluginStatic =
            Mockito.mockStatic(DrawPlugin.class)) {

            mockedDrawPluginStatic.when(DrawPlugin::getCurrentDrawPlugin)
                .thenReturn(mockedDrawPlugin);

            //when
            DialogApi.showSaveFileDialog(mockedFile, mockedFilter);

            //then
            verify(_mockedService).showSaveFileDialog(mockedFile, mockedFilter);
        }
    }

    @Test
    void testShowSelectFilesDialogWithFilterOnly() {
        //given
        SimpleFileFilter mockedFilter = Mockito.mock(SimpleFileFilter.class);

        DrawApplication mockedDrawApplication = Mockito.mock(DrawApplication.class);
        when(mockedDrawApplication.getFrame()).thenReturn(Mockito.mock(JFrame.class));

        try (MockedStatic<DrawPlugin> mockedDrawPluginStatic =
            Mockito.mockStatic(DrawPlugin.class)) {
            mockedDrawPluginStatic.when(DrawPlugin::getGui).thenReturn(mockedDrawApplication);

            //when
            DialogApi.showSelectFilesDialog(mockedFilter);

            //then
            verify(_mockedService).showSelectFilesDialog(mockedFilter);
        }
    }

    @Test
    void testShowSelectFilesDialogWithFileAndFilter() {
        //given
        File mockedFile = Mockito.mock(File.class);
        SimpleFileFilter mockedFilter = Mockito.mock(SimpleFileFilter.class);

        DrawApplication mockedDrawApplication = Mockito.mock(DrawApplication.class);
        when(mockedDrawApplication.getFrame()).thenReturn(Mockito.mock(JFrame.class));

        try (MockedStatic<DrawPlugin> mockedDrawPluginStatic =
            Mockito.mockStatic(DrawPlugin.class)) {
            mockedDrawPluginStatic.when(DrawPlugin::getGui).thenReturn(mockedDrawApplication);

            //when
            DialogApi.showSelectFilesDialog(mockedFile, mockedFilter);

            //then
            verify(_mockedService).showSelectFilesDialog(mockedFile, mockedFilter);
        }
    }

    @Test
    void testShowSelectFilesDialogWithFileFilterAndMultiSelect() {
        //given
        File mockedFile = Mockito.mock(File.class);
        SimpleFileFilter mockedFilter = Mockito.mock(SimpleFileFilter.class);

        DrawApplication mockedDrawApplication = Mockito.mock(DrawApplication.class);
        when(mockedDrawApplication.getFrame()).thenReturn(Mockito.mock(JFrame.class));

        try (MockedStatic<DrawPlugin> mockedDrawPluginStatic =
            Mockito.mockStatic(DrawPlugin.class)) {
            mockedDrawPluginStatic.when(DrawPlugin::getGui).thenReturn(mockedDrawApplication);

            //when
            DialogApi.showSelectFilesDialog(mockedFile, mockedFilter, true);

            //then
            verify(_mockedService).showSelectFilesDialog(mockedFile, mockedFilter, true);
        }
    }
}
