/**
 * @file institutional-identity.ts
 * @notice Indy identity service for institutional credentials
 */

export interface DIDDocument {
    did: string;
    publicKey: string[];
    service: Array<{
        id: string;
        type: string;
        serviceEndpoint: string;
    }>;
}

export interface VerifiableCredential {
    '@context': string[];
    id: string;
    type: string[];
    issuer: string;
    issuanceDate: string;
    credentialSubject: {
        id: string;
        claims: Record<string, any>;
    };
    proof: {
        type: string;
        created: string;
        proofPurpose: string;
        verificationMethod: string;
        jws: string;
    };
}

export interface IdentityRequest {
    institutionName: string;
    institutionType: 'central_bank' | 'commercial_bank' | 'ifi' | 'other';
    jurisdiction: string;
    regulatoryLicense?: string;
}

export class InstitutionalIdentityService {
    private indyApiUrl: string;
    private indyPoolName: string;

    constructor(indyApiUrl: string, indyPoolName: string = 'dbis-pool') {
        this.indyApiUrl = indyApiUrl;
        this.indyPoolName = indyPoolName;
    }

    /**
     * Issue DID for institution
     */
    async issueDID(request: IdentityRequest): Promise<DIDDocument> {
        try {
            const response = await fetch(`${this.indyApiUrl}/api/v1/ledger/did`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    alias: request.institutionName,
                    role: 'TRUSTEE',
                    seed: undefined // In production, use secure seed generation
                })
            });

            if (!response.ok) {
                throw new Error('DID issuance failed');
            }

            const result = await response.json();
            return result.didDocument;
        } catch (error: any) {
            throw new Error(`DID issuance error: ${error.message}`);
        }
    }

    /**
     * Issue Verifiable Credential
     */
    async issueCredential(
        did: string,
        credentialType: 'KYC' | 'AML' | 'RegulatoryApproval' | 'BankLicense',
        claims: Record<string, any>
    ): Promise<VerifiableCredential> {
        try {
            const response = await fetch(`${this.indyApiUrl}/api/v1/credentials/issue`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    did,
                    credentialType,
                    claims,
                    schemaId: this.getSchemaId(credentialType)
                })
            });

            if (!response.ok) {
                throw new Error('Credential issuance failed');
            }

            return await response.json();
        } catch (error: any) {
            throw new Error(`Credential issuance error: ${error.message}`);
        }
    }

    /**
     * Verify credential
     */
    async verifyCredential(credential: VerifiableCredential): Promise<{ valid: boolean; error?: string }> {
        try {
            const response = await fetch(`${this.indyApiUrl}/api/v1/credentials/verify`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ credential })
            });

            if (!response.ok) {
                return { valid: false, error: 'Verification failed' };
            }

            const result = await response.json();
            return { valid: result.valid, error: result.error };
        } catch (error: any) {
            return { valid: false, error: error.message };
        }
    }

    /**
     * Get credential for institution
     */
    async getInstitutionCredentials(did: string): Promise<VerifiableCredential[]> {
        try {
            const response = await fetch(`${this.indyApiUrl}/api/v1/credentials/${did}`, {
                method: 'GET',
                headers: { 'Content-Type': 'application/json' }
            });

            if (!response.ok) {
                return [];
            }

            return await response.json();
        } catch (error) {
            console.error('Get credentials error:', error);
            return [];
        }
    }

    /**
     * Check if institution has required credentials for tokenization
     */
    async checkTokenizationEligibility(did: string): Promise<{
        eligible: boolean;
        missingCredentials: string[];
        tier: number;
    }> {
        const credentials = await this.getInstitutionCredentials(did);

        const requiredCredentials = ['KYC', 'AML', 'RegulatoryApproval'];
        const missing: string[] = [];

        for (const required of requiredCredentials) {
            const hasCredential = credentials.some(
                (vc: VerifiableCredential) => vc.type.includes(required)
            );
            if (!hasCredential) {
                missing.push(required);
            }
        }

        // Determine tier based on credentials
        let tier = 0;
        if (credentials.some((vc: VerifiableCredential) => vc.type.includes('BankLicense'))) {
            tier = 3; // Highest tier
        } else if (missing.length === 0) {
            tier = 2; // Full compliance
        } else if (missing.length === 1) {
            tier = 1; // Partial compliance
        }

        return {
            eligible: missing.length === 0,
            missingCredentials: missing,
            tier
        };
    }

    /**
     * Get schema ID for credential type
     */
    private getSchemaId(credentialType: string): string {
        const schemaMap: Record<string, string> = {
            'KYC': 'KYCSchema:1.0',
            'AML': 'AMLSchema:1.0',
            'RegulatoryApproval': 'RegulatorySchema:1.0',
            'BankLicense': 'BankLicenseSchema:1.0'
        };

        return schemaMap[credentialType] || 'GenericSchema:1.0';
    }
}
