package de.assecutor.votianlt.pages.view;

import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Anchor;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.server.StreamResource;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import de.assecutor.votianlt.model.Job;
import de.assecutor.votianlt.model.JobStatus;
import de.assecutor.votianlt.repository.JobRepository;
import de.assecutor.votianlt.security.SecurityService;
import jakarta.annotation.security.RolesAllowed;
import org.springframework.beans.factory.annotation.Autowired;

@PageTitle("Aufträge")
@Route(value = "jobs", layout = de.assecutor.votianlt.pages.base.ui.view.MainLayout.class)
@RolesAllowed({ "USER" })
public class ShowJobsView extends VerticalLayout {

    private final DatePicker startDate = new DatePicker("Startdatum");
    private final DatePicker endDate = new DatePicker("Enddatum");
    private final TextField searchField = new TextField("Auftragsnummer suchen");
    private final ComboBox<String> statusFilter = new ComboBox<>("Status");
    private final JobRepository jobRepository;
    private final SecurityService securityService;
    private final Grid<Job> grid = new Grid<>(Job.class, false);

    @Autowired
    public ShowJobsView(JobRepository jobRepository, SecurityService securityService) {
        this.jobRepository = jobRepository;
        this.securityService = securityService;
        setSizeFull();
        setPadding(true);
        setSpacing(true);

        // Configure status filter
        statusFilter.setItems("Alle", "Offen", "Erledigt");
        statusFilter.setValue("Offen");
        statusFilter.setWidth("150px");

        // Configure search field
        searchField.setPlaceholder("Auftragsnummer eingeben...");
        searchField.setClearButtonVisible(true);
        searchField.setWidth("200px");

        // Filterleiste mit Export-Button am rechten Rand
        Button applyFilter = new Button("Anwenden");
        HorizontalLayout leftFilters = new HorizontalLayout(startDate, endDate, searchField, statusFilter, applyFilter);
        leftFilters.setAlignItems(Alignment.END);

        HorizontalLayout filterBar = new HorizontalLayout();
        filterBar.setWidthFull();
        filterBar.add(leftFilters);
        Button exportButton = new Button("CSV Export");
        filterBar.add(exportButton);
        filterBar.setJustifyContentMode(JustifyContentMode.BETWEEN);
        filterBar.setAlignItems(Alignment.END);
        add(filterBar);

        H2 title = new H2("Aufträge");
        add(title);
        // Init default period: last 30 days
        java.time.LocalDate today = java.time.LocalDate.now();
        startDate.setValue(today.minusDays(30));
        endDate.setValue(today);
        applyFilter.addClickListener(e -> loadData());
        exportButton.addClickListener(e -> exportToCsv());

        // Add real-time filtering
        searchField.addValueChangeListener(e -> loadData());
        statusFilter.addValueChangeListener(e -> loadData());
        startDate.addValueChangeListener(e -> loadData());
        endDate.addValueChangeListener(e -> loadData());

        // Configure grid columns: Kunde, Auftragsnummer, Auftragsdatum, Zielort
        grid.addColumn(Job::getDeliveryCompany).setHeader("Kunde").setAutoWidth(true).setFlexGrow(1).setSortable(true);
        grid.addColumn(Job::getJobNumber).setHeader("Auftragsnummer").setAutoWidth(true).setSortable(true);
        grid.addColumn(Job::getCreatedAt).setHeader("Auftragsdatum").setAutoWidth(true).setSortable(true);
        grid.addColumn(Job::getDeliveryCity).setHeader("Zielort").setAutoWidth(true).setFlexGrow(1).setSortable(true);

        grid.setMultiSort(true);
        grid.setSizeFull();

        // Make grid rows clickable
        grid.setSelectionMode(Grid.SelectionMode.SINGLE);
        grid.getStyle().set("cursor", "pointer");

        // Add click listener to navigate to job summary view
        grid.addItemClickListener(event -> {
            Job job = event.getItem();
            if (job != null && job.getId() != null) {
                getUI().ifPresent(ui -> ui.navigate("job_summary/" + job.getId().toHexString()));
            }
        });

        add(grid);

        loadData();
    }

    private void loadData() {
        var start = startDate.getValue();
        var end = endDate.getValue();
        java.time.LocalDateTime startDt = start != null ? start.atStartOfDay()
                : java.time.LocalDate.now().minusDays(30).atStartOfDay();
        java.time.LocalDateTime endDt = end != null ? end.atTime(23, 59, 59)
                : java.time.LocalDate.now().atTime(23, 59, 59);

        // Aktuellen Benutzer (ObjectId Hex) ermitteln
        String currentUserIdHex = securityService.getCurrentUserId().toHexString();

        // Status-Filter bestimmen
        String selectedStatus = statusFilter.getValue();
        java.util.List<JobStatus> statusList;

        if ("Erledigt".equals(selectedStatus)) {
            statusList = java.util.List.of(JobStatus.DELIVERED, JobStatus.COMPLETED, JobStatus.CANCELLED);
        } else if ("Offen".equals(selectedStatus)) {
            statusList = java.util.List.of(JobStatus.CREATED, JobStatus.IN_PROGRESS, JobStatus.PICKUP_SCHEDULED,
                    JobStatus.PICKED_UP, JobStatus.IN_TRANSIT);
        } else { // "Alle"
            statusList = java.util.Arrays.asList(JobStatus.values());
        }

        // Suchtext für Auftragsnummer
        String searchText = searchField.getValue();
        String jobNumberPattern = searchText != null && !searchText.trim().isEmpty() ? searchText.trim() : ".*"; // Regex
                                                                                                                 // für
                                                                                                                 // alle
                                                                                                                 // wenn
                                                                                                                 // leer

        // Verwende die erweiterte Suchmethode
        var filteredJobs = jobRepository.findWithFilters(startDt, endDt, currentUserIdHex, jobNumberPattern,
                statusList);
        grid.setItems(filteredJobs);
    }

    private void exportToCsv() {
        var items = grid.getListDataView().getItems().toList();

        StreamResource resource = new StreamResource("jobs.csv", () -> new java.io.ByteArrayInputStream(
                generateCsv(items).getBytes(java.nio.charset.StandardCharsets.UTF_8)));
        resource.setContentType("text/csv");
        resource.setCacheTime(0);

        // Create download anchor and trigger immediately
        Anchor downloadAnchor = new Anchor(resource, "Download CSV");
        downloadAnchor.getElement().setAttribute("download", "jobs.csv");
        downloadAnchor.setTarget("_blank");

        // Add to UI and trigger download via JavaScript
        add(downloadAnchor);
        getUI().ifPresent(ui -> ui.getPage().executeJs(
                "const link = arguments[0]; link.click(); setTimeout(() => link.remove(), 100);",
                downloadAnchor.getElement()));
    }

    private String generateCsv(java.util.List<Job> jobs) {
        StringBuilder csv = new StringBuilder();
        // CSV Header
        csv.append("Kunde,Auftragsnummer,Auftragsdatum,Zielort\n");

        // CSV Data
        for (Job job : jobs) {
            csv.append(escapeCsv(job.getDeliveryCompany())).append(",");
            csv.append(escapeCsv(job.getJobNumber())).append(",");
            csv.append(job.getCreatedAt() != null ? job.getCreatedAt().toString() : "").append(",");
            csv.append(escapeCsv(job.getDeliveryCity())).append("\n");
        }

        return csv.toString();
    }

    private String escapeCsv(String value) {
        if (value == null)
            return "";
        if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
            return "\"" + value.replace("\"", "\"\"") + "\"";
        }
        return value;
    }
}
