import { SuiClient } from '@mysten/sui/client'

import { MoveCallObjectFetcher } from './move-call-object-fetcher'
import { IPTBValidator, ObjectFetchOptions } from './ptb-validator'
import { MAX_BATCH_SIZE, MoveCall } from '../types'

/**
 * Validates move calls using multiple validators with a single object fetch
 * @param client - SuiClient instance
 * @param moveCalls - Array of move calls to validate
 * @param validators - Array of validators to run
 * @param options - Options for what object data to fetch
 * @param batchSize - Batch size for object fetching
 */
export async function validateWithDetails(
    client: SuiClient,
    moveCalls: MoveCall[],
    validators: IPTBValidator[],
    sender?: string,
    userOptions: ObjectFetchOptions = {},
    batchSize: number = MAX_BATCH_SIZE
): Promise<void> {
    if (validators.length === 0) {
        return // No validators to run
    }

    // Default to fetching all common options, user can override
    const defaultOptions: ObjectFetchOptions = {
        showOwner: true,
        showType: true,
        showContent: false,
        showBcs: false,
        showDisplay: false,
        showStorageRebate: false,
    }

    // Merge user options with defaults (user options take precedence)
    const finalOptions = { ...defaultOptions, ...userOptions }

    // Fetch object details once
    const objectFetcher = new MoveCallObjectFetcher(client, batchSize)
    const moveCallsWithDetails = await objectFetcher.fetchObjectDetails(moveCalls, finalOptions)
    // Run all validators with the same object details
    for (const validator of validators) {
        const result = validator.validate(moveCallsWithDetails, sender)
        if (result instanceof Promise) {
            await result
        }
    }
}
