package de.thpeetz.kontor.media.views;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.contextmenu.ContextMenu;
import com.vaadin.flow.component.contextmenu.MenuItem;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.annotation.SpringComponent;
import de.thpeetz.kontor.common.views.MainLayout;
import de.thpeetz.kontor.common.views.ColumnToggleContextMenu;
import de.thpeetz.kontor.common.views.StatusIcon;
import de.thpeetz.kontor.media.MediaConstants;
import de.thpeetz.kontor.media.data.MediaVideo;
import de.thpeetz.kontor.media.services.MediaVideoService;
import jakarta.annotation.security.PermitAll;
import lombok.Getter;
import org.springframework.context.annotation.Scope;

@SpringComponent
@Scope("prototype")
@PermitAll
@Route(value = MediaConstants.MEDIAVIDEO_ROUTE, layout = MainLayout.class)
@PageTitle("MediaVideo | Media | Kontor")
public class MediaVideoView extends VerticalLayout {

    @Getter
    Grid<MediaVideo> grid = new Grid<>(MediaVideo.class, false);
    Grid.Column<MediaVideo> idColumn = grid.addColumn(MediaVideo::getId).setHeader("ID").setResizable(true);
    Grid.Column<MediaVideo> urlColumn = grid.addColumn(MediaVideo::getUrl).setHeader("URL").setResizable(true).setSortable(true);
    Grid.Column<MediaVideo> titleColumn = grid.addColumn(MediaVideo::getTitle).setHeader("Titel").setResizable(true).setSortable(true);
    Grid.Column<MediaVideo> fileNameColumn = grid.addColumn(MediaVideo::getFileName).setHeader("Dateiname").setResizable(true).setSortable(true);
    Grid.Column<MediaVideo> cloudLinkColumn = grid.addColumn(MediaVideo::getCloudLink).setHeader("Cloud Link").setResizable(true).setSortable(true);
    Grid.Column<MediaVideo> reviewColumn = grid.addComponentColumn(mediaVideo -> StatusIcon.create(mediaVideo.isReview()))
            .setHeader("Überprüfung")
            .setWidth("6rem");
    Grid.Column<MediaVideo> shouldDownloadColumn = grid.addComponentColumn(mediaVideo -> StatusIcon.create(mediaVideo.isShouldDownload()))
            .setHeader("Download?")
            .setWidth("6rem");
    TextField searchField = new TextField();
    @Getter
    MediaVideoForm form;
    MediaVideoService service;

    public MediaVideoView(MediaVideoService service) {
        this.service = service;
        addClassName("mediavideo-view");
        setSizeFull();
        configureGrid();
        configureForm();

        add(getToolbar(), getContent());
        updateList();
    }

    private void configureGrid() {
        grid.addClassName("mediavideo-grid");
        grid.setSizeFull();
        grid.getColumns().forEach(col -> col.setAutoWidth(true));
        idColumn.setVisible(false);
        grid.asSingleSelect().addValueChangeListener(event -> editMediaVideo(event.getValue()));
    }

    private void configureForm() {
        form = new MediaVideoForm();
        form.setWidth("75em");
        form.setVisible(false);
        form.addSaveListener(this::saveMediaVideo);
        form.addDeleteListener(this::deleteMediaVideo);
        form.addCloseListener(e -> closeEditor());
    }

    private void saveMediaVideo(MediaVideoForm.SaveEvent event) {
        service.saveMediaVideo(event.getMediaVideo());
        updateList();
        closeEditor();
    }

    private void deleteMediaVideo(MediaVideoForm.DeleteEvent event) {
        service.deleteMediaVideo(event.getMediaVideo());
        updateList();
        closeEditor();
    }

    private Component getContent() {
        HorizontalLayout content = new HorizontalLayout(grid, form);
        content.setFlexGrow(2, grid);
        content.setFlexGrow(1, form);
        content.addClassName("content");
        content.setSizeFull();
        return content;
    }

    private HorizontalLayout getToolbar() {
        searchField.setPlaceholder("Search");
        searchField.setClearButtonVisible(true);
        searchField.setPrefixComponent(new Icon(VaadinIcon.SEARCH));
        searchField.setValueChangeMode(ValueChangeMode.EAGER);
        searchField.addValueChangeListener(e -> updateList());

        Button addMediaVideoButton = new Button("Add MediaVideo");
        addMediaVideoButton.addClickListener(click -> addMediaVideo());

        Button menuButton = new Button("Show/Hide Columns");
        menuButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
        ColumnToggleContextMenu<MediaVideo> columnToggleContextMenu = new ColumnToggleContextMenu<>(menuButton);
        columnToggleContextMenu.addColumnToggleItem(idColumn);
        columnToggleContextMenu.addColumnToggleItem(urlColumn);
        columnToggleContextMenu.addColumnToggleItem(titleColumn);
        columnToggleContextMenu.addColumnToggleItem(fileNameColumn);
        columnToggleContextMenu.addColumnToggleItem(cloudLinkColumn);
        columnToggleContextMenu.addColumnToggleItem(reviewColumn);
        columnToggleContextMenu.addColumnToggleItem(shouldDownloadColumn);
        HorizontalLayout toolbar = new HorizontalLayout(searchField, addMediaVideoButton, menuButton);
        toolbar.addClassName("toolbar");
        return toolbar;
    }

    public void editMediaVideo(MediaVideo mediaVideo) {
        if (mediaVideo == null) {
            closeEditor();
        } else {
            form.setMediaVideo(mediaVideo);
            form.setVisible(true);
            addClassName("editing");
        }
    }

    private void closeEditor() {
        form.setMediaVideo(null);
        form.setVisible(false);
        removeClassName("editing");
    }

    private void addMediaVideo() {
        grid.asSingleSelect().clear();
        editMediaVideo(new MediaVideo());
    }

    public void updateList() {
        grid.setItems(service.findAllMediaVideos(searchField.getValue()));
    }
}
