using Application.Abstractions.Data;
using Domain.Entities.Stocks;
using Microsoft.EntityFrameworkCore;
namespace Infrastructure.StockData;
///
/// SeibroIssuerSyncService 의 DB 반영 로직 분리 (테스트 가능) — HTTP 없이 파서 출력(fixture)으로 검증한다
/// (KRX 테스트들이 파서/로직을 분리 검증하는 방식 미러링).
///
public static class SeibroIssuerImport
{
///
/// getShotnByMart 결과를 SeibroIssuerCode 로 upsert — UQ (Market, ShortCode) 기준.
/// 동일 단축코드 중복 행은 마지막 행 우선. 무변경 행은 no-op (UpdatedAt 미갱신).
///
public static async Task<(int Inserted, int Updated)> UpsertIssuerCodesAsync(IAppDbContext db, string market, IReadOnlyList rows, CancellationToken ct)
{
var existing = await db.SeibroIssuerCode.Where(c => c.Market == market).ToListAsync(ct);
var byShortCode = existing.ToDictionary(c => c.ShortCode);
var inserted = 0;
var updated = 0;
foreach (var row in rows)
{
if (byShortCode.TryGetValue(row.ShortCode, out var code))
{
var was = code.UpdatedAt;
code.Update(row.Name, row.IssucoCustno);
if (code.UpdatedAt != was)
{
updated++;
}
}
else
{
var created = SeibroIssuerCode.Create(market, row.ShortCode, row.Name, row.IssucoCustno);
await db.SeibroIssuerCode.AddAsync(created, ct);
byShortCode[row.ShortCode] = created;
inserted++;
}
}
await db.SaveChangesAsync(ct);
return (inserted, updated);
}
///
/// Stock.IssucoCustno 스탬핑 — Stock.Code = 단축코드 조인. 이미 같은 값이면 무변경. 반환 = 실제 스탬핑된 종목 수.
/// KRX Stock 은 KOSPI/KOSDAQ/KONEX 만 커버하므로 K-OTC(13) 등 미커버 시장 코드는 자연히 매칭되지 않는다.
///
public static async Task StampStockIssucoCustnoAsync(IAppDbContext db, IReadOnlyDictionary custnoByShortCode, CancellationToken ct)
{
var stocks = await db.Stock.ToListAsync(ct);
var stamped = 0;
foreach (var stock in stocks)
{
if (!custnoByShortCode.TryGetValue(stock.Code, out var custno) || stock.IssucoCustno == custno)
{
continue;
}
stock.SetIssucoCustno(custno);
stamped++;
}
await db.SaveChangesAsync(ct);
return stamped;
}
}