package de.assecutor.votianlt.pages.view;

import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
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.Menu;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.theme.lumo.LumoUtility;
import de.assecutor.votianlt.model.JobStatus;
import de.assecutor.votianlt.repository.*;
import jakarta.annotation.security.RolesAllowed;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.CompletableFuture;

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

    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 PendingMqttMessageRepository pendingMqttMessageRepository;

    private final Div statisticsContainer;
    private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");

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

        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.pendingMqttMessageRepository = pendingMqttMessageRepository;

        setSizeFull();
        addClassNames(LumoUtility.BoxSizing.BORDER, LumoUtility.Display.FLEX,
                     LumoUtility.FlexDirection.COLUMN, LumoUtility.Padding.MEDIUM);

        // Header
        H1 title = new H1("Administrator Dashboard");
        title.addClassNames(LumoUtility.Margin.Bottom.MEDIUM, LumoUtility.Margin.Top.NONE);

        HorizontalLayout header = new HorizontalLayout(title);
        header.setAlignItems(FlexComponent.Alignment.CENTER);
        header.setWidthFull();

        // Statistics container
        statisticsContainer = new Div();
        statisticsContainer.setSizeFull();

        // Content container
        VerticalLayout content = new VerticalLayout(header, statisticsContainer);
        content.setSizeFull();
        content.setPadding(false);
        content.setSpacing(true);

        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("Lade Statistiken..."));

        // 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("Fehler beim Laden der Statistiken: " + e.getMessage()));
                }
            }));
        });
    }

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

        // Create main layout
        VerticalLayout mainLayout = new VerticalLayout();
        mainLayout.setPadding(false);
        mainLayout.setSpacing(true);

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

        // 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.addClassName(LumoUtility.Background.CONTRAST_5);
        section.getStyle().set("border-radius", "8px").set("padding", "1rem");

        H3 title = new H3("System-Übersicht");
        title.addClassName(LumoUtility.Margin.Bottom.MEDIUM);

        HorizontalLayout cards = new HorizontalLayout();
        cards.setWidthFull();
        cards.setSpacing(true);

        // Total jobs card
        long totalJobs = jobRepository.count();
        cards.add(createStatCard("Gesamt Jobs", String.valueOf(totalJobs), VaadinIcon.PACKAGE, "blue"));

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

        // Total app users card
        long totalAppUsers = appUserRepository.count();
        cards.add(createStatCard("App-Benutzer", String.valueOf(totalAppUsers), VaadinIcon.MOBILE, "purple"));

        // Current time
        String currentTime = LocalDateTime.now().format(dateTimeFormatter);
        cards.add(createStatCard("Letzte Aktualisierung", currentTime, VaadinIcon.CLOCK, "gray"));

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

    private VerticalLayout createJobStatisticsSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassName(LumoUtility.Background.CONTRAST_5);
        section.getStyle().set("border-radius", "8px").set("padding", "1rem");

        H3 title = new H3("Job-Statistiken");
        title.addClassName(LumoUtility.Margin.Bottom.MEDIUM);

        HorizontalLayout cards = new HorizontalLayout();
        cards.setWidthFull();
        cards.setSpacing(true);

        // 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("Offene Jobs", String.valueOf(openJobs), VaadinIcon.HOURGLASS_START, "orange"));
            cards.add(createStatCard("In Bearbeitung", String.valueOf(inProgressJobs), VaadinIcon.PLAY, "blue"));
            cards.add(createStatCard("Abgeschlossen", String.valueOf(completedJobs), VaadinIcon.CHECK_CIRCLE, "green"));

            // Total cargo items
            long totalCargoItems = cargoItemRepository.count();
            cards.add(createStatCard("Frachtgüter", String.valueOf(totalCargoItems), VaadinIcon.CUBE, "purple"));

        } catch (Exception e) {
            log.warn("Could not load job statistics by status", e);
            cards.add(createStatCard("Status-Info", "Nicht verfügbar", VaadinIcon.WARNING, "red"));
        }

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

    private VerticalLayout createTaskStatisticsSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassName(LumoUtility.Background.CONTRAST_5);
        section.getStyle().set("border-radius", "8px").set("padding", "1rem");

        H3 title = new H3("Aufgaben-Statistiken");
        title.addClassName(LumoUtility.Margin.Bottom.MEDIUM);

        HorizontalLayout cards = new HorizontalLayout();
        cards.setWidthFull();
        cards.setSpacing(true);

        // Total tasks
        long totalTasks = taskRepository.count();
        cards.add(createStatCard("Gesamt Aufgaben", String.valueOf(totalTasks), VaadinIcon.TASKS, "blue"));

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

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

        // Completion rate
        double completionRate = totalTasks > 0 ? (completedTasks * 100.0 / totalTasks) : 0;
        cards.add(createStatCard("Erfolgsquote", 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.addClassName(LumoUtility.Background.CONTRAST_5);
        section.getStyle().set("border-radius", "8px").set("padding", "1rem");

        H3 title = new H3("Benutzer-Aktivität");
        title.addClassName(LumoUtility.Margin.Bottom.MEDIUM);

        HorizontalLayout cards = new HorizontalLayout();
        cards.setWidthFull();
        cards.setSpacing(true);

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

        long totalBarcodes = barcodeRepository.count();
        cards.add(createStatCard("Barcodes", String.valueOf(totalBarcodes), VaadinIcon.BARCODE, "green"));

        long totalSignatures = signatureRepository.count();
        cards.add(createStatCard("Unterschriften", String.valueOf(totalSignatures), VaadinIcon.EDIT, "purple"));

        long totalComments = commentRepository.count();
        cards.add(createStatCard("Kommentare", String.valueOf(totalComments), VaadinIcon.COMMENT, "orange"));

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

    private VerticalLayout createSystemHealthSection() {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(false);
        section.addClassName(LumoUtility.Background.CONTRAST_5);
        section.getStyle().set("border-radius", "8px").set("padding", "1rem");

        H3 title = new H3("System-Status");
        title.addClassName(LumoUtility.Margin.Bottom.MEDIUM);

        HorizontalLayout cards = new HorizontalLayout();
        cards.setWidthFull();
        cards.setSpacing(true);

        // Database connection status
        try {
            userRepository.count(); // Test database connection
            cards.add(createStatCard("Datenbank", "Verbunden", VaadinIcon.DATABASE, "green"));
        } catch (Exception e) {
            cards.add(createStatCard("Datenbank", "Fehler", VaadinIcon.DATABASE, "red"));
        }

        // Pending MQTT messages
        long pendingMqttMessages = pendingMqttMessageRepository.count();
        String mqttStatus = pendingMqttMessages == 0 ? "OK" : "Warteschlange: " + pendingMqttMessages;
        String mqttColor = pendingMqttMessages == 0 ? "green" : "orange";
        cards.add(createStatCard("MQTT", mqttStatus, VaadinIcon.CONNECT, mqttColor));

        // System uptime (placeholder)
        cards.add(createStatCard("Anwendung", "Läuft", 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("Speicher", 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.addClassName(LumoUtility.Background.BASE);
        card.getStyle()
                .set("border-radius", "8px")
                .set("padding", "1rem")
                .set("box-shadow", "0 2px 4px rgba(0,0,0,0.1)")
                .set("min-width", "200px")
                .set("border-left", "4px solid var(--lumo-" + color + "-color, #007bff)");

        HorizontalLayout header = new HorizontalLayout();
        header.setAlignItems(FlexComponent.Alignment.CENTER);
        header.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);

        Icon cardIcon = icon.create();
        cardIcon.getStyle().set("color", "var(--lumo-" + color + "-color, #007bff)");

        Span titleSpan = new Span(title);
        titleSpan.addClassName(LumoUtility.FontSize.SMALL);
        titleSpan.getStyle().set("color", "var(--lumo-secondary-text-color)");

        header.add(titleSpan, cardIcon);

        Span valueSpan = new Span(value);
        valueSpan.addClassName(LumoUtility.FontSize.XLARGE);
        valueSpan.addClassName(LumoUtility.FontWeight.BOLD);

        VerticalLayout content = new VerticalLayout(header, valueSpan);
        content.setPadding(false);
        content.setSpacing(false);

        card.add(content);
        return card;
    }
}