namespace Shared.Excel;

public sealed class ImportMappingEngine
{
    public IReadOnlyList<ImportMapping> Map(
        IReadOnlyList<string> sourceColumns,
        ImportDefinition definition,
        IReadOnlyList<ImportMapping>? saved = null)
    {
        var savedBySource = (saved ?? [])
            .Where(x => x.TargetField is not null)
            .ToDictionary(x => Normalize(x.SourceColumn), StringComparer.OrdinalIgnoreCase);

        var result = new List<ImportMapping>(sourceColumns.Count);
        foreach (var source in sourceColumns)
        {
            var normalized = Normalize(source);
            if (savedBySource.TryGetValue(normalized, out var savedMapping) &&
                definition.Fields.Any(x => x.Key.Equals(savedMapping.TargetField, StringComparison.OrdinalIgnoreCase)))
            {
                result.Add(savedMapping with { SourceColumn = source, Source = "saved", Confidence = 1m, Reason = "저장된 매핑" });
                continue;
            }

            var exact = definition.Fields.FirstOrDefault(x => Normalize(x.Label) == normalized || Normalize(x.Key) == normalized);
            if (exact is not null)
            {
                result.Add(new(source, exact.Key, "exact", 1m, "필드명 일치"));
                continue;
            }

            var alias = definition.Fields.FirstOrDefault(x => x.Aliases.Any(a => Normalize(a) == normalized));
            if (alias is not null)
            {
                result.Add(new(source, alias.Key, "alias", 1m, $"별칭 '{source}' 일치"));
                continue;
            }

            result.Add(new(source, null, "manual", null, null));
        }
        return result;
    }

    private static string Normalize(string value) =>
        new(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
}
