import { ethers } from 'ethers';
import { GoTakeSDK } from '../src';
import * as dotenv from 'dotenv';

// Load environment variables
dotenv.config();

interface PermissionSummary {
    contentId: number;
    hasPermission: boolean;
    purchaseTime?: Date;
    remainingViews: number;
    isExpired: boolean;
}

class PermissionChecker {
    private sdk: GoTakeSDK;

    constructor(provider: ethers.providers.Provider, private signer: ethers.Signer) {
        this.sdk = new GoTakeSDK({
            provider: provider,
            signer: signer
        });
    }

    async checkUserPermissions(userAddress: string, contentIds: number[]): Promise<void> {
        console.log(`\n🔍 Checking permissions for user: ${userAddress}`);
        console.log('='.repeat(80));

        const summaries: PermissionSummary[] = [];

        // Check permissions for each content
        for (const contentId of contentIds) {
            try {
                const hasPermission = await this.sdk.videoPayment.userHasViewPermission(userAddress, contentId);

                let purchaseTime: Date | undefined;
                let remainingViews = 0;
                let isExpired = true;

                if (hasPermission) {
                    const permissions = await this.sdk.videoPayment.getUserPermissions(userAddress, contentId);
                    purchaseTime = new Date(permissions.purchaseTime.toNumber() * 1000);
                    remainingViews = permissions.remainingViews.toNumber();
                    isExpired = !permissions.isValid;
                }

                const summary: PermissionSummary = {
                    contentId,
                    hasPermission,
                    purchaseTime,
                    remainingViews,
                    isExpired
                };

                summaries.push(summary);
                this.displayPermissionDetails(summary);
            } catch (error) {
                console.error(`❌ Failed to process permissions for content ${contentId}:`, error.message);
                summaries.push({
                    contentId,
                    hasPermission: false,
                    remainingViews: 0,
                    isExpired: true
                });
            }
        }

        this.displaySummaryTable(summaries);
        this.displayRecommendations(summaries);
    }

    private displayPermissionDetails(summary: PermissionSummary): void {
        console.log(`\n📺 Content ID: ${summary.contentId}`);

        if (summary.hasPermission) {
            console.log(`   Permission: ✅ Granted`);
            console.log(`   Purchase Time: ${summary.purchaseTime?.toLocaleString()}`);
            console.log(`   Remaining Views: ${summary.remainingViews}`);
            console.log(`   Status: ${summary.isExpired ? '❌ Expired' : '✅ Active'}`);
        } else {
            console.log(`   Permission: ❌ Not granted`);
            console.log(`   Action Required: Purchase access to view this content`);
        }
    }

    private displaySummaryTable(summaries: PermissionSummary[]): void {
        console.log('\n📊 Permission Summary Table:');
        console.log('┌────────────┬──────────────┬──────────────┬──────────────┐');
        console.log('│ Content ID │   Permission │   Views Left │      Status  │');
        console.log('├────────────┼──────────────┼──────────────┼──────────────┤');

        summaries.forEach(summary => {
            const contentId = summary.contentId.toString().padStart(10);
            const permission = summary.hasPermission ? '✅ Yes'.padStart(12) : '❌ No'.padStart(11);
            const views = summary.remainingViews.toString().padStart(12);
            const status = summary.isExpired ? '❌ Expired'.padStart(11) : '✅ Active'.padStart(12);

            console.log(`│ ${contentId} │ ${permission} │ ${views} │ ${status} │`);
        });

        console.log('└────────────┴──────────────┴──────────────┴──────────────┘');
    }

    private displayRecommendations(summaries: PermissionSummary[]): void {
        console.log('\n💡 Recommendations:');

        const needToPurchase = summaries.filter(s => !s.hasPermission);
        const expiredPermissions = summaries.filter(s => s.hasPermission && s.isExpired);
        const activePermissions = summaries.filter(s => s.hasPermission && !s.isExpired);

        if (needToPurchase.length > 0) {
            console.log('\n🛒 Content Available for Purchase:');
            needToPurchase.forEach(s => {
                console.log(`   • Content ${s.contentId}: Available for purchase`);
            });

            // Batch purchase suggestion
            if (needToPurchase.length > 1) {
                console.log(`   💡 Tip: Use batch purchase to buy multiple content at once`);
                console.log(`   Command: npm run purchase-content batch ${needToPurchase.map(s => s.contentId).join(' ')}`);
            }
        }

        if (expiredPermissions.length > 0) {
            console.log('\n⏰ Expired Permissions (Repurchase Required):');
            expiredPermissions.forEach(s => {
                console.log(`   • Content ${s.contentId}: Permission expired`);
            });
        }

        if (activePermissions.length > 0) {
            console.log('\n✅ Active Permissions:');
            activePermissions.forEach(s => {
                console.log(`   • Content ${s.contentId}: ${s.remainingViews} views remaining`);
            });
        }

        // Performance suggestions
        if (activePermissions.length > 0) {
            const lowViewCounts = activePermissions.filter(s => s.remainingViews <= 1);
            if (lowViewCounts.length > 0) {
                console.log('\n⚡ Usage Alert:');
                lowViewCounts.forEach(s => {
                    console.log(`   • Content ${s.contentId}: Only ${s.remainingViews} view(s) remaining`);
                });
            }
        }
    }

    async checkMyPermissions(contentIds: number[]): Promise<void> {
        const userAddress = await this.signer.getAddress();
        await this.checkUserPermissions(userAddress, contentIds);
    }

    async bulkPermissionCheck(userAddresses: string[], contentIds: number[]): Promise<void> {
        console.log('\n👥 Bulk Permission Check');
        console.log('='.repeat(50));

        for (const userAddress of userAddresses) {
            await this.checkUserPermissions(userAddress, contentIds);
            console.log('\n' + '-'.repeat(80));
        }
    }

    async analyzeUserEngagement(userAddress: string, contentIds: number[]): Promise<void> {
        console.log(`\n📈 User Engagement Analysis for: ${userAddress}`);
        console.log('='.repeat(80));

        let totalPurchases = 0;
        let activePurchases = 0;
        let expiredPurchases = 0;
        let totalViewsRemaining = 0;

        for (const contentId of contentIds) {
            try {
                const hasPermission = await this.sdk.videoPayment.userHasViewPermission(userAddress, contentId);

                if (hasPermission) {
                    totalPurchases++;

                    const permissions = await this.sdk.videoPayment.getUserPermissions(userAddress, contentId);
                    totalViewsRemaining += permissions.remainingViews.toNumber();

                    if (permissions.isValid) {
                        activePurchases++;
                    } else {
                        expiredPurchases++;
                    }
                }
            } catch (error) {
                console.warn(`Failed to analyze content ${contentId}:`, error.message);
            }
        }

        console.log('\n📊 Engagement Statistics:');
        console.log(`   Total Purchases: ${totalPurchases}`);
        console.log(`   Active Purchases: ${activePurchases}`);
        console.log(`   Expired Purchases: ${expiredPurchases}`);
        console.log(`   Views Remaining: ${totalViewsRemaining}`);

        if (totalPurchases > 0) {
            console.log(`   Purchase Retention Rate: ${((activePurchases / totalPurchases) * 100).toFixed(1)}%`);
        }

        if (totalViewsRemaining > 0 && activePurchases > 0) {
            console.log(`   Average Views per Active Purchase: ${(totalViewsRemaining / activePurchases).toFixed(1)}`);
        }
    }

    async performanceTest(userAddress: string, contentIds: number[]): Promise<void> {
        console.log('\n⚡ Performance Test: Individual Operations');
        console.log('='.repeat(60));

        // Test individual operations
        console.time('Individual Operations');
        try {
            for (const contentId of contentIds) {
                await this.sdk.videoPayment.userHasViewPermission(userAddress, contentId);
            }
            console.timeEnd('Individual Operations');
            console.log('✅ Individual operations completed successfully');
        } catch (error) {
            console.timeEnd('Individual Operations');
            console.log('❌ Individual operations failed:', error.message);
        }
    }
}

async function main() {
    console.log('👁️  GoTake Permission Checker');
    console.log('============================\n');

    // Environment configuration
    const PROVIDER_URL = process.env.PROVIDER_URL || 'https://sepolia.base.org';
    const PRIVATE_KEY = process.env.PRIVATE_KEY;

    if (!PRIVATE_KEY) {
        console.error('❌ Please set PRIVATE_KEY environment variable');
        process.exit(1);
    }

    try {
        // Initialize provider and signer
        const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL);
        const signer = new ethers.Wallet(PRIVATE_KEY, provider);

        const checker = new PermissionChecker(provider, signer);

        // Get command line arguments
        const command = process.argv[2];
        const targetAddress = process.argv[3];

        // Default test content IDs
        const contentIds = [1, 2, 3, 4];

        switch (command) {
            case 'check':
                if (targetAddress) {
                    await checker.checkUserPermissions(targetAddress, contentIds);
                } else {
                    await checker.checkMyPermissions(contentIds);
                }
                break;

            case 'my-permissions':
                await checker.checkMyPermissions(contentIds);
                break;

            case 'analyze':
                const analyzeAddress = targetAddress || await signer.getAddress();
                await checker.analyzeUserEngagement(analyzeAddress, contentIds);
                break;

            case 'bulk':
                // Example bulk check with multiple addresses
                const addresses = process.argv.slice(3);
                if (addresses.length === 0) {
                    console.error('Usage: npm run check-permissions bulk <address1> [address2] ...');
                    process.exit(1);
                }
                await checker.bulkPermissionCheck(addresses, contentIds);
                break;

            case 'single':
                // Check single content for current user
                const singleContentId = parseInt(process.argv[3]);
                if (!singleContentId) {
                    console.error('Usage: npm run check-permissions single <contentId>');
                    process.exit(1);
                }
                await checker.checkMyPermissions([singleContentId]);
                break;

            case 'performance':
                // Performance test
                const testAddress = targetAddress || await signer.getAddress();
                await checker.performanceTest(testAddress, contentIds);
                break;

            default:
                console.log('Available commands:');
                console.log('  check [address]         - Check permissions (current user if no address)');
                console.log('  my-permissions          - Check current user permissions');
                console.log('  analyze [address]       - Analyze user engagement');
                console.log('  bulk <addr1> [addr2]... - Bulk check multiple users');
                console.log('  single <contentId>      - Check single content for current user');
                console.log('  performance [address]   - Test individual operations');
                console.log('\nExamples:');
                console.log('  npm run check-permissions check');
                console.log('  npm run check-permissions check 0x742d35Cc6638C0532925a3b8A39c309b64D0b76b');
                console.log('  npm run check-permissions analyze');
                console.log('  npm run check-permissions single 1');
                console.log('  npm run check-permissions performance');
                break;
        }

    } catch (error) {
        console.error('❌ Permission check failed:', error);
        process.exit(1);
    }
}

// Run the script
if (require.main === module) {
    main().catch(console.error);
} 