"""Reconcile replayed ledger records and locate target-sum audit batches."""


def deduplicate(records):
    """Record = (nonempty transaction ID, nonempty account, signed integer amount)."""
    seen, unique = {}, []
    for record in records:
        if (len(record) != 3 or not isinstance(record[0], str) or not record[0]
                or not isinstance(record[1], str) or not record[1] or not isinstance(record[2], int)):
            raise ValueError("invalid transaction")
        record = tuple(record)
        transaction_id = record[0]
        if transaction_id in seen:
            if seen[transaction_id] != record:
                raise ValueError("same transaction ID has conflicting data")
        else:
            seen[transaction_id] = record
            unique.append(record)
    return unique


def account_balances(records):
    balances = {}
    for _, account, amount in records:
        balances[account] = balances.get(account, 0) + amount
    return balances


def first_target_pair(records, target):
    """Earliest second position, then earliest first position; distinct records."""
    first_amount = {}
    for transaction_id, _, amount in records:
        if target - amount in first_amount:
            return (first_amount[target - amount], transaction_id)
        first_amount.setdefault(amount, transaction_id)
    return None


def count_target_batches(records, target):
    """Count nonempty contiguous batches in the deduplicated arrival order."""
    frequencies = {0: 1}
    prefix = count = 0
    for _, _, amount in records:
        prefix += amount
        count += frequencies.get(prefix - target, 0)
        frequencies[prefix] = frequencies.get(prefix, 0) + 1
    return count


def audit_ledger(records, target=0):
    if not isinstance(target, int):
        raise ValueError("target must be an integer")
    unique = deduplicate(records)
    return {"records": unique, "balances": account_balances(unique),
            "pair": first_target_pair(unique, target),
            "batch_count": count_target_batches(unique, target)}
