using QuantEngine.Core.Models;

namespace QuantEngine.Application.Services;

/// <summary>
/// 가격 데이터 정규화 — Python _collect_one() 로직 대응
/// </summary>
public class PriceDataNormalizer
{
    private readonly SourcePriorityResolver _priorityResolver;

    public PriceDataNormalizer(SourcePriorityResolver priorityResolver)
    {
        _priorityResolver = priorityResolver;
    }

    public (Dictionary<string, object> Normalized, Dictionary<string, object> Provenance) NormalizeCollectionRow(
        Dictionary<string, object> row,
        PriceSourceResult? kis,
        PriceSourceResult? naver,
        bool includeNaver = false)
    {
        var ticker = (row.GetValueOrDefault("Ticker") as string) ?? (row.GetValueOrDefault("ticker") as string) ?? "";
        var name = (row.GetValueOrDefault("Name") as string) ?? (row.GetValueOrDefault("name") as string) ?? "";
        var sector = (row.GetValueOrDefault("Sector") as string) ?? (row.GetValueOrDefault("sector") as string);

        var normalized = new Dictionary<string, object>(row);
        
        var (sourcePriority, provenance) = _priorityResolver.ResolveSourcePriority(
            ticker, kis, naver, includeNaver: includeNaver);

        // KIS 데이터 병합
        if (kis?.Status == "OK")
        {
            MergeSourceFields(normalized, kis, new[] { "current_price", "open", "high", "low", "volume" });
            MergeSourceFields(normalized, kis, new[] { "relative_return_20d", "volume_ratio_5d", "microstructure_pressure", "short_turnover_share" });
        }

        // Naver 폴백
        if (naver?.Status == "OK" || naver?.Status == "DATA_MISSING")
        {
            // Removed
            // Removed
            NormalizedSetDefault(normalized, "naver_price_status", naver?.Status);
            NormalizedSetDefault(normalized, "current_price", naver?.CurrentPrice);
            NormalizedSetDefault(normalized, "open", naver?.Open);
            NormalizedSetDefault(normalized, "high", naver?.High);
            NormalizedSetDefault(normalized, "low", naver?.Low);
            NormalizedSetDefault(normalized, "volume", naver?.Volume);
        }

        // 최종 폴백 (기초 데이터)
        NormalizedSetDefault(normalized, "current_price", DataNormalizationHelper.CoerceFloat(row.GetValueOrDefault("current_price") ?? row.GetValueOrDefault("Current_Price") ?? row.GetValueOrDefault("close")));
        NormalizedSetDefault(normalized, "open", DataNormalizationHelper.CoerceFloat(row.GetValueOrDefault("open") ?? row.GetValueOrDefault("Open")));
        NormalizedSetDefault(normalized, "high", DataNormalizationHelper.CoerceFloat(row.GetValueOrDefault("high") ?? row.GetValueOrDefault("High")));
        NormalizedSetDefault(normalized, "low", DataNormalizationHelper.CoerceFloat(row.GetValueOrDefault("low") ?? row.GetValueOrDefault("Low")));
        NormalizedSetDefault(normalized, "volume", DataNormalizationHelper.CoerceFloat(row.GetValueOrDefault("volume") ?? row.GetValueOrDefault("Volume")));

        normalized["collection_as_of"] = DataNormalizationHelper.KstNowIso();

        return (normalized, provenance);
    }

    private void MergeSourceFields(Dictionary<string, object> target, PriceSourceResult source, string[] keys)
    {
        foreach (var key in keys)
        {
            var value = source.GetType().GetProperty(ToPascalCase(key))?.GetValue(source);
            if (value != null && !string.IsNullOrEmpty(value.ToString()))
                target[key] = value;
        }
    }

    private void NormalizedSetDefault(Dictionary<string, object> normalized, string key, object? value)
    {
        if (!normalized.ContainsKey(key) && value != null && !string.IsNullOrEmpty(value.ToString()))
            normalized[key] = value;
    }

    private string ToPascalCase(string snake)
    {
        return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(snake.Replace("_", " ")).Replace(" ", "");
    }
}

