/**
 * @file status-api.ts
 * @notice Status API for bridge transfer tracking
 */

import { ethers } from 'ethers';
import { WorkflowEngine, TransferStatus } from './workflow-engine';
import { BridgeEscrowVault } from '../../contracts/bridge/interop';

export interface TransferStatusResponse {
    transferId: string;
    status: TransferStatus;
    depositor: string;
    asset: string;
    amount: string;
    destinationType: number;
    destinationData: string;
    timestamp: number;
    timeout: number;
    refunded: boolean;
    executionData?: {
        txHash?: string;
        blockNumber?: number;
        finalityBlocks?: number;
        xrplTxHash?: string;
        fabricTxId?: string;
        error?: string;
    };
    route?: {
        chainId: number;
        chainName: string;
        provider: string;
        estimatedTime: number;
        fee: string;
        healthScore: number;
    };
    isRefundable: boolean;
    refundDeadline?: number;
}

export class StatusAPI {
    private workflowEngine: WorkflowEngine;
    private provider: ethers.Provider;
    private escrowVault: ethers.Contract;

    constructor(
        workflowEngine: WorkflowEngine,
        rpcUrl: string,
        escrowVaultAddress: string,
        escrowAbi: any[]
    ) {
        this.workflowEngine = workflowEngine;
        this.provider = new ethers.JsonRpcProvider(rpcUrl);
        this.escrowVault = new ethers.Contract(escrowVaultAddress, escrowAbi, this.provider);
    }

    /**
     * Get transfer status
     */
    async getStatus(transferId: string): Promise<TransferStatusResponse> {
        // Get on-chain transfer data
        const transfer = await this.escrowVault.getTransfer(transferId);
        
        // Get workflow status
        const workflowStatus = this.workflowEngine.getStatus(transferId);
        
        // Check refund eligibility
        const isRefundable = await this.workflowEngine.isRefundable(transferId);
        
        // Calculate refund deadline
        const refundDeadline = transfer.timestamp + transfer.timeout;

        return {
            transferId,
            status: workflowStatus || this.mapOnChainStatus(transfer.status),
            depositor: transfer.depositor,
            asset: transfer.asset,
            amount: transfer.amount.toString(),
            destinationType: Number(transfer.destinationType),
            destinationData: ethers.toUtf8String(transfer.destinationData),
            timestamp: Number(transfer.timestamp),
            timeout: Number(transfer.timeout),
            refunded: transfer.refunded,
            isRefundable,
            refundDeadline: Number(refundDeadline)
        };
    }

    /**
     * Get status for multiple transfers
     */
    async getBatchStatus(transferIds: string[]): Promise<TransferStatusResponse[]> {
        return Promise.all(transferIds.map(id => this.getStatus(id)));
    }

    /**
     * Get transfers by depositor
     */
    async getTransfersByDepositor(
        depositor: string,
        limit: number = 50,
        offset: number = 0
    ): Promise<TransferStatusResponse[]> {
        // This would typically query a database or indexer
        // For now, return empty array - implement with event indexing
        return [];
    }

    /**
     * Get transfers by status
     */
    async getTransfersByStatus(
        status: TransferStatus,
        limit: number = 50,
        offset: number = 0
    ): Promise<TransferStatusResponse[]> {
        // This would typically query a database or indexer
        // For now, return empty array - implement with event indexing
        return [];
    }

    /**
     * Map on-chain status to workflow status
     */
    private mapOnChainStatus(status: number): TransferStatus {
        const statusMap: Record<number, TransferStatus> = {
            0: TransferStatus.INITIATED,
            1: TransferStatus.DEPOSIT_CONFIRMED,
            2: TransferStatus.ROUTE_SELECTED,
            3: TransferStatus.EXECUTING,
            4: TransferStatus.DESTINATION_SENT,
            5: TransferStatus.FINALITY_CONFIRMED,
            6: TransferStatus.COMPLETED,
            7: TransferStatus.FAILED,
            8: TransferStatus.REFUND_PENDING,
            9: TransferStatus.REFUNDED
        };

        return statusMap[status] || TransferStatus.INITIATED;
    }
}
