using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd;
using Ban.Sdaid.Icd.Api.Endpoints.InputPackets.GetInputQueue;
using Ban.Sdaid.Icd.Api.Endpoints.InputPackets.DeleteInputPacket;
using Ban.Sdaid.Icd.Api.Endpoints.InputPackets.GetFrameContent;
using Ban.Sdaid.Icd.Api.Endpoints.InputPackets.NormalizePacket;
using Ban.Sdaid.Icd.Domain.Capture;
using Ban.Sdaid.Icd.Domain.Cards.Template.Vocabularies;
namespace Ban.Sdaid.Icd.Ui.Pages
{
/// <summary>Экран очереди и обработки пакета — мастер-деталь.</summary>
public class ProcessingQueuePage : IPageDocument, IFolder<UiFolder>, IHasStructuralLinks
{
public SdaidLink[] Links => new[]
{
Rel.Uses<InputPacketSpec>(),
Rel.Uses<DOC_GetInputQueue>(),
Rel.Uses<DOC_DeleteInputPacket>(),
Rel.Uses<DOC_GetFrameContent>(),
Rel.Uses<DOC_NormalizePacket>(),
Rel.Uses<VocabularyCatalog>(),
};
public string Name => "Очередь обработки";
/// <summary>Display-текст для типизированных ссылок <c>SdaidAnchors.RefTo<ProcessingQueuePage>()</c>.</summary>
public static string _refName = "экран «Очередь обработки»";
public string Description =>
@"Очередь пакетов слева, проверка выбранного пакета на двух вкладках справа: «Пакет ввода» и «Проверка карты» (ADR-008).";
public string Version => "0.7";
public string Status => "draft";
public string[] Comments => new[]
{
"2026-08-18. Переписана под две вкладки: меню этапов с подтверждениями отменено ADR-008.",
"2026-08-26. По CR «Обязательные поля ИК»: пометка обязательных полей, «Взять следующий», открытие вкладки на первом поле.",
"2026-08-27. Справочные поля: выбор из набора вместо ввода текстом; место хранения берётся из учётной записи.",
"2026-08-28. Повторяющиеся группы — эксперты и мониторинг — показаны списками вместо полей с номерами.",
"2026-08-31. Убран подбор экземпляра фонда: выведен из состава Сервиса.",
};
public static string S0_Implemented = $"""
## Реализовано (упрощённый срез)
Мастер-деталь: список пакетов очереди слева, карточка выбранного справа (номер, состояние,
время; удаление **мягкое**/**жёсткое**). Поиск по номеру/идентификаторам, относительное время,
обновление, автоскролл к выбранному.
Карточка пакета — **две вкладки проверки** (ADR-008, горизонтальные): реализована только
«**Пакет ввода**», «Проверка карты» — недоступна (заглушка). На «Пакете ввода» — **сетка
карточек кадров** с крупным превью (портрет 3:4): клик по превью — **просмотр** (полноэкранный
просмотрщик), кнопки **«Обработать заново»** (нормализация orthocover) и **удаления кадра** —
пер-кадрово. Обработанный кадр помечается меткой «обработано» на превью.
**Просмотрщик** (переиспользуемый) — полноэкранный оверлей, инфо-панель сверху, перелистывание кадров;
при наличии обработанной версии — переключатель **«Оригинал ↔ Обработано»**.
Прочие действия по кадру (переназначить страницу, переснять) и вкладка «Проверка карты» —
целевое видение (ниже), ещё не реализованы.
Контракты среза: очередь — {SdaidAnchors.RefTo<DOC_GetInputQueue>()}, содержимое кадра
(оригинал/обработанное) — {SdaidAnchors.RefTo<DOC_GetFrameContent>()}, обработка —
{SdaidAnchors.RefTo<DOC_NormalizePacket>()}, удаление (мягкое/жёсткое) —
{SdaidAnchors.RefTo<DOC_DeleteInputPacket>()}. Сущность очереди — {SdaidAnchors.RefTo<InputPacketSpec>()}.
""";
public static string S1_Layout = """
## Раскладка
Мастер-деталь: слева очередь пакетов, справа обработка выбранного. Полностраничный список здесь не
подходит — пакеты разбирают подряд, и вход в карточку не должен уводить с экрана очередь.
Панель очереди сворачивается, когда нужна вся ширина.
""";
public static string S2_Queue = $"""
## Очередь
Поиск по номеру пакета, шифру, инвентарному номеру и заглавию — по тому, что пользователь
помнит о карте, а не только по служебному номеру.
Фильтр по состояниям пакета — множественный выбор с счётчиками, четыре значения
({nameof(Ban.Sdaid.Icd.Arch.Adr.ADR_008_PacketStatesAndTwoTabs)}): в очереди,
проверка, завершён, ошибка. Переключатель «только мои» и отдельная ссылка сброса всех фильтров:
принадлежность и сброс — разные понятия и не смешиваются в одном элементе.
Кнопка «Взять в работу» выдаёт первый свободный пакет, подходящий под настройки профиля,
и показывает, какой именно будет взят.
Строка пакета: номер, время, опознанный вид ИК, состояние и уверенность распознавания числом.
Пока обработка не прошла, уверенности нет — так и показывается, а не нулём.
Индикатор состояния отвечает на вопрос «чья очередь ходить»: работает автоматика, ждёт
оператора либо завершено. Дублировать им название состояния незачем — оно выведено словами.
""";
public static string S3_Tabs = $"""
## Две вкладки
Обработка пакета делится не на этапы с подтверждениями, а на два вопроса, и каждому отведена
своя вкладка: **«Пакет ввода»** — верны ли исходные данные, **«Проверка карты»** — верно ли
Сервис их прочитал. Переход между вкладками свободный, подтверждать нечего: прохождение
пакета отражает его состояние, а не цепочка подтверждений.
### Пакет ввода
Вкладка строится **от опознанной формы**, а не от списка кадров: перечислены страницы формы,
напротив каждой — отнесённый к ней кадр либо возможность отснять недостающую. Так видно,
чего не хватает, — по списку кадров этого не понять.
Вид ИК и форма показаны явно, с уверенностью определения. Если вид определён неверно,
действие **«Вид ИК не распознан»** отклоняет его с возможностью указать верный; пакет уходит
в очередь вместе с этим контекстом — указанный вид не теряется, — а пользователь берёт следующий.
Кадр открывается в полном размере: переключение «оригинал ↔ обработанное», смена страницы,
переснять, повторить обработку, удалить. Кадры, не отнесённые ни к одной странице, — лишние:
их удаление повторной обработки не требует.
Правка, меняющая исходные данные разбора, делает результаты распознавания недействительными —
это показано, а на повторную обработку пакет уходит **по команде пользователя**, не сам.
### Проверка карты
Поля сгруппированы по страницам и разделам формы, у каждого — уверенность. Рядом
с исправленным значением видно, что прочла модель.
**Обязательные поля помечены**, а незаполненное среди них выделено так, чтобы его было
видно, не открывая каждый раздел. Состав обязательных зависит от вида документа
и берётся из настройки, а не зашит в экран.
**Поле со справочным значением текстом не вводится.** Отметке в клетке бланка отвечает
выбор из набора допустимых значений; наборы переданы заказчиком
({SdaidAnchors.RefTo<VocabularyCatalog>()}). Пользователь видит значение, хранится
и выгружается код. Несколько отметок на бланке дают несколько выбранных значений,
а отметка «Ничего» исключает остальные и исключается ими.
Если модель прочла то, чего в наборе нет, **поле остаётся незаполненным**, а прочитанное
показано рядом: подставить нечего, а выбрать верное — работа пользователя. Так же
выглядит расхождение бланка и справочника, когда клетка напечатана, а значения
в наборе нет.
**Повторяющаяся группа бланка показывается списком.** Строка — эксперт, закладка
биотеста, замер: отдельный {SdaidAnchors.RefTo<Ban.Sdaid.Icd.Domain.Cards.CardDocumentSpec>()},
а не набор полей с номерами. Строки добавляются и удаляются — бумага отводит под
экспертов пять строк, но это свойство бланка, а не состава вида.
В строке видно только значение, уверенность передана его цветом; редактор ячейки
открывается под таблицей. Числа уверенности в каждой ячейке и редакторы у всех ячеек
сразу таблицу не читают.
Отдельным блоком **над полями формы** — реквизиты самой карты, которых на бланке нет:
**место хранения** выбирается из справочника и по умолчанию берётся из учётной записи
пользователя — у заказчика они связаны. В состав формы такое поле не входит и в разделах
бланка не показывается: читать его неоткуда, уверенности у него нет.
Выбор поля показывает справа страницу-источник с подсвеченной областью. Изображение крупное,
с прямоугольной лупой во всю ширину — иначе рукописный текст не разобрать. Вкладка
открывается на первом поле бланка: пустой просмотрщик не объясняет, зачем он нужен.
Ниже — состав экспертов со сверкой по справочнику. Экземпляр фонда здесь не подбирается:
привязка карты к экземпляру в состав Сервиса не входит.
Завершает работу действие **«Создать ИК»**. Оно недоступно, пока не заполнены обязательные
поля; состав кадров на это не влияет — не снятую страницу пользователь вправе внести руками.
Рядом названы недостающие поля.
Этой же командой создаётся файл для загрузки в АБИС: отдельной кнопки выгрузки на экране
нет и не нужно.
Рядом с ним — **«Взять следующий»**, выход для того, кто карту сейчас не создаёт. Данных
это действие не меняет: правки сохраняются по мере ввода, пакет остаётся за оператором,
и он вернётся к нему через очередь. Отдельного «Сохранить» на экране нет и не нужно.
Сценарий целиком — {nameof(Ban.Sdaid.Icd.Epics.PacketProcessing.UseCases.VerifyPacketUseCase)}.
""";
public static string S9_Prototype = $"""
## Прототип
{SdaidHtml.LinkTo<ProcessingQueuePage>("queue.html", "Открыть прототип в новой вкладке")}
{SdaidHtml.IframeOf<ProcessingQueuePage>("queue.html", 720)}
""";
}
}