--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using Dalamud.Interface;
+using Dalamud.Interface.Colors;
+using Dalamud.Interface.Components;
+using Dalamud.Plugin;
+using ImGuiNET;
+using LLib.ImGui;
+using Questionable.Controller;
+using Questionable.Functions;
+using Questionable.Model;
+using Questionable.Model.Questing;
+using Questionable.Windows.QuestComponents;
+
+namespace Questionable.Windows;
+
+internal sealed class PriorityWindow : LWindow
+{
+    private readonly QuestController _questController;
+    private readonly QuestRegistry _questRegistry;
+    private readonly QuestFunctions _questFunctions;
+    private readonly QuestTooltipComponent _questTooltipComponent;
+    private readonly UiUtils _uiUtils;
+    private readonly IDalamudPluginInterface _pluginInterface;
+
+    private string _searchString = string.Empty;
+    private ElementId? _draggedItem;
+
+    public PriorityWindow(QuestController questController, QuestRegistry questRegistry, QuestFunctions questFunctions,
+        QuestTooltipComponent questTooltipComponent, UiUtils uiUtils, IDalamudPluginInterface pluginInterface)
+        : base("Quest Priority###QuestionableQuestPriority")
+    {
+        _questController = questController;
+        _questRegistry = questRegistry;
+        _questFunctions = questFunctions;
+        _questTooltipComponent = questTooltipComponent;
+        _uiUtils = uiUtils;
+        _pluginInterface = pluginInterface;
+
+        Size = new Vector2(400, 400);
+        SizeCondition = ImGuiCond.Once;
+        SizeConstraints = new WindowSizeConstraints
+        {
+            MinimumSize = new Vector2(400, 400),
+            MaximumSize = new Vector2(400, 999)
+        };
+    }
+
+    public override void Draw()
+    {
+        ImGui.Text("Quests to do first:");
+        DrawQuestFilter();
+        DrawQuestList();
+        ImGui.Spacing();
+
+        ImGui.Separator();
+        ImGui.Spacing();
+        ImGui.TextWrapped(
+            "If you have an active MSQ quest, Questionable will generally try to do:");
+        ImGui.BulletText("'Priority' quests: class quests, ARR primals, ARR raids");
+        ImGui.BulletText(
+            "Supported quests in your 'To-Do list'\n(quests from your Journal that are always on-screen)");
+        ImGui.BulletText("MSQ quest (if available, unless it is marked as 'ignored'\nin your Journal)");
+        ImGui.TextWrapped(
+            "If you don't have any active MSQ quest, it will always try to pick up the next quest in the MSQ first.");
+    }
+
+    private void DrawQuestFilter()
+    {
+        ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
+        if (ImGui.BeginCombo($"##QuestSelection", "Add Quest...", ImGuiComboFlags.HeightLarge))
+        {
+            ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
+            bool addFirst = ImGui.InputTextWithHint("", "Filter...", ref _searchString, 256,
+                ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.EnterReturnsTrue);
+
+            IEnumerable<Quest> foundQuests;
+            if (!string.IsNullOrEmpty(_searchString))
+            {
+                foundQuests = _questRegistry.AllQuests
+                    .Where(x => x.Info.Name.Contains(_searchString, StringComparison.CurrentCultureIgnoreCase))
+                    .Where(x => x.Id is not QuestId questId || !_questFunctions.IsQuestUnobtainable(questId));
+            }
+            else
+            {
+                foundQuests = _questRegistry.AllQuests.Where(x => _questFunctions.IsQuestAccepted(x.Id));
+            }
+
+            foreach (var quest in foundQuests)
+            {
+                if (quest.Info.IsMainScenarioQuest || _questController.ManualPriorityQuests.Contains(quest))
+                    continue;
+
+                bool addThis = ImGui.Selectable(quest.Info.Name);
+                if (addThis || addFirst)
+                {
+                    _questController.ManualPriorityQuests.Add(quest);
+
+                    if (addFirst)
+                    {
+                        ImGui.CloseCurrentPopup();
+                        addFirst = false;
+                    }
+                }
+            }
+
+            ImGui.EndCombo();
+        }
+
+        ImGui.Spacing();
+    }
+
+    private void DrawQuestList()
+    {
+        List<Quest> priorityQuests = _questController.ManualPriorityQuests;
+        Quest? itemToRemove = null;
+        Quest? itemToAdd = null;
+        int indexToAdd = 0;
+
+        float width = ImGui.GetContentRegionAvail().X;
+        List<(Vector2 TopLeft, Vector2 BottomRight)> itemPositions = [];
+
+        for (int i = 0; i < priorityQuests.Count; ++i)
+        {
+            Vector2 topLeft = ImGui.GetCursorScreenPos() +
+                              new Vector2(0, -ImGui.GetStyle().ItemSpacing.Y / 2);
+            var quest = priorityQuests[i];
+            ImGui.PushID($"Quest{quest.Id}");
+
+            var style = _uiUtils.GetQuestStyle(quest.Id);
+            bool hovered;
+            using (var _ = _pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
+            {
+                ImGui.AlignTextToFramePadding();
+                ImGui.TextColored(style.Color, style.Icon.ToIconString());
+                hovered = ImGui.IsItemHovered();
+            }
+
+            ImGui.SameLine();
+            ImGui.AlignTextToFramePadding();
+            ImGui.Text(quest.Info.Name);
+            hovered |= ImGui.IsItemHovered();
+
+            if (hovered)
+                _questTooltipComponent.Draw(quest.Info);
+
+            if (priorityQuests.Count > 1)
+            {
+                ImGui.PushFont(UiBuilder.IconFont);
+                ImGui.SameLine(ImGui.GetContentRegionAvail().X +
+                               ImGui.GetStyle().WindowPadding.X -
+                               ImGui.CalcTextSize(FontAwesomeIcon.ArrowsUpDown.ToIconString()).X -
+                               ImGui.CalcTextSize(FontAwesomeIcon.Times.ToIconString()).X -
+                               ImGui.GetStyle().FramePadding.X * 4 -
+                               ImGui.GetStyle().ItemSpacing.X);
+                ImGui.PopFont();
+
+                if (_draggedItem == quest.Id)
+                {
+                    ImGuiComponents.IconButton("##Move", FontAwesomeIcon.ArrowsUpDown,
+                        ImGui.ColorConvertU32ToFloat4(ImGui.GetColorU32(ImGuiCol.ButtonActive)));
+                }
+                else
+                    ImGuiComponents.IconButton("##Move", FontAwesomeIcon.ArrowsUpDown);
+
+                if (_draggedItem == null && ImGui.IsItemActive() && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
+                    _draggedItem = quest.Id;
+
+                ImGui.SameLine();
+            }
+            else
+            {
+                ImGui.PushFont(UiBuilder.IconFont);
+                ImGui.SameLine(ImGui.GetContentRegionAvail().X +
+                               ImGui.GetStyle().WindowPadding.X -
+                               ImGui.CalcTextSize(FontAwesomeIcon.Times.ToIconString()).X -
+                               ImGui.GetStyle().FramePadding.X * 2);
+                ImGui.PopFont();
+            }
+
+            if (ImGuiComponents.IconButton($"##Remove{i}", FontAwesomeIcon.Times))
+                itemToRemove = quest;
+
+            ImGui.PopID();
+
+            Vector2 bottomRight = new Vector2(topLeft.X + width,
+                ImGui.GetCursorScreenPos().Y - ImGui.GetStyle().ItemSpacing.Y + 2);
+            itemPositions.Add((topLeft, bottomRight));
+        }
+
+        if (!ImGui.IsMouseDragging(ImGuiMouseButton.Left))
+            _draggedItem = null;
+        else if (_draggedItem != null)
+        {
+            var draggedItem = priorityQuests.Single(x => x.Id == _draggedItem);
+            int oldIndex = priorityQuests.IndexOf(draggedItem);
+
+            var (topLeft, bottomRight) = itemPositions[oldIndex];
+            ImGui.GetWindowDrawList().AddRect(topLeft, bottomRight, ImGui.GetColorU32(ImGuiColors.DalamudGrey), 3f,
+                ImDrawFlags.RoundCornersAll);
+
+            int newIndex = itemPositions.FindIndex(x => ImGui.IsMouseHoveringRect(x.TopLeft, x.BottomRight, true));
+            if (newIndex >= 0 && oldIndex != newIndex)
+            {
+                itemToAdd = priorityQuests.Single(x => x.Id == _draggedItem);
+                indexToAdd = newIndex;
+            }
+        }
+
+        if (itemToRemove != null)
+        {
+            priorityQuests.Remove(itemToRemove);
+        }
+
+        if (itemToAdd != null)
+        {
+            priorityQuests.Remove(itemToAdd);
+            priorityQuests.Insert(indexToAdd, itemToAdd);
+        }
+    }
+}