import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JsonRpcProvider, Contract, formatEther } from 'ethers';
import { COUPON_ABI } from '../../contracts/abis/coupon.abi';
import { CONTRACT_ADDRESSES } from '../../contracts/addresses';

@Injectable()
export class AddressService {
  private provider: JsonRpcProvider;
  private couponContract: Contract;

  constructor(private config: ConfigService) {
    this.provider = new JsonRpcProvider(this.config.get('rpcUrl'));
    this.couponContract = new Contract(CONTRACT_ADDRESSES.coupon, COUPON_ABI, this.provider);
  }

  async getBalance(address: string) {
    const gnxBalance = await this.provider.getBalance(address);
    return {
      address,
      gnx: formatEther(gnxBalance),
      gnxWei: gnxBalance.toString(),
    };
  }

  async getTokenHoldings(address: string) {
    try {
      const balance = await this.couponContract.balanceOf(address);
      const count = Number(balance);
      const tokens: any[] = [];

      for (let i = 0; i < count && i < 100; i++) {
        const tokenId = await this.couponContract.tokenOfOwnerByIndex(address, i);
        const config = await this.couponContract.getConfig(tokenId);
        tokens.push({
          tokenId: tokenId.toString(),
          issuer: config.issuer,
          faceValue: config.faceValue.toString(),
          couponType: Number(config.couponType) === 0 ? 'utility' : 'security',
          expiryDate: new Date(Number(config.expiryDate) * 1000).toISOString(),
          transferable: config.transferable,
        });
      }

      return { address, totalCount: count, tokens };
    } catch {
      return { address, totalCount: 0, tokens: [] };
    }
  }
}
