/**
 * @file tokenization.service.ts
 * @notice SolaceNet capability service for tokenization
 */

import { requireCapability } from '@/shared/solacenet/sdk';
import { EntitlementCheckContext } from '@/shared/solacenet/types';

export interface TokenizationRequest {
    underlyingAsset: string;
    amount: string;
    issuer: string;
    reserveId: string;
    recipient?: string;
    regulatoryFlags?: Record<string, any>;
}

export interface TokenizationResult {
    requestId: string;
    fabricTokenId: string;
    fabricTxHash: string;
    besuTokenAddress: string;
    besuTxHash: string;
    status: string;
}

export class TokenizationService {
    private fireflyApiUrl: string;
    private tokenizationWorkflowUrl: string;

    constructor(fireflyApiUrl: string, tokenizationWorkflowUrl: string) {
        this.fireflyApiUrl = fireflyApiUrl;
        this.tokenizationWorkflowUrl = tokenizationWorkflowUrl;
    }

    /**
     * Mint tokenized asset
     * Requires: tokenization.mint capability
     */
    async mintToken(
        request: TokenizationRequest,
        context: EntitlementCheckContext
    ): Promise<TokenizationResult> {
        // Check SolaceNet capability
        await requireCapability('tokenization.mint', context);

        // Generate request ID
        const requestId = this.generateRequestId();

        // Call FireFly tokenization workflow
        const response = await fetch(`${this.tokenizationWorkflowUrl}/api/tokenization/mint`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                requestId,
                ...request
            })
        });

        if (!response.ok) {
            throw new Error('Tokenization mint failed');
        }

        return await response.json();
    }

    /**
     * Transfer tokenized asset
     * Requires: tokenization.transfer capability
     */
    async transferToken(
        tokenId: string,
        from: string,
        to: string,
        amount: string,
        context: EntitlementCheckContext
    ): Promise<{ txHash: string }> {
        // Check SolaceNet capability
        await requireCapability('tokenization.transfer', context);

        // Call FireFly tokenization workflow
        const response = await fetch(`${this.tokenizationWorkflowUrl}/api/tokenization/transfer`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                tokenId,
                from,
                to,
                amount
            })
        });

        if (!response.ok) {
            throw new Error('Tokenization transfer failed');
        }

        return await response.json();
    }

    /**
     * Redeem tokenized asset
     * Requires: tokenization.redeem capability
     */
    async redeemToken(
        tokenId: string,
        redeemer: string,
        amount: string,
        context: EntitlementCheckContext
    ): Promise<{ fabricTxHash: string; besuTxHash: string }> {
        // Check SolaceNet capability
        await requireCapability('tokenization.redeem', context);

        // Call FireFly tokenization workflow
        const response = await fetch(`${this.tokenizationWorkflowUrl}/api/tokenization/redeem`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                tokenId,
                redeemer,
                amount
            })
        });

        if (!response.ok) {
            throw new Error('Tokenization redemption failed');
        }

        return await response.json();
    }

    /**
     * Get tokenization status
     */
    async getStatus(requestId: string, context: EntitlementCheckContext): Promise<TokenizationResult> {
        // Check SolaceNet capability (viewer level)
        await requireCapability('tokenization.view', context);

        const response = await fetch(`${this.tokenizationWorkflowUrl}/api/tokenization/status/${requestId}`, {
            method: 'GET',
            headers: { 'Content-Type': 'application/json' }
        });

        if (!response.ok) {
            throw new Error('Failed to get tokenization status');
        }

        return await response.json();
    }

    /**
     * Get tokenized asset details
     */
    async getTokenDetails(
        tokenId: string,
        context: EntitlementCheckContext
    ): Promise<any> {
        // Check SolaceNet capability
        await requireCapability('tokenization.view', context);

        const response = await fetch(`${this.tokenizationWorkflowUrl}/api/tokenization/token/${tokenId}`, {
            method: 'GET',
            headers: { 'Content-Type': 'application/json' }
        });

        if (!response.ok) {
            throw new Error('Failed to get token details');
        }

        return await response.json();
    }

    /**
     * Generate request ID
     */
    private generateRequestId(): string {
        return `TOKEN-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    }
}

// Export singleton instance
export const tokenizationService = new TokenizationService(
    process.env.FIREFLY_API_URL || 'http://localhost:5000',
    process.env.TOKENIZATION_WORKFLOW_URL || 'http://localhost:3001'
);
