using System;
using System.Collections.Generic;
using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd.Domain.Cards.Template;
namespace Ban.Sdaid.Icd.Domain.Cards
{
/// <summary>Электронная ИК — документы своего вида плюс ядро и связи Сервиса.</summary>
[DomainEntity]
public class InformationCard
{
/// <summary>Идентификатор карты.</summary>
public Guid Id { get; init; }
/// <summary>Вид документа, по которому заполнена карта.</summary>
[Relation]
public DocumentKind Kind { get; init; } = null!;
/// <summary>Дата карты: когда экземпляр передан в обработку.</summary>
public DateOnly Date { get; init; }
/// <summary>Документы карты: содержимое, заполненное по видам.</summary>
[Relation(Kind = RelationKind.Composition, Min = 1)]
public IReadOnlyList<CardDocument> Documents { get; init; } = new CardDocument[0];
/// <summary>Пакет ввода, из которого создана карта.</summary>
public Guid SourcePacketId { get; init; }
/// <summary>Ядро: шифр хранения.</summary>
public string Shelf { get; init; } = string.Empty;
/// <summary>Ядро: инвентарный номер.</summary>
public string InventoryNumber { get; init; } = string.Empty;
/// <summary>Ядро: заглавие документа.</summary>
public string Title { get; init; } = string.Empty;
/// <summary>Ядро: автор.</summary>
public string? Author { get; init; }
/// <summary>Ядро: год издания.</summary>
public int? Year { get; init; }
/// <summary>Момент создания карты.</summary>
public DateTime CreatedAt { get; init; }
/// <summary>Пользователь, создавший карту.</summary>
public Guid CreatedByUserId { get; init; }
/// <summary>Момент последней выгрузки в АБИС; null — не выгружалась.</summary>
public DateTime? ExportedAt { get; init; }
}
/// <summary>Описание доменной сущности <see cref="InformationCard"/>.</summary>
public class InformationCardSpec : IDomainEntityDocument
{
public Type Entity => typeof(InformationCard);
public string Name => "Информационная карта";
public string Description =>
@"Итог оцифровки одной бумажной формы: документы карты со значениями атрибутов, типизированное ядро для поиска, связь с пакетом-первоисточником и отметка о выгрузке в АБИС.";
public string Version => "0.4";
public string Status => "draft";
public string[] Comments => new[]
{
"2026-08-19. Переписана по варианту 5: вид документа, дата как обязательный реквизит, дерево документов карты вместо одного корневого документа.",
"2026-08-31. Убрана связь с экземпляром фонда: реестр экземпляров и привязка карты к экземпляру выведены из состава Сервиса.",
};
public static string S1_Purpose = """
## Назначение
Итог оцифровки одной бумажной формы. Создаётся командой пользователя по итогам проверки
и попадает в реестр информационных карт.
""";
public static string S2_WhySeparateEntity = """
## Почему карта — отдельная сущность, а не просто документ
Содержимое карты хранится в документах карты, но карта ими не исчерпывается.
У неё есть то, чего у документа как такового быть не может:
- связь с пакетом-первоисточником;
- дата карты: когда экземпляр передан в обработку;
- факт выгрузки в АБИС;
- собственный жизненный цикл: карта возникает командой пользователя по итогам проверки.
Карта при этом **не является** документом дерева: она стоит над ним и содержит документы,
а не наследует их устройство. Собственных атрибутов у неё нет — всё, что пишется
на бланке, живёт в документах карты.
Загнать это в атрибуты нельзя: «выгружена ли карта» не может быть строкой в общем
хранилище значений наравне с заглавием и годом издания.
""";
public static string S3_Core = """
## Ядро
Шифр, инвентарный номер, заглавие, автор, год вынесены в типизированные свойства.
Дата в ядро не входит: это собственный реквизит карты, а не проекция значения.
Критерий отбора функциональный: в ядро идёт то, **по чему Сервис работает сам** — ищет
карту, строит реестр, отбирает выборку, формирует выгрузку.
Структурный критерий «общее для всех бланков» здесь не работает: у ИК издания одно поле
«Заглавие», а у ИК рукописи их три — унифицированное, полное и перевод.
**Ядро — проекция, а не второй источник истины.** Источник истины — значения атрибутов
документов карты; свойства ядра заполняются из них и пересчитываются при правке значений.
Какой атрибут даёт какое свойство ядра, задаёт атрибут вида документа.
Чем это оплачено: ядро можно рассинхронизировать со значениями, и ошибка будет тихой —
реестр покажет одно, карта будет содержать другое.
""";
public static string S4_Invariants = """
## Инварианты
- Карта создаётся только по пакету, у которого заполнены обязательные поля состава.
- Один пакет порождает одну карту.
- Карта не бывает без документов: собственных атрибутов у неё нет, и всё, что на бланке,
живёт в документах. Карта без них пуста.
- Карта не ссылается на экземпляр фонда: привязка карты к экземпляру в состав Сервиса
не входит. Документ опознаётся на стороне АБИС по шифру и инвентарному номеру,
которые в карте есть всегда — они обязательны.
- У одного документа фонда может быть несколько карт — по числу событий обработки;
различает их дата карты.
- Свойства ядра совпадают со значениями атрибутов, из которых выведены.
- Вид карты совпадает с видом документа, по которому собран пакет-первоисточник.
""";
public static string S99_Related = $"""
## Связанные артефакты
- {nameof(Ban.Sdaid.Icd.Arch.Adr.ADR_006_CardDataStructure)} — решение о структуре данных информационной карты
""";
}
}