package de.assecutor.votianlt.pages.view;

import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H2;
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.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.BeforeEvent;
import com.vaadin.flow.router.HasUrlParameter;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import de.assecutor.votianlt.model.AppUser;
import de.assecutor.votianlt.model.Message;
import de.assecutor.votianlt.model.MessageContentType;
import de.assecutor.votianlt.model.MessageOrigin;
import de.assecutor.votianlt.model.MessageType;
import de.assecutor.votianlt.pages.service.AppUserService;
import de.assecutor.votianlt.service.MessageService;
import jakarta.annotation.security.RolesAllowed;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Route(value = "user-messages", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@PageTitle("Nachrichten")
@RolesAllowed("USER")
@Slf4j
public class UserMessagesView extends Main implements HasUrlParameter<String> {

    private final AppUserService appUserService;
    private final MessageService messageService;

    private String participantKey;
    private VerticalLayout contentLayout;
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");

    public UserMessagesView(AppUserService appUserService, MessageService messageService) {
        this.appUserService = appUserService;
        this.messageService = messageService;
        
        // Create main layout
        contentLayout = new VerticalLayout();
        contentLayout.setPadding(true);
        contentLayout.setSpacing(true);
        contentLayout.setWidthFull();
        
        add(contentLayout);
    }

    @Override
    public void setParameter(BeforeEvent event, String parameter) {
        this.participantKey = parameter;
        loadClientMessages();
    }

    private void loadClientMessages() {
        contentLayout.removeAll();

        // Get client info
        AppUser client = null;
        try {
            ObjectId objectId = new ObjectId(participantKey);
            client = appUserService.findById(objectId);
        } catch (Exception e) {
            log.debug("Could not resolve AppUser for participant key {}: {}", participantKey, e.getMessage());
        }

        String clientName = client != null ? 
            client.getVorname() + " " + client.getNachname() : Optional.ofNullable(participantKey).orElse("Unbekannter Teilnehmer");

        HorizontalLayout headerLayout = createHeaderLayout(clientName);
        contentLayout.add(headerLayout);

        List<Message> conversation = messageService.getMessagesForAppUserAscending(participantKey);
        Map<MessageType, List<Message>> messagesByType = conversation.stream()
                .collect(Collectors.groupingBy(message -> Optional.ofNullable(message.getMessageType()).orElse(MessageType.GENERAL)));

        VerticalLayout generalSection = createGeneralMessagesSection(messagesByType.get(MessageType.GENERAL));

        VerticalLayout jobSection = createJobMessagesSection(messagesByType.get(MessageType.JOB_RELATED));

        contentLayout.add(generalSection, jobSection);
    }

    private HorizontalLayout createHeaderLayout(String clientName) {
        Button backButton = new Button("Zurück", VaadinIcon.ARROW_LEFT.create());
        backButton.addClickListener(e -> UI.getCurrent().navigate("messages"));
        
        H2 title = new H2("Nachrichten mit " + clientName);
        
        HorizontalLayout layout = new HorizontalLayout(backButton, title);
        layout.setWidthFull();
        layout.setAlignItems(com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment.CENTER);
        layout.setSpacing(true);
        
        return layout;
    }

    private VerticalLayout createGeneralMessagesSection(List<Message> generalMessages) {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(true);
        section.setSpacing(true);
        section.getStyle().set("border", "1px solid #e0e0e0");
        section.getStyle().set("border-radius", "8px");
        section.setWidthFull();
        section.getStyle().set("margin-right", "20px");

        H3 title = new H3("Allgemeine Nachrichten");
        section.add(title);

        List<Message> sortedMessages = new ArrayList<>();
        if (generalMessages != null) {
            sortedMessages.addAll(generalMessages);
        }

        sortedMessages.sort(Comparator.comparing(Message::getCreatedAt, Comparator.nullsLast(LocalDateTime::compareTo)));

        Message latest = sortedMessages.isEmpty() ? null : sortedMessages.get(sortedMessages.size() - 1);
        int unreadCount = (int) sortedMessages.stream()
                .filter(message -> message.getOrigin() == MessageOrigin.CLIENT && !message.isRead())
                .count();
        int messageCount = sortedMessages.size();
        LocalDateTime lastMessageTime = latest != null ? latest.getCreatedAt() : null;
        String preview = resolvePreview(latest);

        section.add(createMessageCard(
                "Allgemeine Unterhaltung",
                preview,
                lastMessageTime,
                messageCount,
                unreadCount,
                "general"
        ));

        return section;
    }

    private VerticalLayout createJobMessagesSection(List<Message> jobMessages) {
        VerticalLayout section = new VerticalLayout();
        section.setPadding(true);
        section.setSpacing(true);
        section.getStyle().set("border", "1px solid #e0e0e0");
        section.getStyle().set("border-radius", "8px");
        section.setWidthFull();
        section.getStyle().set("margin-right", "20px");

        H3 title = new H3("Nachrichten zu Aufträgen");
        section.add(title);

        if (jobMessages == null || jobMessages.isEmpty()) {
            section.add(new Span("Keine auftragsbezogenen Nachrichten vorhanden."));
            return section;
        }

        Map<String, List<Message>> messagesByJob = jobMessages.stream()
                .collect(Collectors.groupingBy(this::resolveJobKey, LinkedHashMap::new, Collectors.toList()));

        messagesByJob.forEach((jobKey, messages) -> {
            messages.sort(Comparator.comparing(Message::getCreatedAt, Comparator.nullsLast(LocalDateTime::compareTo)));
            Message latest = messages.get(messages.size() - 1);
            int unreadCount = (int) messages.stream()
                    .filter(message -> message.getOrigin() == MessageOrigin.CLIENT && !message.isRead())
                    .count();

            String conversationTitle = "Auftrag " + jobKey;
            section.add(createMessageCard(
                    conversationTitle,
                    resolvePreview(latest),
                    latest.getCreatedAt(),
                    messages.size(),
                    unreadCount,
                    "job-" + sanitizeConversationId(jobKey)
            ));
        });

        return section;
    }

    private String resolvePreview(Message message) {
        if (message == null) {
            return "";
        }

        if (message.getContentType() == MessageContentType.IMAGE) {
            return "[Bildnachricht]";
        }

        return Optional.ofNullable(message.getContent())
                .map(String::trim)
                .orElse("");
    }

    private Div createMessageCard(String conversationTitle, String lastMessagePreview,
            LocalDateTime lastMessageTime, int messageCount,
            int unreadCount, String conversationId) {
        Div card = new Div();
        card.setWidthFull();
        card.getStyle().set("padding", "15px");
        card.getStyle().set("border", "1px solid #e0e0e0");
        card.getStyle().set("border-radius", "8px");
        card.getStyle().set("cursor", "pointer");
        card.getStyle().set("background-color", "#ffffff");
        card.getStyle().set("margin-bottom", "10px");
        card.getStyle().set("max-width", "97.5%");
        card.addClassName("message-card");
        
        // Hover effect
        card.getElement().addEventListener("mouseenter", e -> {
            card.getStyle().set("background-color", "#f5f5f5");
        });
        card.getElement().addEventListener("mouseleave", e -> {
            card.getStyle().set("background-color", "#ffffff");
        });
        
        // Title row with unread indicator
        HorizontalLayout titleRow = new HorizontalLayout();
        titleRow.setWidthFull();
        titleRow.setAlignItems(com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment.CENTER);
        
        Span titleSpan = new Span(conversationTitle);
        titleSpan.getStyle().set("font-weight", "bold");
        titleSpan.getStyle().set("font-size", "16px");
        
        if (unreadCount > 0) {
            Span unreadBadge = new Span(String.valueOf(unreadCount));
            unreadBadge.getStyle().set("background-color", "var(--lumo-primary-color)");
            unreadBadge.getStyle().set("color", "white");
            unreadBadge.getStyle().set("border-radius", "50%");
            unreadBadge.getStyle().set("padding", "2px 8px");
            unreadBadge.getStyle().set("font-size", "12px");
            unreadBadge.getStyle().set("font-weight", "bold");
            titleRow.add(titleSpan, unreadBadge);
        } else {
            titleRow.add(titleSpan);
        }
        
        titleRow.expand(titleSpan);
        
        // Preview text
        Span preview = new Span(Optional.ofNullable(lastMessagePreview).filter(s -> !s.isBlank()).orElse("(kein Inhalt)"));
        preview.getStyle().set("color", "#666666");
        preview.getStyle().set("font-size", "14px");
        
        // Metadata row
        HorizontalLayout metaRow = new HorizontalLayout();
        metaRow.setWidthFull();
        
        Span timeSpan = new Span(lastMessageTime != null ? lastMessageTime.format(DATE_FORMATTER) : "-");
        timeSpan.getStyle().set("color", "#999999");
        timeSpan.getStyle().set("font-size", "12px");
        
        Span countSpan = new Span(messageCount + " Nachrichten");
        countSpan.getStyle().set("color", "#999999");
        countSpan.getStyle().set("font-size", "12px");
        
        metaRow.add(timeSpan, countSpan);
        metaRow.expand(timeSpan);
        
        // Add all elements to card
        VerticalLayout cardContent = new VerticalLayout(titleRow, preview, metaRow);
        cardContent.setWidthFull();
        cardContent.setPadding(false);
        cardContent.setSpacing(false);
        card.add(cardContent);
        
        // Click listener to navigate to message details
        card.addClickListener(e -> UI.getCurrent().navigate("message-details/" + participantKey + "/" + conversationId));

        return card;
    }

    private String resolveJobKey(Message message) {
        if (message == null) {
            return "Unbekannt";
        }
        String jobNumber = Optional.ofNullable(message.getJobNumber()).filter(s -> !s.isBlank()).orElse(null);
        if (jobNumber != null) {
            return jobNumber;
        }
        String jobId = message.getJobIdAsString();
        if (jobId != null && !jobId.isBlank()) {
            return jobId;
        }
        return "Unbekannt";
    }

    private String sanitizeConversationId(String value) {
        if (value == null || value.isBlank()) {
            return "unknown";
        }
        return value.replaceAll("[^a-zA-Z0-9_-]", "_");
    }
}
