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

// Load environment variables
dotenv.config();

/**
 * Simple preflight checks - only check balance and contract existence
 */
async function preflightChecks(sdk: GoTakeSDK, userAddress: string): Promise<boolean> {
    console.log('\n🔍 Running preflight checks...');
    console.log('===============================');

    try {
        // 1. Check ETH balance
        console.log('💰 Checking account balance...');
        const balance = await sdk.provider.getBalance(userAddress);
        const balanceETH = parseFloat(ethers.utils.formatEther(balance));
        const minETH = 0.001; // Minimum 0.001 ETH needed

        console.log(`   Balance: ${balanceETH.toFixed(4)} ETH`);

        if (balanceETH < minETH) {
            console.log(`   ❌ Insufficient balance, at least ${minETH} ETH needed for transactions`);
            console.log('   💰 Get test ETH: https://www.coinbase.com/faucets/base-ethereum-sepolia-faucet');
            return false;
        } else {
            console.log('   ✅ ETH balance sufficient');
        }

        // 2. Check contract deployment
        console.log('📋 Verifying VideoPayment contract...');
        await sdk.videoPayment.init();
        console.log('   ✅ VideoPayment contract initialized');

        console.log('\n✅ All preflight checks passed!');
        return true;

    } catch (error) {
        console.error('❌ Preflight check failed:', error.message);
        return false;
    }
}

/**
 * Simple content purchaser that works with the actual SDK
 */
class ContentPurchaser {
    public sdk: GoTakeSDK;

    constructor(private provider: ethers.providers.Provider, private signer: ethers.Signer) {
        // Initialize SDK with proper options
        this.sdk = new GoTakeSDK({
            provider: this.provider,
            signer: this.signer
        });
    }

    /**
     * Purchase single content with ETH
     */
    async purchaseWithETH(contentId: number): Promise<void> {
        console.log(`\n🛒 Purchasing Content ID: ${contentId} with ETH`);
        console.log('='.repeat(50));

        try {
            // Check if user already has permission
            const hasPermission = await this.sdk.videoPayment.hasViewPermission(contentId);
            if (hasPermission) {
                console.log('⚠️  You already have access to this content');
                return;
            }

            // Make the purchase
            console.log('\n💳 Initiating Purchase Transaction...');
            const result = await this.sdk.videoPayment.purchaseContent(contentId, 'ETH');

            console.log('\n✅ Purchase Successful!');
            console.log(`   Transaction Hash: ${result.transactionHash}`);
            console.log(`   Content ID: ${result.contentId}`);

            // Verify purchase
            const verifyPermission = await this.sdk.videoPayment.hasViewPermission(contentId);
            console.log(`   Purchase Verified: ${verifyPermission ? 'Yes' : 'No'}`);

        } catch (error) {
            console.error('\n❌ Purchase Failed:', error.message);
            throw error;
        }
    }

    /**
     * Purchase single content with ERC20 token
     */
    async purchaseWithToken(contentId: number, tokenAddress: string): Promise<void> {
        console.log(`\n🛒 Purchasing Content ID: ${contentId} with Token`);
        console.log('='.repeat(50));

        try {
            console.log(`   Token Address: ${tokenAddress}`);

            // Check if user already has permission
            const hasPermission = await this.sdk.videoPayment.hasViewPermission(contentId);
            if (hasPermission) {
                console.log('⚠️  You already have access to this content');
                return;
            }

            // Make the purchase
            console.log('\n💳 Initiating Token Purchase Transaction...');
            const result = await this.sdk.videoPayment.purchaseContent(contentId, 'ERC20', tokenAddress);

            console.log('\n✅ Purchase Successful!');
            console.log(`   Transaction Hash: ${result.transactionHash}`);
            console.log(`   Content ID: ${result.contentId}`);

            // Verify purchase
            const verifyPermission = await this.sdk.videoPayment.hasViewPermission(contentId);
            console.log(`   Purchase Verified: ${verifyPermission ? 'Yes' : 'No'}`);

        } catch (error) {
            console.error('\n❌ Purchase Failed:', error.message);
            throw error;
        }
    }

    /**
     * Check content information
     */
    async checkContent(contentId: number): Promise<void> {
        console.log(`\n📋 Content Information for ID: ${contentId}`);
        console.log('='.repeat(50));

        try {
            // Check user permissions
            const hasPermission = await this.sdk.videoPayment.hasViewPermission(contentId);
            console.log(`   Your Access: ${hasPermission ? 'Yes ✅' : 'No ❌'}`);

            if (hasPermission) {
                const permissions = await this.sdk.videoPayment.getMyPermissions(contentId);
                console.log(`   Remaining Views: ${permissions.remainingViews.toNumber()}`);
                console.log(`   Purchase Time: ${new Date(permissions.purchaseTime.toNumber() * 1000).toLocaleString()}`);
                console.log(`   Permission Valid: ${permissions.isValid ? 'Yes' : 'No'}`);
            }

        } catch (error) {
            console.error('❌ Failed to get content info:', error.message);
            throw error;
        }
    }

    /**
     * Batch purchase multiple content items
     */
    async batchPurchase(contentIds: number[]): Promise<void> {
        console.log(`\n🛒 Batch Purchase: ${contentIds.length} items`);
        console.log('='.repeat(50));

        try {
            const result = await this.sdk.videoPayment.batchPurchaseContent(contentIds, 'ETH');

            console.log('\n✅ Batch Purchase Successful!');
            console.log(`   Transaction Hash: ${result.transactionHash}`);
            console.log(`   Content IDs: ${contentIds.join(', ')}`);

            // Verify purchases
            let successCount = 0;
            for (const contentId of contentIds) {
                const hasPermission = await this.sdk.videoPayment.hasViewPermission(contentId);
                if (hasPermission) {
                    successCount++;
                }
            }

            console.log(`\n📊 Batch Purchase Summary:`);
            console.log(`   Total Items: ${contentIds.length}`);
            console.log(`   Successful: ${successCount}`);
            console.log(`   Success Rate: ${((successCount / contentIds.length) * 100).toFixed(1)}%`);

        } catch (error) {
            console.error('\n❌ Batch Purchase Failed:', error.message);
            throw error;
        }
    }
}

async function main() {
    console.log('🛒 GoTake Content Purchaser');
    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);

        console.log(`🌐 Connected to: ${PROVIDER_URL}`);
        console.log(`👤 Wallet Address: ${signer.address}`);

        // Check wallet balance
        const balance = await provider.getBalance(signer.address);
        console.log(`💰 Wallet Balance: ${ethers.utils.formatEther(balance)} ETH\n`);

        if (balance.lt(ethers.utils.parseEther('0.001'))) {
            console.log('⚠️  Warning: Low ETH balance, may not be sufficient for transactions');
        }

        const purchaser = new ContentPurchaser(provider, signer);

        // Run preflight checks
        const preflightPassed = await preflightChecks(purchaser.sdk, signer.address);
        if (!preflightPassed) {
            console.log('\n❌ Preflight checks failed. Please resolve the issues above before continuing.');
            process.exit(1);
        }

        // Parse command line arguments
        const command = process.argv[2];

        switch (command) {
            case 'buy':
                // Purchase single content with ETH
                const contentId = parseInt(process.argv[3]);
                if (!contentId) {
                    console.error('Usage: npm run purchase-content buy <contentId>');
                    process.exit(1);
                }
                await purchaser.purchaseWithETH(contentId);
                break;

            case 'token':
                // Purchase with ERC20 token
                const tokenContentId = parseInt(process.argv[3]);
                const tokenAddress = process.argv[4];
                if (!tokenContentId || !tokenAddress) {
                    console.error('Usage: npm run purchase-content token <contentId> <tokenAddress>');
                    process.exit(1);
                }
                await purchaser.purchaseWithToken(tokenContentId, tokenAddress);
                break;

            case 'check':
                // Check content information
                const checkContentId = parseInt(process.argv[3]);
                if (!checkContentId) {
                    console.error('Usage: npm run purchase-content check <contentId>');
                    process.exit(1);
                }
                await purchaser.checkContent(checkContentId);
                break;

            case 'batch':
                // Batch purchase multiple content
                const contentIds = process.argv.slice(3).map(id => parseInt(id));
                if (contentIds.length === 0) {
                    console.error('Usage: npm run purchase-content batch <contentId1> [contentId2] ...');
                    process.exit(1);
                }
                await purchaser.batchPurchase(contentIds);
                break;

            default:
                console.log('Available commands:');
                console.log('  buy <id>                         - Purchase content with ETH');
                console.log('  token <id> <tokenAddress>        - Purchase content with ERC20 token');
                console.log('  check <id>                       - Check content information');
                console.log('  batch <id1> [id2] ...            - Batch purchase multiple content');
                console.log('\nExamples:');
                console.log('  npm run purchase-content buy 1');
                console.log('  npm run purchase-content token 1 0x4D1F4F683AB7122fBb77aB544aC03c5678acA968');
                console.log('  npm run purchase-content check 1');
                console.log('  npm run purchase-content batch 1 2 3');
                break;
        }

    } catch (error) {
        console.error('❌ Purchase operation failed:', error);
        console.error('Details:', error.message);
        process.exit(1);
    }
}

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