using Deal.Contracts.Integrations.Models;
using Deal.Modules.Kanban.Application;
using Deal.Modules.Kanban.Application.Models;
using Deal.Modules.Pipeline.Application.Models;
namespace Deal.Modules.Pipeline.Application;
///
/// Создание карточки пайплайна через публичный интерфейс Kanban (план Task 7 L400–402, Ruling 3/4;
/// python _store_lead L483–514: INSERT карточки → UPDATE dedup.lead_id → чтение после записи).
///
///
/// Тонкая обёртка создания: генерирует id карточки (c_, / —
/// переиспользуем генератор владельца), собирает полный снимок через и пишет его
/// , после чего связывает заявку дедупа с карточкой
/// ( — порядок AddCard → Link 1:1 с Ruling 4, L512–513) и перечитывает
/// полный (для SSE new_card, Ruling 8/9).
///
/// Проверку «уже есть карточка по дедупу» обёртка НЕ дублирует — её делает воркер на «new»-проходе pump
/// (Ruling 8, L940–951): к моменту записи сообщение уже прошло дедуп-гвард и его хэш заявлен (LeadId=null).
/// Транзакционности карточка + dedup-link нет (как в прототипе — два отдельных statement'а адаптеров на общем
/// TenantDbContext, Ruling 3/4): сбой LinkAsync оставляет карточку без связи и пробрасывается вызывающему.
///
///
public sealed class PipelineCardWriter(ICardStore kanjStore, IPipelineStore pipelineStore, CardComposer composer)
{
///
/// Создаёт карточку из разобранного сообщения и связывает её с заявкой дедупа.
///
/// Разбор сообщения (ИИ/локальный путь; колонка разбора пройдёт ContainerAccepts-страховку).
/// Строка очереди с сообщением-источником (метаданные канала/текст/время).
/// SHA1-hex хэша текста (заявка дедупа уже создана воркером, Ruling 8).
/// Токен отмены.
/// Полная карточка (чтение после записи — §4.1, как lead_to_dict после INSERT, L514).
/// Карточка не прочиталась сразу после создания.
public async Task CreateCardAsync(
AiParsedCardDto parsed,
QueueItemDto message,
string dedupHash,
CancellationToken ct)
{
string cardId = PrefixId.New(KanbanIdPrefixes.Card);
CardSnapshot snapshot = await composer.BuildAsync(parsed, message, cardId, ct);
await kanjStore.AddCardAsync(snapshot, ct);
await pipelineStore.LinkAsync(dedupHash, cardId, ct);
return await kanjStore.GetCardAsync(cardId, ct)
?? throw new InvalidOperationException("Карточка не прочиталась после создания: " + cardId);
}
}