// PaperclipChain Staking Interface
// Handles all staking-related functionality in the wallet

const { ipcRenderer } = require('electron');

class StakingManager {
    constructor() {
        this.validators = [];
        this.stakingInfo = null;
        this.totalStaked = 0;
        this.pendingRewards = 0;
        this.refreshInterval = null;
    }

    async init() {
        console.log('Initializing staking manager...');
        await this.loadStakingData();
        this.setupEventHandlers();
        this.startAutoRefresh();
    }

    async loadStakingData() {
        try {
            // Load validators
            this.validators = await ipcRenderer.invoke('paperclip-get-validators');
            
            // Load total staked
            this.totalStaked = await ipcRenderer.invoke('paperclip-get-total-staked');
            
            // Load user staking info if wallet is selected  
            if (ClipsWallet.addressList.length > 0) {
                const currentAddress = ClipsWallet.addressList[0]; // Use first wallet as current
                this.stakingInfo = await ipcRenderer.invoke('paperclip-get-staking-info', currentAddress);
                this.pendingRewards = await ipcRenderer.invoke('paperclip-get-staking-rewards', currentAddress);
            }
            
            this.updateUI();
        } catch (error) {
            console.error('Failed to load staking data:', error);
            this.showError('Failed to load staking data: ' + error.message);
        }
    }

    updateUI() {
        // Update overview cards
        $('#totalStakedAmount').text(this.formatClips(this.totalStaked));
        $('#pendingRewards').text(this.formatClips(this.pendingRewards));
        $('#activeValidators').text(this.validators.filter(v => v.active).length);
        
        // Update validators table
        this.updateValidatorsTable();
        
        // Update progress bars
        this.updateProgressBars();
    }

    updateValidatorsTable() {
        const tbody = $('#validatorsTableBody');
        tbody.empty();
        
        this.validators.forEach(validator => {
            const apy = this.calculateValidatorAPY(validator);
            const userStake = this.getUserStakeForValidator(validator.address);
            const status = validator.active ? 
                '<span class="badge badge-success">Active</span>' : 
                '<span class="badge badge-danger">Inactive</span>';
            
            const row = `
                <tr data-validator="${validator.address}">
                    <td>
                        <div class="validator-info">
                            <strong>${validator.address.substring(0, 12)}...</strong>
                            <br><small class="text-muted">${validator.address}</small>
                        </div>
                    </td>
                    <td>${status}</td>
                    <td>${this.formatClips(validator.stakedAmount || 0)}</td>
                    <td>${this.formatClips(validator.delegatedAmount || 0)}</td>
                    <td>${(validator.commission / 100).toFixed(2)}%</td>
                    <td>~${apy.toFixed(2)}%</td>
                    <td>${this.formatClips(userStake)}</td>
                    <td>
                        <div class="btn-group-sm">
                            <button class="btn btn-sm btn-clips btn-delegate" data-validator="${validator.address}" ${!validator.active ? 'disabled' : ''}>
                                Delegate
                            </button>
                            ${userStake > 0 ? `<button class="btn btn-sm btn-warning btn-undelegate" data-validator="${validator.address}">Undelegate</button>` : ''}
                        </div>
                    </td>
                </tr>
            `;
            tbody.append(row);
        });
        
        // Initialize DataTable if not already initialized
        if (!$.fn.DataTable.isDataTable('#validatorsTable')) {
            $('#validatorsTable').DataTable({
                pageLength: 10,
                responsive: true,
                order: [[2, 'desc']] // Sort by self stake desc
            });
        } else {
            $('#validatorsTable').DataTable().draw();
        }
    }

    updateProgressBars() {
        // Calculate total network stake percentage (mock calculation)
        const networkSupply = 1000000000; // 1B CLIPS total supply (mock)
        const stakedPercent = (this.totalStaked / networkSupply) * 100;
        $('#totalStakedProgress').css('width', Math.min(stakedPercent, 100) + '%');
        
        // Update rewards progress (mock)
        const rewardsPercent = Math.min((this.pendingRewards / 1000) * 100, 100);
        $('#rewardsProgress').css('width', rewardsPercent + '%');
    }

    setupEventHandlers() {
        // Navigation
        $('#mainNavBtnStaking').off('click').on('click', () => {
            this.showStakingPage();
        });

        // Refresh button
        $('#btnRefreshValidators').off('click').on('click', () => {
            this.loadStakingData();
        });

        // Quick action buttons
        $('#btnDelegate').off('click').on('click', () => {
            this.showDelegateModal();
        });

        $('#btnUndelegate').off('click').on('click', () => {
            this.showUndelegateModal();
        });

        $('#btnClaimRewards').off('click').on('click', () => {
            this.claimRewards();
        });

        $('#btnCreateValidator').off('click').on('click', () => {
            this.showCreateValidatorModal();
        });

        // Table action buttons (delegated event handling)
        $(document).off('click', '.btn-delegate').on('click', '.btn-delegate', (e) => {
            const validatorAddress = $(e.target).data('validator');
            this.showDelegateModal(validatorAddress);
        });

        $(document).off('click', '.btn-undelegate').on('click', '.btn-undelegate', (e) => {
            const validatorAddress = $(e.target).data('validator');
            this.showUndelegateModal(validatorAddress);
        });

        // Modal handlers
        $('#btnDelegateConfirm').off('click').on('click', () => {
            this.performDelegation();
        });

        $('#btnUndelegateConfirm').off('click').on('click', () => {
            this.performUndelegation();
        });

        $('#btnCreateValidatorConfirm').off('click').on('click', () => {
            this.createValidator();
        });

        // Modal cancel buttons
        $('#btnDelegateCancel, #btnUndelegateCancel, #btnCreateValidatorCancel').off('click').on('click', function() {
            $(this).closest('.modalDialog').iziModal('close');
        });
    }

    showStakingPage() {
        EthoMainGUI.renderTemplate('staking.html', {});
        this.loadStakingData();
        this.setupEventHandlers();
    }

    showDelegateModal(validatorAddress = null) {
        // Populate validator dropdown
        const validatorSelect = $('#delegateValidator');
        validatorSelect.empty().append('<option value="">Select a validator...</option>');
        
        this.validators.filter(v => v.active).forEach(validator => {
            const option = `<option value="${validator.address}">${validator.address.substring(0, 20)}... (${(validator.commission / 100).toFixed(2)}% commission)</option>`;
            validatorSelect.append(option);
        });
        
        if (validatorAddress) {
            validatorSelect.val(validatorAddress);
        }
        
        // Populate wallet dropdown
        this.populateWalletDropdown('#delegateWallet');
        
        // Update available balance
        this.updateAvailableBalance('#availableBalance');
        
        $('#dlgDelegate').iziModal('open');
    }

    showUndelegateModal(validatorAddress = null) {
        // Populate validator dropdown with only validators user has stake with
        const validatorSelect = $('#undelegateValidator');
        validatorSelect.empty().append('<option value="">Select a validator...</option>');
        
        this.validators.forEach(validator => {
            const userStake = this.getUserStakeForValidator(validator.address);
            if (userStake > 0) {
                const option = `<option value="${validator.address}">${validator.address.substring(0, 20)}... (${this.formatClips(userStake)} staked)</option>`;
                validatorSelect.append(option);
            }
        });
        
        if (validatorAddress) {
            validatorSelect.val(validatorAddress);
            this.updateYourStakeAmount(validatorAddress);
        }
        
        // Populate wallet dropdown
        this.populateWalletDropdown('#undelegateWallet');
        
        // Event handler for validator selection change
        validatorSelect.off('change').on('change', (e) => {
            this.updateYourStakeAmount(e.target.value);
        });
        
        $('#dlgUndelegate').iziModal('open');
    }

    showCreateValidatorModal() {
        // Populate wallet dropdown
        this.populateWalletDropdown('#validatorWallet');
        
        $('#dlgCreateValidator').iziModal('open');
    }

    async performDelegation() {
        try {
            const validatorAddress = $('#delegateValidator').val();
            const amount = parseFloat($('#delegateAmount').val());
            const walletAddress = $('#delegateWallet').val();
            
            if (!validatorAddress || !amount || !walletAddress || amount < 100) {
                this.showError('Please fill all fields correctly. Minimum delegation is 100 CLIPS.');
                return;
            }
            
            if (!ClipsWallet.getAddressExists(walletAddress)) {
                this.showError('Selected wallet not found.');
                return;
            }
            
            // Create delegation transaction
            const txData = {
                sender: walletAddress,
                receiver: validatorAddress,
                amount: Math.floor(amount * 1000000), // Convert to micro-CLIPS
                txType: 'delegate',
                gas: 30000,
                gasPrice: 1
            };
            
            // Sign and broadcast transaction
            const result = await this.sendStakingTransaction(txData, { address: walletAddress });
            
            if (result.success) {
                this.showSuccess('Delegation successful!');
                $('#dlgDelegate').iziModal('close');
                await this.loadStakingData();
            } else {
                this.showError('Delegation failed: ' + result.error);
            }
            
        } catch (error) {
            console.error('Delegation failed:', error);
            this.showError('Delegation failed: ' + error.message);
        }
    }

    async performUndelegation() {
        try {
            const validatorAddress = $('#undelegateValidator').val();
            const amount = parseFloat($('#undelegateAmount').val());
            const walletAddress = $('#undelegateWallet').val();
            
            if (!validatorAddress || !amount || !walletAddress || amount <= 0) {
                this.showError('Please fill all fields correctly.');
                return;
            }
            
            if (!ClipsWallet.getAddressExists(walletAddress)) {
                this.showError('Selected wallet not found.');
                return;
            }
            
            // Create undelegation transaction
            const txData = {
                sender: walletAddress,
                receiver: validatorAddress,
                amount: Math.floor(amount * 1000000), // Convert to micro-CLIPS
                txType: 'undelegate',
                gas: 30000,
                gasPrice: 1
            };
            
            // Sign and broadcast transaction
            const result = await this.sendStakingTransaction(txData, { address: walletAddress });
            
            if (result.success) {
                this.showSuccess('Undelegation successful!');
                $('#dlgUndelegate').iziModal('close');
                await this.loadStakingData();
            } else {
                this.showError('Undelegation failed: ' + result.error);
            }
            
        } catch (error) {
            console.error('Undelegation failed:', error);
            this.showError('Undelegation failed: ' + error.message);
        }
    }

    async createValidator() {
        try {
            const stakeAmount = parseFloat($('#validatorStake').val());
            const commission = parseFloat($('#validatorCommission').val());
            const walletAddress = $('#validatorWallet').val();
            
            if (!stakeAmount || !walletAddress || stakeAmount < 10000 || commission < 0 || commission > 50) {
                this.showError('Please fill all fields correctly. Minimum stake is 10,000 CLIPS, commission must be 0-50%.');
                return;
            }
            
            if (!ClipsWallet.getAddressExists(walletAddress)) {
                this.showError('Selected wallet not found.');
                return;
            }
            
            // Create validator creation transaction
            const txData = {
                sender: walletAddress,
                receiver: '',
                amount: Math.floor(stakeAmount * 1000000), // Convert to micro-CLIPS
                txType: 'create_validator',
                gas: 30000,
                gasPrice: 1,
                data: JSON.stringify({ commission: Math.floor(commission * 100) }) // Convert to basis points
            };
            
            // Sign and broadcast transaction
            const result = await this.sendStakingTransaction(txData, { address: walletAddress });
            
            if (result.success) {
                this.showSuccess('Validator created successfully!');
                $('#dlgCreateValidator').iziModal('close');
                await this.loadStakingData();
            } else {
                this.showError('Validator creation failed: ' + result.error);
            }
            
        } catch (error) {
            console.error('Validator creation failed:', error);
            this.showError('Validator creation failed: ' + error.message);
        }
    }

    async claimRewards() {
        try {
            if (ClipsWallet.addressList.length === 0) {
                this.showError('No wallet available.');
                return;
            }
            
            if (this.pendingRewards <= 0) {
                this.showError('No rewards to claim.');
                return;
            }
            
            const currentAddress = ClipsWallet.addressList[0];
            
            // Create claim rewards transaction
            const txData = {
                sender: currentAddress,
                receiver: '',
                amount: 0,
                txType: 'claim_rewards',
                gas: 30000,
                gasPrice: 1
            };
            
            // Sign and broadcast transaction
            const result = await this.sendStakingTransaction(txData, { address: currentAddress });
            
            if (result.success) {
                this.showSuccess('Rewards claimed successfully!');
                await this.loadStakingData();
            } else {
                this.showError('Claim failed: ' + result.error);
            }
            
        } catch (error) {
            console.error('Claim failed:', error);
            this.showError('Claim failed: ' + error.message);
        }
    }

    async sendStakingTransaction(txData, wallet) {
        try {
            // Get current nonce
            const nonce = await ipcRenderer.invoke('paperclip-get-nonce', wallet.address);
            txData.nonce = nonce + 1;
            
            // Sign transaction (this would use the actual wallet signing)
            const signedTx = await ClipsWallet.signTransaction(txData, wallet);
            
            // Broadcast transaction
            const result = await ipcRenderer.invoke('paperclip-broadcast-tx', signedTx);
            
            return result;
        } catch (error) {
            throw error;
        }
    }

    // Utility functions
    populateWalletDropdown(selector) {
        const walletSelect = $(selector);
        walletSelect.empty();
        
        ClipsWallet.addressList.forEach((address, index) => {
            const option = `<option value="${address}">Wallet ${index + 1} (${address.substring(0, 12)}...)</option>`;
            walletSelect.append(option);
        });
    }

    async updateAvailableBalance(selector) {
        if (ClipsWallet.addressList.length > 0) {
            try {
                const currentAddress = ClipsWallet.addressList[0];
                const balance = await ipcRenderer.invoke('paperclip-get-balance', currentAddress);
                $(selector).text(this.formatClips(balance));
            } catch (error) {
                $(selector).text('0 CLIPS');
            }
        } else {
            $(selector).text('0 CLIPS');
        }
    }

    updateYourStakeAmount(validatorAddress) {
        const userStake = this.getUserStakeForValidator(validatorAddress);
        $('#yourStakeAmount').text(this.formatClips(userStake));
    }

    getUserStakeForValidator(validatorAddress) {
        if (!this.stakingInfo || !this.stakingInfo.delegations) {
            return 0;
        }
        
        const delegation = this.stakingInfo.delegations.find(d => d.validator === validatorAddress);
        return delegation ? delegation.amount : 0;
    }

    calculateValidatorAPY(validator) {
        // Simplified APY calculation
        const baseAPY = 8.0; // 8% base APY
        const totalStake = (validator.stakedAmount || 0) + (validator.delegatedAmount || 0);
        if (totalStake === 0) return 0;
        
        // Adjust APY based on commission
        const adjustedAPY = baseAPY * (1 - (validator.commission || 0) / 10000);
        return Math.max(adjustedAPY, 0);
    }

    formatClips(microClips) {
        return (microClips / 1000000).toFixed(6) + ' CLIPS';
    }

    startAutoRefresh() {
        // Refresh staking data every 30 seconds
        this.refreshInterval = setInterval(() => {
            this.loadStakingData();
        }, 30000);
    }

    stopAutoRefresh() {
        if (this.refreshInterval) {
            clearInterval(this.refreshInterval);
            this.refreshInterval = null;
        }
    }

    showError(message) {
        iziToast.error({
            title: 'Staking Error',
            message: message,
            position: 'topRight'
        });
    }

    showSuccess(message) {
        iziToast.success({
            title: 'Staking Success',
            message: message,
            position: 'topRight'
        });
    }
}

// Initialize staking manager
const PaperclipStaking = new StakingManager();

// Export for use in other modules
if (typeof module !== 'undefined' && module.exports) {
    module.exports = PaperclipStaking;
}