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.grid.Grid;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
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.*;
import de.thpeetz.kontor.media.data.MediaFile;
import de.thpeetz.kontor.media.services.MediaFileService;
import jakarta.annotation.security.RolesAllowed;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;

@Slf4j
@SpringComponent
@Scope("prototype")
@RolesAllowed("MEDIA")
@Route(value = "media/mediafile", layout = MainLayout.class)
@PageTitle("MediaFile | Media | Kontor")
public class MediaFileView extends VerticalLayout {

    @Getter
    Grid<MediaFile> grid = new Grid<>(MediaFile.class, false);
    Grid.Column<MediaFile> idColumn = grid.addColumn(MediaFile::getId)
            .setHeader("ID").setResizable(true).setSortable(true);
    Grid.Column<MediaFile> createdColumn = grid.addColumn(MediaFile::getCreatedDate)
            .setHeader("Erstellt").setResizable(true).setSortable(true);
    Grid.Column<MediaFile> modifiedColumn = grid.addColumn(MediaFile::getLastModifiedDate)
            .setHeader("Geändert").setResizable(true).setSortable(true);
    Grid.Column<MediaFile> urlColumn = grid.addColumn(MediaFile::getUrl)
            .setHeader("URL").setResizable(true).setSortable(true);
    Grid.Column<MediaFile> titleColumn = grid.addColumn(MediaFile::getTitle)
            .setHeader("Titel").setResizable(true).setSortable(true);
    Grid.Column<MediaFile> fileNameColumn = grid.addColumn(MediaFile::getFileName)
            .setHeader("Dateiname").setResizable(true).setSortable(true);
    Grid.Column<MediaFile> cloudLinkColumn = grid.addColumn(MediaFile::getCloudLink)
            .setHeader("Cloud Link").setResizable(true).setSortable(true);
    Grid.Column<MediaFile> reviewColumn = grid.addComponentColumn(mediafile -> StatusIcon.create(mediafile.isReview())).
            setHeader("Überprüfung").setWidth("6rem").setSortable(true);
    Grid.Column<MediaFile> shouldDownloadColumn = grid.addComponentColumn(mediafile -> StatusIcon.create(mediafile.isShouldDownload())).
            setHeader("Download?").setWidth("6rem").setSortable(true);
    SearchFilterField searchFilterField = new SearchFilterField();
    @Getter
    MediaFileForm form;
    MediaFileService service;

    public MediaFileView(MediaFileService service) {
        this.service = service;
        addClassName("mediafile-view");
        setSizeFull();
        configureGrid();
        configureForm();

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

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

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

    private void saveMediaFile(MediaFileForm.SaveEvent event) {
        service.saveMediaFile(event.getMediaFile());
        updateList();
        closeEditor();
    }

    private void deleteMediaFile(MediaFileForm.DeleteEvent event) {
        service.deleteMediaFile(event.getMediaFile());
        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() {
        searchFilterField.addFilter("Überprüfung");
        searchFilterField.addFilter("Download");
        searchFilterField.addValueChangeListener(e -> updateList());

        Button addMediaFileButton = new Button("Add MediaFile");
        addMediaFileButton.addClickListener(click -> addMediaFile());

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

    public void editMediaFile(MediaFile mediaFile) {
        if (mediaFile == null) {
            closeEditor();
        } else {
            form.setMediaFile(mediaFile);
            if (mediaFile.getMediaActorFiles() == null) {
                log.info("no MediaActorFiles");
            } else {
                log.info("MediaActorFiles size: {}", mediaFile.getMediaActorFiles().size());
            }
            form.setMediaActorFiles(mediaFile.getMediaActorFiles());
            form.setVisible(true);
            addClassName("editing");
        }
    }

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

    private void addMediaFile() {
        grid.asSingleSelect().clear();
        editMediaFile(new MediaFile());
    }

    public void updateList() {
        log.info("searchFilterField: {}", searchFilterField.getValue());
        grid.setItems(service.findAllMediaFiles(searchFilterField.getValue()));
    }
}
