package ru.vyatsu.qr_access_admin.common;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.ComponentUtil;
import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.tabs.Tab;
import com.vaadin.flow.component.tabs.Tabs;
import com.vaadin.flow.component.tabs.TabsVariant;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.RouterLink;
import ru.vyatsu.qr_access_admin.client.view.ClientView;
import ru.vyatsu.qr_access_admin.common.view.MainView;
import ru.vyatsu.qr_access_admin.door.view.DoorView;
import ru.vyatsu.qr_access_admin.partner.view.PartnerView;
import ru.vyatsu.qr_access_admin.unit.view.UnitView;

import java.util.Optional;

public class MainLayout extends AppLayout {
    private final Tabs menu;
    private H2 viewTitle;


    public MainLayout() {
        setPrimarySection(Section.DRAWER);
        addToNavbar(true, createHeaderContent());
        menu = createMenu();

        addToDrawer(createDrawerContent(menu));
    }

    @Override
    protected void afterNavigation() {
        super.afterNavigation();

        // Select the tab corresponding to currently shown view
        getTabForComponent(getContent()).ifPresent(menu::setSelectedTab);

        // Set the view title in the header
        viewTitle.setText(getCurrentPageTitle());
    }

    private Optional<Tab> getTabForComponent(Component component) {
        return menu.getChildren()
                .filter(tab -> ComponentUtil.getData(tab, Class.class)
                        .equals(component.getClass()))
                .findFirst().map(Tab.class::cast);
    }

    private String getCurrentPageTitle() {
        return getContent().getClass().getAnnotation(PageTitle.class).value();
    }

    private Component createHeaderContent() {
        HorizontalLayout layout = new HorizontalLayout();

        layout.setId("header");
        layout.getThemeList().set("dark", true);
        layout.setWidthFull();
        layout.setAlignItems(FlexComponent.Alignment.CENTER);

        HorizontalLayout innerLayout = new HorizontalLayout();
        innerLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
        innerLayout.setAlignItems(FlexComponent.Alignment.CENTER);
        innerLayout.setWidth("100%");
        layout.add(new DrawerToggle());

        viewTitle = new H2();
        innerLayout.add(viewTitle);

        RouterLink homeLink = new RouterLink(MainView.class);
        homeLink.add(VaadinIcon.USER.create());
        innerLayout.add(homeLink);
        layout.add(innerLayout);

        return layout;
    }

    private Component createDrawerContent(Tabs menu) {
        VerticalLayout layout = new VerticalLayout();

        // Configure styling for the drawer
        layout.setSizeFull();
        layout.setPadding(false);
        layout.setSpacing(false);
        layout.getThemeList().set("spacing-s", true);
        layout.setAlignItems(FlexComponent.Alignment.STRETCH);

        // Have a drawer header with an application logo
        HorizontalLayout logoLayout = new HorizontalLayout();
        logoLayout.setId("logo");
        logoLayout.setAlignItems(FlexComponent.Alignment.CENTER);
        logoLayout.add(VaadinIcon.QRCODE.create());
        logoLayout.add(new H1("QR-admin"));

        // Display the logo and the menu in the drawer
        layout.add(logoLayout, menu);
        return layout;
    }

    private Tabs createMenu() {
        final Tabs tabs = new Tabs();
        tabs.setOrientation(Tabs.Orientation.VERTICAL);
        tabs.addThemeVariants(TabsVariant.LUMO_MINIMAL);
        tabs.setId("tabs");
        tabs.add(createMenuItems());
        return tabs;
    }

    private Tab[] createMenuItems() {
        return new Tab[]{
                createTab("Домашняя страница", MainView.class),
                createTab("Устройства", UnitView.class),
                createTab("Двери", DoorView.class),
                createTab("Партнеры", PartnerView.class),
                createTab("Клиенты", ClientView.class)
        };
    }

    private static Tab createTab(String text, Class<? extends Component> navigationTarget) {
        final Tab tab = new Tab();
        tab.add(new RouterLink(text, navigationTarget));
        ComponentUtil.setData(tab, Class.class, navigationTarget);
        return tab;
    }
}
