import { normalizedUnionType } from "../types/type-ops.js";
import { collectNarrowingCandidateLeaves } from "./narrowing-candidates.js";
export const narrowTypeByAssignableTarget = (collector, currentType, targetType, wantAssignable) => {
    const tryTargetFallback = () => {
        if (!wantAssignable || !currentType || currentType.kind === "unknownType") {
            return undefined;
        }
        if (collector.isAssignableTo(targetType, currentType)) {
            return targetType;
        }
        const kept = collectNarrowingCandidateLeaves(collector, targetType).filter((candidate) => !!candidate && collector.isAssignableTo(candidate, currentType));
        if (kept.length === 0)
            return undefined;
        if (kept.length === 1)
            return kept[0];
        return normalizedUnionType(kept);
    };
    if (!currentType || currentType.kind === "unknownType") {
        return wantAssignable ? targetType : undefined;
    }
    if (currentType.kind === "unionType") {
        const directMembers = currentType.types.filter((member) => !!member);
        const directKept = directMembers.filter((member) => {
            const isMatch = collector.isAssignableTo(member, targetType);
            return wantAssignable ? isMatch : !isMatch;
        });
        if (directKept.length !== directMembers.length) {
            if (directKept.length === 0) {
                return undefined;
            }
            if (directKept.length === 1) {
                return directKept[0];
            }
            return normalizedUnionType(directKept);
        }
    }
    const candidates = collectNarrowingCandidateLeaves(collector, currentType);
    const kept = candidates.filter((member) => {
        if (!member)
            return false;
        const isMatch = collector.isAssignableTo(member, targetType);
        return wantAssignable ? isMatch : !isMatch;
    });
    if (kept.length === 0) {
        return wantAssignable ? tryTargetFallback() : currentType;
    }
    if (kept.length === 1)
        return kept[0];
    return normalizedUnionType(kept);
};
//# sourceMappingURL=reference-type-guards.js.map