package de.assecutor.votianlt.pages.base.ui.view;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasElement;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.avatar.Avatar;
import com.vaadin.flow.component.avatar.AvatarVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.menubar.MenuBar;
import com.vaadin.flow.component.menubar.MenuBarVariant;
import com.vaadin.flow.component.orderedlayout.Scroller;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.sidenav.SideNav;
import com.vaadin.flow.component.sidenav.SideNavItem;
import com.vaadin.flow.router.Layout;
import com.vaadin.flow.server.auth.AnonymousAllowed;
import de.assecutor.votianlt.pages.base.ui.component.DialogStylingHelper;
import de.assecutor.votianlt.security.SecurityService;

import static com.vaadin.flow.theme.lumo.LumoUtility.*;

@AnonymousAllowed
@Layout("admin")
public final class AdminLayout extends AppLayout {

    private final SecurityService securityService;
    private Div headerRef;
    private Scroller navRef;
    private Component userMenuRef;
    private final Div viewContainer = new Div();

    public AdminLayout(SecurityService securityService) {
        this.securityService = securityService;
        addClassName("admin-shell");
        setPrimarySection(Section.DRAWER);
        getStyle().set("--vaadin-app-layout-drawer-width", "336px");

        // Always build the drawer; keep references and toggle visibility on attach and
        // after navigation
        headerRef = createHeader();
        navRef = new Scroller(createSideNav());
        navRef.addClassName("app-drawer-scroll");
        navRef.setScrollDirection(Scroller.ScrollDirection.VERTICAL);
        userMenuRef = createUserMenu();
        addToDrawer(headerRef, navRef, userMenuRef);

        // Same content wrapper as MainLayout so admin pages get the identical
        // page frame (margin, rounded corners, shell background)
        viewContainer.addClassName("view-container");
        getElement().appendChild(viewContainer.getElement());

        updateDrawerVisibility();

        // Re-check on attach (new UI/session) and on every navigation cycle
        addAttachListener(e -> updateDrawerVisibility());
    }

    @Override
    public void showRouterLayoutContent(HasElement content) {
        viewContainer.getElement().removeAllChildren();
        if (content != null) {
            viewContainer.getElement().appendChild(content.getElement());
        }
    }

    private void updateDrawerVisibility() {
        boolean loggedIn = securityService.isUserLoggedIn();
        if (headerRef != null)
            headerRef.setVisible(loggedIn);
        if (navRef != null)
            navRef.setVisible(loggedIn);
        if (userMenuRef != null)
            userMenuRef.setVisible(loggedIn);
        setDrawerOpened(loggedIn);
    }

    private Div createHeader() {
        var appLogo = VaadinIcon.SHIELD.create();
        appLogo.addClassNames(TextColor.PRIMARY, IconSize.LARGE);
        appLogo.addClassName("app-drawer-logo-icon");

        var appName = new Span("VotianLT Admin");
        appName.addClassNames(FontWeight.SEMIBOLD, FontSize.LARGE);
        appName.addClassName("app-drawer-title");

        var header = new Div(appLogo, appName);
        header.addClassNames(Display.FLEX, Padding.MEDIUM, Gap.MEDIUM, AlignItems.CENTER);
        header.addClassName("app-drawer-header");
        header.getStyle().set("cursor", "pointer");
        header.getElement().setProperty("title", "Zum Dashboard");
        header.addClickListener(event -> UI.getCurrent().navigate("admin-dashboard"));
        return header;
    }

    private Component createSideNav() {
        var nav = new SideNav();
        nav.addClassName("app-side-nav");

        // Only admin-specific menu items
        SideNavItem dashboard = new SideNavItem("Dashboard", "admin-dashboard", new Icon(VaadinIcon.DASHBOARD));
        SideNavItem invoiceGenerator = new SideNavItem("Rechnungsgenerator", "invoice-generator",
                new Icon(VaadinIcon.FILE_PROCESS));
        SideNavItem createInvoices = new SideNavItem("Rechnungen erstellen", "admin-create-invoices",
                new Icon(VaadinIcon.INVOICE));
        SideNavItem priceTable = new SideNavItem("Preis-Tabelle", "admin-price-table", new Icon(VaadinIcon.COG));
        // SideNavItem systemSettings = new SideNavItem("Systemeinstellungen",
        // "admin-settings", new Icon(VaadinIcon.COG));
        // SideNavItem userManagement = new SideNavItem("Benutzerverwaltung",
        // "admin-users", new Icon(VaadinIcon.USERS));
        // SideNavItem systemLogs = new SideNavItem("System-Logs", "admin-logs", new
        // Icon(VaadinIcon.FILE_TEXT));

        nav.addItem(dashboard);
        nav.addItem(invoiceGenerator);
        nav.addItem(createInvoices);
        nav.addItem(priceTable);
        // nav.addItem(systemSettings);
        // nav.addItem(userManagement);
        // nav.addItem(systemLogs);

        // Create a vertical layout to hold menu items
        VerticalLayout navContainer = new VerticalLayout();
        navContainer.setPadding(false);
        navContainer.setSpacing(false);
        navContainer.setWidthFull();
        navContainer.addClassName("app-nav-container");
        navContainer.add(nav);

        return navContainer;
    }

    private Component createUserMenu() {
        var userMenu = new MenuBar();
        userMenu.addThemeVariants(MenuBarVariant.LUMO_TERTIARY_INLINE);
        userMenu.addClassName("app-user-menu");

        // Dynamically updatable components
        var avatar = new Avatar();
        avatar.addThemeVariants(AvatarVariant.LUMO_XSMALL);
        avatar.addClassNames(Margin.Right.SMALL);
        avatar.setColorIndex(1); // Different color for admin
        avatar.addClassName("app-user-avatar");

        var userNameSpan = new Span();
        userNameSpan.addClassName("app-user-name");

        var userMenuItem = userMenu.addItem(avatar);
        userMenuItem.add(userNameSpan);

        // Profile display with navigation to the admin company profile
        userMenuItem.getSubMenu().addItem("Profil anzeigen", e -> UI.getCurrent().navigate("admin-profile"));
        userMenuItem.getSubMenu().addItem("Abmelden", e -> openLogoutConfirmDialog());

        // Update function for username and avatar
        Runnable updateUserInfo = () -> {
            String currentUser = securityService.getCurrentUsername();
            avatar.setName(currentUser + " (Admin)");
            userNameSpan.setText(currentUser);
        };

        // Update initially and on attach
        updateUserInfo.run();
        addAttachListener(e -> updateUserInfo.run());

        return userMenu;
    }

    private void openLogoutConfirmDialog() {
        var dialog = DialogStylingHelper.createConfirmationDialog(
                getTranslation("logout.confirm.title"),
                getTranslation("logout.confirm.message"),
                "460px",
                getTranslation("button.cancel"),
                getTranslation("nav.logout"),
                securityService::logout,
                com.vaadin.flow.component.button.ButtonVariant.LUMO_PRIMARY,
                com.vaadin.flow.component.button.ButtonVariant.LUMO_ERROR);
        dialog.open();
    }
}
