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

class PaperclipWallets {
  constructor() {
    this.addressList = [];
    this.price = 0;
  }

  _getPrice() {
    return this.price;
  }

  _setPrice(price) {
    this.price = price;
  }

  getAddressList() {
    return this.addressList;
  }

  clearAddressList() {
    this.addressList = [];
  }

  getAddressExists(address) {
    if (address) {
      return this.addressList.indexOf(address) > -1;
    }
    return false;
  }

  addAddressToList(address) {
    if (address) {
      this.addressList.push(address);
    }
  }

  async createNewWallet(password) {
    try {
      const ClipsCrypto = require('../modules/clips-crypto.js');
      const keyPair = ClipsCrypto.generateKeyPair();
      
      // Store wallet in database
      const wallet = {
        address: keyPair.address,
        publicKey: keyPair.publicKey,
        privateKey: keyPair.privateKey, // In production, encrypt this with password
        name: `Account ${this.addressList.length + 1}`,
        created: Date.now()
      };
      
      PaperclipDatabase.saveWallet(wallet);
      this.addAddressToList(keyPair.address);
      
      return wallet;
    } catch (error) {
      throw new Error(`Failed to create wallet: ${error.message}`);
    }
  }

  async importFromPrivateKey(privateKeyHex, password) {
    try {
      const ClipsCrypto = require('../modules/clips-crypto.js');
      const keyPair = ClipsCrypto.importPrivateKey(privateKeyHex);
      
      const wallet = {
        address: keyPair.address,
        publicKey: keyPair.publicKey,
        privateKey: keyPair.privateKey,
        name: `Imported Account`,
        created: Date.now()
      };
      
      PaperclipDatabase.saveWallet(wallet);
      this.addAddressToList(keyPair.address);
      
      return wallet;
    } catch (error) {
      throw new Error(`Failed to import wallet: ${error.message}`);
    }
  }

  async sendTransaction(fromAddress, toAddress, amount, password) {
    try {
      // Get wallet data
      const wallet = PaperclipDatabase.getWallet(fromAddress);
      if (!wallet) {
        throw new Error("Wallet not found");
      }

      // Validate address format
      const ClipsCrypto = require('../modules/clips-crypto.js');
      if (!ClipsCrypto.isValidAddress(toAddress)) {
        throw new Error("Invalid recipient address");
      }

      // Get current nonce
      const nonce = await ipcRenderer.invoke("paperclip-get-nonce", fromAddress);
      
      // Create and sign transaction
      const transaction = ClipsCrypto.createTransaction({
        sender: fromAddress,
        receiver: toAddress,
        amount: parseInt(amount),
        nonce: nonce,
        type: 'transfer',
        data: '',
        privateKey: wallet.privateKey
      });

      // Broadcast transaction
      const result = await ipcRenderer.invoke("paperclip-broadcast-tx", 
        ClipsCrypto.transactionToHex(transaction));
      
      if (result.success) {
        return {
          hash: result.hash,
          height: result.height
        };
      } else {
        throw new Error(result.error || "Transaction failed");
      }
    } catch (error) {
      throw new Error(`Transaction failed: ${error.message}`);
    }
  }

  async getWalletBalance(address) {
    try {
      const balance = await ipcRenderer.invoke("paperclip-get-balance", address);
      return balance;
    } catch (error) {
      console.error(`Failed to get balance for ${address}:`, error);
      return 0;
    }
  }

  async refreshWalletData() {
    try {
      this.clearAddressList();
      
      const wallets = PaperclipDatabase.getWallets();
      if (!wallets || !wallets.addresses) {
        return {
          sumBalance: 0,
          addressData: [],
          sumBalanceFormatted: "0 CLIPS"
        };
      }

      const data = {
        sumBalance: 0,
        addressData: []
      };

      // Get balance for each wallet
      for (const address of wallets.addresses) {
        const wallet = PaperclipDatabase.getWallet(address);
        const balance = await this.getWalletBalance(address);
        
        data.addressData.push({
          address: address,
          name: wallet ? wallet.name : `Account`,
          balance: balance,
          balanceFormatted: this.formatBalance(balance)
        });
        
        data.sumBalance += balance;
        this.addAddressToList(address);
      }

      data.sumBalanceFormatted = this.formatBalance(data.sumBalance);
      return data;
    } catch (error) {
      throw new Error(`Failed to refresh wallet data: ${error.message}`);
    }
  }

  formatBalance(balance) {
    if (balance === 0) {
      return "0 CLIPS";
    }
    
    if (balance >= 1000000) {
      return (balance / 1000000).toFixed(2) + "M CLIPS";
    } else if (balance >= 1000) {
      return (balance / 1000).toFixed(2) + "K CLIPS";
    } else {
      return balance.toLocaleString() + " CLIPS";
    }
  }

  validateAddress(address) {
    const ClipsCrypto = require('../modules/clips-crypto.js');
    return ClipsCrypto.isValidAddress(address);
  }

  validateAmount(amount) {
    const num = parseFloat(amount);
    return !isNaN(num) && num > 0;
  }

  // UI Event Handlers
  async handleCreateNewWallet() {
    const password = $("#walletPasswordFirst").val();
    
    if (!password) {
      throw new Error("Password cannot be empty");
    }
    
    if (password !== $("#walletPasswordSecond").val()) {
      throw new Error("Passwords do not match");
    }

    return await this.createNewWallet(password);
  }

  async handleImportPrivateKey() {
    const privateKey = $("#inputPrivateKey").val();
    const password = $("#keyPasswordFirst").val();
    
    if (!privateKey) {
      throw new Error("Private key cannot be empty");
    }
    
    if (!password) {
      throw new Error("Password cannot be empty");
    }
    
    if (password !== $("#keyPasswordSecond").val()) {
      throw new Error("Passwords do not match");
    }

    return await this.importFromPrivateKey(privateKey, password);
  }

  async handleSendTransaction() {
    const fromAddress = $("#sendFromAddress").val();
    const toAddress = $("#sendToAddress").val();
    const amount = $("#sendAmount").val();
    const password = $("#sendPassword").val();
    
    if (!fromAddress) {
      throw new Error("From address is required");
    }
    
    if (!toAddress) {
      throw new Error("To address is required");
    }
    
    if (!this.validateAddress(toAddress)) {
      throw new Error("Invalid recipient address format");
    }
    
    if (!this.validateAmount(amount)) {
      throw new Error("Invalid amount");
    }
    
    if (!password) {
      throw new Error("Password is required");
    }

    return await this.sendTransaction(fromAddress, toAddress, amount, password);
  }
}

// Create global instance
const ClipsWallet = new PaperclipWallets();

// Make it available globally
window.ClipsWallet = ClipsWallet;