package ru.dragonestia.kubik.discovery.vaadin.route;

import com.vaadin.flow.component.Unit;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.provider.DataProvider;
import com.vaadin.flow.data.provider.ListDataProvider;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import ru.dragonestia.kubik.discovery.model.Server;
import ru.dragonestia.kubik.discovery.service.ServerService;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@PageTitle("Kubik")
@Route("")
public class HomeRoute extends VerticalLayout {

    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    private final ServerService serverService;
    private final List<Server> providedServers;
    private final DataProvider<Server, ?> serverProvider;

    public HomeRoute(ServerService serverService) {
        this.serverService = serverService;
        providedServers = new ArrayList<>();
        serverProvider = new ListDataProvider<>(providedServers);

        add(new H1("Active servers"));
        add(createGrid());

        update();

        addAttachListener(event -> {
            var future = scheduler.scheduleWithFixedDelay(
                    () -> {
                        var ui = event.getUI();
                        ui.access(() -> {
                            update();
                            ui.push();
                        });
                    },
                    1,
                    1,
                    TimeUnit.SECONDS
            );

            addDetachListener(_ -> future.cancel(false));
        });
    }

    private Grid<Server> createGrid() {
        var grid = new Grid<>(Server.class, false);

        grid.addColumn(Server::getId).setHeader("Id");
        grid.addColumn(Server::getGroupId).setHeader("Group id");
        grid.addColumn(Server::getAddress).setHeader("Address");
        grid.addColumn(Server::getPort).setHeader("Port");
        grid.addColumn(Server::isCanPicked).setHeader("Can picked");
        grid.addColumn(server -> {
            var now = Instant.now();
            var delta = now.getEpochSecond() - server.getLastActivity().getEpochSecond();
            return "%ss ago".formatted(delta);
        }).setHeader("Last activity");

        grid.setHeight(80, Unit.VH);
        grid.setDataProvider(serverProvider);
        return grid;
    }

    private void update() {
        providedServers.clear();
        providedServers.addAll(serverService.getAllServers());
        serverProvider.refreshAll();
    }
}
