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

// Removed unused interfaces to fix linting warnings

interface ContentManagerOptions {
    batchSize?: number;
    confirmActions?: boolean;
    dryRun?: boolean;
}

// Removed unused ContentBatchConfig interface

interface ContentSummary {
    contentId: number;
    status: string;
    error?: string;
}

class ContentManager {
    private sdk: GoTakeSDK;
    private options: ContentManagerOptions;

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

        this.options = {
            batchSize: 10,
            confirmActions: true,
            dryRun: false,
            ...options
        };
    }

    async checkAdminRights(): Promise<void> {
        console.log('\n🔐 Checking Admin Rights');
        console.log('========================');

        try {
            await this.sdk.videoPayment.init();
            console.log('\n✅ Admin rights verified - you can manage content');

        } catch (error) {
            console.error('\n❌ Admin rights check failed:', error.message);
            throw error;
        }
    }

    async createContent(
        contentId: number,
        priceETH: string,
        viewCount: number,
        durationHours: number,
        isActive: boolean = true
    ): Promise<void> {
        console.log(`\n📝 Creating Content ID: ${contentId}`);
        console.log('='.repeat(40));

        try {
            const priceWei = ethers.utils.parseEther(priceETH);
            const durationSeconds = durationHours * 3600;

            console.log('\nContent Configuration:');
            console.log(`   Content ID: ${contentId}`);
            console.log(`   Price: ${priceETH} ETH (${priceWei.toString()} wei)`);
            console.log(`   View Count: ${viewCount}`);
            console.log(`   Duration: ${durationHours} hours (${durationSeconds} seconds)`);
            console.log(`   Active: ${isActive ? 'Yes' : 'No'}`);

            if (this.options.dryRun) {
                console.log('\n🧪 DRY RUN MODE - No actual transaction will be sent');
                return;
            }

            console.log('\n💾 Creating content...');

            const txHash = await this.sdk.videoPayment.setContentConfig({
                contentId,
                nativePrice: priceETH,
                defaultViewCount: viewCount,
                viewDuration: durationSeconds,
                isActive
            });

            console.log(`✅ Content created successfully!`);
            console.log(`   Transaction Hash: ${txHash}`);
            console.log(`   Content ID: ${contentId}`);

            // Wait for transaction confirmation
            console.log('\n⏳ Waiting for transaction confirmation...');
            const receipt = await this.provider.waitForTransaction(txHash);
            console.log(`✅ Transaction confirmed in block ${receipt.blockNumber}`);

        } catch (error) {
            console.error(`❌ Failed to create content ${contentId}:`, error.message);
            throw error;
        }
    }

    async batchCreateContent(configurations: Array<{
        contentId: number;
        priceETH: string;
        viewCount: number;
        durationHours: number;
        isActive?: boolean;
    }>): Promise<void> {
        console.log(`\n📦 Batch Creating ${configurations.length} Content Items`);
        console.log('='.repeat(60));

        if (configurations.length === 0) {
            console.log('❌ No configurations provided');
            return;
        }

        // Prepare batch data
        const contentIds = configurations.map(c => c.contentId);
        const nativePrices = configurations.map(c => c.priceETH);
        const defaultViewCounts = configurations.map(c => c.viewCount);
        const viewDurations = configurations.map(c => c.durationHours * 3600);
        const isActiveArray = configurations.map(c => c.isActive ?? true);

        console.log('Batch Configuration Summary:');
        configurations.forEach((config, index) => {
            console.log(`   ${index + 1}. Content ${config.contentId}: ${config.priceETH} ETH, ${config.viewCount} views, ${config.durationHours}h, ${config.isActive ? 'Active' : 'Inactive'}`);
        });

        if (this.options.dryRun) {
            console.log('\n🧪 DRY RUN MODE - No actual transaction will be sent');
            return;
        }

        try {
            console.log('\n💾 Executing batch content creation...');

            const txHash = await this.sdk.videoPayment.batchSetContentConfig({
                contentIds,
                nativePrices,
                defaultViewCounts,
                viewDurations,
                isActiveArray
            });

            console.log(`✅ Batch content creation successful!`);
            console.log(`   Transaction Hash: ${txHash}`);
            console.log(`   Created ${configurations.length} content items`);

            // Wait for transaction confirmation
            console.log('\n⏳ Waiting for transaction confirmation...');
            const receipt = await this.provider.waitForTransaction(txHash);
            console.log(`✅ Transaction confirmed in block ${receipt.blockNumber}`);

        } catch (error) {
            console.error('❌ Batch content creation failed:', error.message);
            throw error;
        }
    }

    async updateContentPrice(contentId: number, newPriceETH: string): Promise<void> {
        console.log(`\n💰 Updating Price for Content ID: ${contentId}`);
        console.log('='.repeat(50));

        try {
            console.log(`New Price: ${newPriceETH} ETH`);

            if (this.options.dryRun) {
                console.log('\n🧪 DRY RUN MODE - No actual transaction will be sent');
                return;
            }

            console.log('\n💾 Updating price...');

            const txHash = await this.sdk.videoPayment.updateContentPrice(
                contentId,
                ethers.utils.parseEther(newPriceETH)
            );

            console.log(`✅ Price updated successfully!`);
            console.log(`   Transaction Hash: ${txHash}`);
            console.log(`   Content ID: ${contentId}`);
            console.log(`   New Price: ${newPriceETH} ETH`);

        } catch (error) {
            console.error(`❌ Failed to update price for content ${contentId}:`, error.message);
            throw error;
        }
    }

    async bulkUpdatePrices(updates: Array<{ contentId: number; newPriceETH: string }>): Promise<void> {
        console.log(`\n💰 Bulk Price Update (${updates.length} items)`);
        console.log('='.repeat(50));

        console.log('Price Update Summary:');
        updates.forEach((update, index) => {
            console.log(`   ${index + 1}. Content ${update.contentId}: ${update.newPriceETH} ETH`);
        });

        if (this.options.dryRun) {
            console.log('\n🧪 DRY RUN MODE - No actual transactions will be sent');
            return;
        }

        let successful = 0;
        let failed = 0;

        for (const update of updates) {
            try {
                console.log(`\n💾 Updating Content ${update.contentId}...`);
                await this.updateContentPrice(update.contentId, update.newPriceETH);
                successful++;
                console.log(`✅ Success`);
            } catch (error) {
                console.error(`❌ Failed: ${error.message}`);
                failed++;
            }
        }

        console.log(`\n📊 Bulk Update Results:`);
        console.log(`   Successful: ${successful}`);
        console.log(`   Failed: ${failed}`);
        console.log(`   Success Rate: ${((successful / updates.length) * 100).toFixed(1)}%`);
    }

    async listContentStatus(contentIds: number[]): Promise<ContentSummary[]> {
        console.log(`\n📋 Content Status Check (${contentIds.length} items)`);
        console.log('='.repeat(60));

        const summaries: ContentSummary[] = [];

        for (const contentId of contentIds) {
            try {
                // Simple status check - just verify if we can access the content
                console.log(`Checking Content ${contentId}...`);
                await this.sdk.videoPayment.init();

                summaries.push({
                    contentId,
                    status: 'Accessible'
                });
            } catch (error) {
                console.error(`❌ Failed to check content ${contentId}:`, error.message);
                summaries.push({
                    contentId,
                    status: 'Error',
                    error: error.message
                });
            }
        }

        // Display content table
        this.displayContentTable(summaries);
        return summaries;
    }

    private displayContentTable(summaries: ContentSummary[]): void {
        console.log('\n📊 Content Status Table:');
        console.log('┌────────────┬──────────────┐');
        console.log('│ Content ID │       Status │');
        console.log('├────────────┼──────────────┤');

        summaries.forEach(summary => {
            const contentId = summary.contentId.toString().padStart(10);
            const status = summary.status.padStart(12);

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

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

        // Summary statistics
        const accessibleCount = summaries.filter(s => s.status === 'Accessible').length;
        const errorCount = summaries.length - accessibleCount;

        console.log(`\n📈 Summary Statistics:`);
        console.log(`   Total Content: ${summaries.length}`);
        console.log(`   Accessible: ${accessibleCount} (${((accessibleCount / summaries.length) * 100).toFixed(1)}%)`);
        console.log(`   Errors: ${errorCount} (${((errorCount / summaries.length) * 100).toFixed(1)}%)`);
    }

    async generateContentReport(contentIds: number[]): Promise<void> {
        console.log('\n📊 Generating Content Report');
        console.log('='.repeat(50));

        const summaries = await this.listContentStatus(contentIds);

        console.log('\n📈 Report Analysis:');
        const accessibleContent = summaries.filter(s => s.status === 'Accessible');
        const errorContent = summaries.filter(s => s.status === 'Error');

        if (accessibleContent.length > 0) {
            console.log(`\n✅ Accessible Content: ${accessibleContent.length} items`);
            accessibleContent.forEach(s => {
                console.log(`   • Content ${s.contentId}: Ready for use`);
            });
        }

        if (errorContent.length > 0) {
            console.log(`\n❌ Content with Errors: ${errorContent.length} items`);
            errorContent.forEach(s => {
                console.log(`   • Content ${s.contentId}: ${s.error}`);
            });
        }

        console.log('\n💡 Recommendations:');
        if (errorContent.length > 0) {
            console.log(`   • Review and fix ${errorContent.length} content items with errors`);
        }
        if (accessibleContent.length > 0) {
            console.log(`   • ${accessibleContent.length} content items are ready for use`);
        }

        console.log('\n✅ Report generation complete');
    }
}

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

        // Parse command line options
        const isDryRun = process.argv.includes('--dry-run');
        const skipConfirm = process.argv.includes('--no-confirm');

        const manager = new ContentManager(provider, signer, {
            dryRun: isDryRun,
            confirmActions: !skipConfirm
        });

        // Check admin rights first
        await manager.checkAdminRights();

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

        switch (command) {
            case 'create':
                // Create single content
                const contentId = parseInt(process.argv[3]);
                const price = process.argv[4];
                const views = parseInt(process.argv[5]);
                const hours = parseInt(process.argv[6]);
                const active = process.argv[7] !== 'false';

                if (!contentId || !price || !views || !hours) {
                    console.error('Usage: npm run manage-content create <contentId> <priceETH> <viewCount> <durationHours> [active]');
                    process.exit(1);
                }

                await manager.createContent(contentId, price, views, hours, active);
                break;

            case 'batch-create':
                // Batch create content from configuration
                const batchConfig = [
                    { contentId: 10, priceETH: '0.001', viewCount: 5, durationHours: 24 },
                    { contentId: 11, priceETH: '0.002', viewCount: 10, durationHours: 48 },
                    { contentId: 12, priceETH: '0.005', viewCount: 20, durationHours: 72 }
                ];

                await manager.batchCreateContent(batchConfig);
                break;

            case 'update-price':
                // Update single content price
                const updateContentId = parseInt(process.argv[3]);
                const newPrice = process.argv[4];

                if (!updateContentId || !newPrice) {
                    console.error('Usage: npm run manage-content update-price <contentId> <newPriceETH>');
                    process.exit(1);
                }

                await manager.updateContentPrice(updateContentId, newPrice);
                break;

            case 'list':
                // List all content
                const defaultContentIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
                await manager.listContentStatus(defaultContentIds);
                break;

            case 'list-range':
                // List content in range
                const startId = parseInt(process.argv[3]);
                const endId = parseInt(process.argv[4]);

                if (!startId || !endId) {
                    console.error('Usage: npm run manage-content list-range <startId> <endId>');
                    process.exit(1);
                }

                const rangeIds = Array.from({ length: endId - startId + 1 }, (_, i) => startId + i);
                await manager.listContentStatus(rangeIds);
                break;

            case 'bulk-price-update':
                // Bulk update prices
                const priceUpdates = [
                    { contentId: 1, newPriceETH: '0.001' },
                    { contentId: 2, newPriceETH: '0.002' },
                    { contentId: 3, newPriceETH: '0.003' }
                ];

                await manager.bulkUpdatePrices(priceUpdates);
                break;

            case 'report':
                // Generate comprehensive report
                const reportContentIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
                await manager.generateContentReport(reportContentIds);
                break;

            default:
                console.log('Available commands:');
                console.log('  create <id> <price> <views> <hours> [active]    - Create single content');
                console.log('  batch-create                                    - Create multiple content (predefined)');
                console.log('  update-price <id> <newPrice>                   - Update content price');
                console.log('  list                                            - List all content (default IDs)');
                console.log('  list-range <start> <end>                        - List content in ID range');
                console.log('  bulk-price-update                               - Bulk update prices (predefined)');
                console.log('  report                                          - Generate comprehensive report');
                console.log('\nOptions:');
                console.log('  --dry-run                                       - Simulate operations without executing');
                console.log('  --no-confirm                                    - Skip confirmation prompts');
                console.log('\nExamples:');
                console.log('  npm run manage-content create 1 0.01 10 24 true');
                console.log('  npm run manage-content update-price 1 0.02');
                console.log('  npm run manage-content list-range 1 20');
                console.log('  npm run manage-content report --dry-run');
                break;
        }

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

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