package de.assecutor.votianlt.pages.view;

import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Main;
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.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.HasDynamicTitle;
import com.vaadin.flow.router.Menu;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.theme.lumo.LumoUtility;
import de.assecutor.votianlt.model.Customer;
import de.assecutor.votianlt.model.JobStatus;
import de.assecutor.votianlt.model.User;
import de.assecutor.votianlt.pages.domain.CustomerRepository;
import de.assecutor.votianlt.repository.*;
import de.assecutor.votianlt.util.DateTimeFormatUtil;
import jakarta.annotation.security.RolesAllowed;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

@Route(value = "admin-dashboard", layout = de.assecutor.votianlt.pages.base.ui.view.AdminLayout.class)
@RolesAllowed("ADMIN")
@Menu(order = 1, icon = "lumo:edit")
@Slf4j
public class AdminDashboardView extends Main implements HasDynamicTitle {

    private final JobRepository jobRepository;
    private final TaskRepository taskRepository;
    private final UserRepository userRepository;
    private final AppUserRepository appUserRepository;
    private final CargoItemRepository cargoItemRepository;
    private final PhotoRepository photoRepository;
    private final BarcodeRepository barcodeRepository;
    private final SignatureRepository signatureRepository;
    private final CommentRepository commentRepository;
    private final CustomerRepository customerRepository;

    private final Div statisticsContainer;

    @Autowired
    public AdminDashboardView(JobRepository jobRepository, TaskRepository taskRepository, UserRepository userRepository,
            AppUserRepository appUserRepository, CargoItemRepository cargoItemRepository,
            PhotoRepository photoRepository, BarcodeRepository barcodeRepository,
            SignatureRepository signatureRepository, CommentRepository commentRepository,
            CustomerRepository customerRepository) {

        this.jobRepository = jobRepository;
        this.taskRepository = taskRepository;
        this.userRepository = userRepository;
        this.appUserRepository = appUserRepository;
        this.cargoItemRepository = cargoItemRepository;
        this.photoRepository = photoRepository;
        this.barcodeRepository = barcodeRepository;
        this.signatureRepository = signatureRepository;
        this.commentRepository = commentRepository;
        this.customerRepository = customerRepository;

        setSizeFull();
        addClassNames(LumoUtility.BoxSizing.BORDER, LumoUtility.Display.FLEX, LumoUtility.FlexDirection.COLUMN,
                LumoUtility.Padding.MEDIUM);
        addClassName("dashboard-view");

        // Header
        H1 title = new H1(getTranslation("admindashboard.title"));
        title.addClassNames(LumoUtility.Margin.Bottom.MEDIUM, LumoUtility.Margin.Top.NONE);
        title.addClassName("dashboard-title");

        HorizontalLayout header = new HorizontalLayout(title);
        header.setAlignItems(FlexComponent.Alignment.CENTER);
        header.setWidthFull();
        header.addClassNames("surface-panel", "dashboard-header");

        // Statistics container
        statisticsContainer = new Div();
        statisticsContainer.setSizeFull();
        statisticsContainer.addClassName("dashboard-content");

        // Content container
        VerticalLayout content = new VerticalLayout(header, statisticsContainer);
        content.setSizeFull();
        content.setPadding(false);
        content.setSpacing(true);
        content.addClassName("dashboard-sections");

        add(content);

        // Load initial statistics
        loadStatistics();
    }

    private void loadStatistics() {
        log.info("Loading dashboard statistics for admin user");

        // Show loading indicator
        statisticsContainer.removeAll();
        statisticsContainer.add(new Span(getTranslation("admindashboard.loading")));

        // Load statistics asynchronously
        CompletableFuture.runAsync(() -> {
            getUI().ifPresent(ui -> ui.access(() -> {
                try {
                    displayStatistics();
                } catch (Exception e) {
                    log.error("Error loading dashboard statistics", e);
                    statisticsContainer.removeAll();
                    statisticsContainer.add(new Span(getTranslation("admindashboard.error", e.getMessage())));
                }
            }));
        });
    }

    private void displayStatistics() {
        statisticsContainer.removeAll();

        // Create main layout
        VerticalLayout mainLayout = new VerticalLayout();
        mainLayout.setPadding(false);
        mainLayout.setSpacing(true);
        mainLayout.addClassName("dashboard-sections");

        // System overview section
        mainLayout.add(createSystemOverviewSection());

        // Customers overview section
        mainLayout.add(createCustomersSection());

        // Job statistics section
        mainLayout.add(createJobStatisticsSection());

        // Task statistics section
        mainLayout.add(createTaskStatisticsSection());

        // User statistics section
        mainLayout.add(createUserStatisticsSection());

        // System health section
        mainLayout.add(createSystemHealthSection());

        statisticsContainer.add(mainLayout);
    }

    private VerticalLayout createSystemOverviewSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassNames("surface-panel", "dashboard-section");

        H3 title = new H3(getTranslation("admindashboard.section.overview"));
        title.addClassNames(LumoUtility.Margin.Bottom.MEDIUM, "dashboard-section-title");

        Div cards = new Div();
        cards.addClassName("dashboard-grid");

        // Total jobs card
        long totalJobs = jobRepository.count();
        cards.add(createStatCard(getTranslation("admindashboard.stat.totaljobs"), String.valueOf(totalJobs),
                VaadinIcon.PACKAGE, "blue"));

        // Total users card
        long totalUsers = userRepository.count();
        cards.add(createStatCard(getTranslation("admindashboard.stat.users"), String.valueOf(totalUsers),
                VaadinIcon.USERS, "green"));

        // Total app users card
        long totalAppUsers = appUserRepository.count();
        cards.add(createStatCard(getTranslation("admindashboard.stat.appusers"), String.valueOf(totalAppUsers),
                VaadinIcon.MOBILE, "purple"));

        // Current time
        String currentTime = DateTimeFormatUtil.formatDateTime(LocalDateTime.now());
        cards.add(createStatCard(getTranslation("admindashboard.stat.lastupdated"), currentTime, VaadinIcon.CLOCK,
                "gray"));

        section.add(title, cards);
        return section;
    }

    private VerticalLayout createCustomersSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassNames("surface-panel", "dashboard-section");

        List<Customer> customers = customerRepository.findAll().stream().filter(customer -> !customer.isInternal())
                .toList();

        H3 title = new H3(getTranslation("admindashboard.section.customers", customers.size()));
        title.addClassNames(LumoUtility.Margin.Bottom.MEDIUM, "dashboard-section-title");

        if (customers.isEmpty()) {
            Span emptyHint = new Span(getTranslation("admindashboard.customers.empty"));
            section.add(title, emptyHint);
            return section;
        }

        Map<ObjectId, User> usersById = userRepository.findAll().stream().filter(user -> user.getId() != null)
                .collect(Collectors.toMap(User::getId, Function.identity(), (first, second) -> first));

        Grid<Customer> grid = new Grid<>();
        grid.setItems(customers);
        grid.addColumn(Customer::getUsrId).setHeader(getTranslation("admindashboard.customers.column.number"))
                .setAutoWidth(true).setFlexGrow(0).setSortable(true);
        grid.addColumn(Customer::getCompanyName).setHeader(getTranslation("customers.column.company"))
                .setAutoWidth(true).setSortable(true);
        grid.addColumn(customer -> ((customer.getFirstname() != null ? customer.getFirstname() : "") + " "
                + (customer.getLastName() != null ? customer.getLastName() : "")).trim())
                .setHeader(getTranslation("customers.column.name")).setAutoWidth(true).setSortable(true);
        grid.addColumn(Customer::getMail).setHeader(getTranslation("customers.column.email")).setAutoWidth(true);
        grid.addColumn(Customer::getTelephone).setHeader(getTranslation("customers.column.phone")).setAutoWidth(true);
        grid.addColumn(customer -> ((customer.getZip() != null ? customer.getZip() : "") + " "
                + (customer.getCity() != null ? customer.getCity() : "")).trim())
                .setHeader(getTranslation("customers.column.city")).setAutoWidth(true).setSortable(true);
        grid.addColumn(customer -> formatOwner(usersById.get(customer.getOwner())))
                .setHeader(getTranslation("admindashboard.customers.column.owner")).setAutoWidth(true)
                .setSortable(true);
        grid.addClassName("data-grid");
        grid.setWidthFull();
        grid.setHeight("400px");

        section.add(title, grid);
        return section;
    }

    private String formatOwner(User owner) {
        if (owner == null) {
            return "";
        }
        if (owner.getCompany() != null && !owner.getCompany().isBlank()) {
            return owner.getCompany();
        }
        return ((owner.getFirstname() != null ? owner.getFirstname() : "") + " "
                + (owner.getName() != null ? owner.getName() : "")).trim();
    }

    private VerticalLayout createJobStatisticsSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassNames("surface-panel", "dashboard-section");

        H3 title = new H3(getTranslation("admindashboard.section.jobs"));
        title.addClassNames(LumoUtility.Margin.Bottom.MEDIUM, "dashboard-section-title");

        Div cards = new Div();
        cards.addClassName("dashboard-grid");

        // Jobs by status
        try {
            long openJobs = jobRepository.countByStatus(JobStatus.CREATED);
            long inProgressJobs = jobRepository.countByStatus(JobStatus.IN_PROGRESS);
            long completedJobs = jobRepository.countByStatus(JobStatus.COMPLETED);

            cards.add(createStatCard(getTranslation("admindashboard.stat.openjobs"), String.valueOf(openJobs),
                    VaadinIcon.HOURGLASS_START, "orange"));
            cards.add(createStatCard(getTranslation("admindashboard.stat.inprogress"), String.valueOf(inProgressJobs),
                    VaadinIcon.PLAY, "blue"));
            cards.add(createStatCard(getTranslation("admindashboard.stat.completed"), String.valueOf(completedJobs),
                    VaadinIcon.CHECK_CIRCLE, "green"));

            // Total cargo items
            long totalCargoItems = cargoItemRepository.count();
            cards.add(createStatCard(getTranslation("admindashboard.stat.cargo"), String.valueOf(totalCargoItems),
                    VaadinIcon.CUBE, "purple"));

        } catch (Exception e) {
            log.warn("Could not load job statistics by status", e);
            cards.add(createStatCard(getTranslation("admindashboard.stat.status.info"),
                    getTranslation("admindashboard.stat.status.unavailable"), VaadinIcon.WARNING, "red"));
        }

        section.add(title, cards);
        return section;
    }

    private VerticalLayout createTaskStatisticsSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassNames("surface-panel", "dashboard-section");

        H3 title = new H3(getTranslation("admindashboard.section.tasks"));
        title.addClassNames(LumoUtility.Margin.Bottom.MEDIUM, "dashboard-section-title");

        Div cards = new Div();
        cards.addClassName("dashboard-grid");

        // Total tasks
        long totalTasks = taskRepository.count();
        cards.add(createStatCard(getTranslation("admindashboard.stat.totaltasks"), String.valueOf(totalTasks),
                VaadinIcon.TASKS, "blue"));

        // Completed tasks
        long completedTasks = taskRepository.countByCompleted(true);
        cards.add(createStatCard(getTranslation("admindashboard.stat.completedtasks"), String.valueOf(completedTasks),
                VaadinIcon.CHECK, "green"));

        // Pending tasks
        long pendingTasks = totalTasks - completedTasks;
        cards.add(createStatCard(getTranslation("admindashboard.stat.pendingtasks"), String.valueOf(pendingTasks),
                VaadinIcon.CLOCK, "orange"));

        // Completion rate
        double completionRate = totalTasks > 0 ? (completedTasks * 100.0 / totalTasks) : 0;
        cards.add(createStatCard(getTranslation("admindashboard.stat.successrate"),
                String.format("%.1f%%", completionRate), VaadinIcon.TRENDING_UP, "purple"));

        section.add(title, cards);
        return section;
    }

    private VerticalLayout createUserStatisticsSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassNames("surface-panel", "dashboard-section");

        H3 title = new H3(getTranslation("admindashboard.section.users"));
        title.addClassNames(LumoUtility.Margin.Bottom.MEDIUM, "dashboard-section-title");

        Div cards = new Div();
        cards.addClassName("dashboard-grid");

        // Content statistics
        long totalPhotos = photoRepository.count();
        cards.add(createStatCard(getTranslation("admindashboard.stat.photos"), String.valueOf(totalPhotos),
                VaadinIcon.CAMERA, "blue"));

        long totalBarcodes = barcodeRepository.count();
        cards.add(createStatCard(getTranslation("admindashboard.stat.barcodes"), String.valueOf(totalBarcodes),
                VaadinIcon.BARCODE, "green"));

        long totalSignatures = signatureRepository.count();
        cards.add(createStatCard(getTranslation("admindashboard.stat.signatures"), String.valueOf(totalSignatures),
                VaadinIcon.EDIT, "purple"));

        long totalComments = commentRepository.count();
        cards.add(createStatCard(getTranslation("admindashboard.stat.comments"), String.valueOf(totalComments),
                VaadinIcon.COMMENT, "orange"));

        section.add(title, cards);
        return section;
    }

    private VerticalLayout createSystemHealthSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassNames("surface-panel", "dashboard-section");

        H3 title = new H3(getTranslation("admindashboard.section.health"));
        title.addClassNames(LumoUtility.Margin.Bottom.MEDIUM, "dashboard-section-title");

        Div cards = new Div();
        cards.addClassName("dashboard-grid");

        // Database connection status
        try {
            userRepository.count(); // Test database connection
            cards.add(createStatCard(getTranslation("admindashboard.stat.database"),
                    getTranslation("admindashboard.stat.database.connected"), VaadinIcon.DATABASE, "green"));
        } catch (Exception e) {
            cards.add(createStatCard(getTranslation("admindashboard.stat.database"),
                    getTranslation("admindashboard.stat.database.error"), VaadinIcon.DATABASE, "red"));
        }

        // Messaging status
        cards.add(createStatCard(getTranslation("admindashboard.stat.websocket"),
                getTranslation("admindashboard.stat.websocket.active"), VaadinIcon.CONNECT, "green"));

        // System uptime (placeholder)
        cards.add(createStatCard(getTranslation("admindashboard.stat.app"),
                getTranslation("admindashboard.stat.app.running"), VaadinIcon.HEART, "green"));

        // Memory usage (placeholder)
        Runtime runtime = Runtime.getRuntime();
        long maxMemory = runtime.maxMemory() / 1024 / 1024; // MB
        long totalMemory = runtime.totalMemory() / 1024 / 1024; // MB
        long usedMemory = totalMemory - (runtime.freeMemory() / 1024 / 1024); // MB
        String memoryInfo = usedMemory + "/" + maxMemory + " MB";
        cards.add(createStatCard(getTranslation("admindashboard.stat.memory"), memoryInfo, VaadinIcon.SERVER, "blue"));

        section.add(title, cards);
        return section;
    }

    private Div createStatCard(String title, String value, VaadinIcon icon, String color) {
        Div card = new Div();
        card.addClassNames("dashboard-stat-card", "accent-" + color);

        HorizontalLayout header = new HorizontalLayout();
        header.setAlignItems(FlexComponent.Alignment.CENTER);
        header.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
        header.addClassName("dashboard-stat-card-header");

        Icon cardIcon = icon.create();
        cardIcon.addClassNames("dashboard-stat-icon", "accent-" + color);

        Span titleSpan = new Span(title);
        titleSpan.addClassName(LumoUtility.FontSize.SMALL);
        titleSpan.addClassName("dashboard-stat-title");

        header.add(titleSpan, cardIcon);

        Span valueSpan = new Span(value);
        valueSpan.addClassName(LumoUtility.FontSize.XLARGE);
        valueSpan.addClassName(LumoUtility.FontWeight.BOLD);
        valueSpan.addClassName("dashboard-stat-value");

        VerticalLayout content = new VerticalLayout(header, valueSpan);
        content.setPadding(false);
        content.setSpacing(false);
        content.addClassName("dashboard-stat-content");

        card.add(content);
        return card;
    }

    @Override
    public String getPageTitle() {
        return getTranslation("page.title.admin.dashboard");
    }
}
