import { Contract, JsonRpcProvider } from 'ethers';

const POOL_ABI = [
  'function _BASE_TOKEN_() view returns (address)',
  'function _QUOTE_TOKEN_() view returns (address)',
  'function querySellBase(address,uint256) view returns (uint256,uint256)',
  'function querySellQuote(address,uint256) view returns (uint256,uint256)',
];

/**
 * PMM / DVM on-chain output for tokenIn amount. Matches DODOPMMIntegration.swapExactIn semantics.
 * Returns null if RPC fails, pool is not a DVM, or tokenIn is not base/quote.
 */
export async function pmmQuoteAmountOutFromChain(params: {
  rpcUrl: string;
  poolAddress: string;
  tokenInLookup: string;
  amountIn: bigint;
  /** Passed to querySell* (MT fee view); default deployer is typical for operator tooling. */
  traderForView: string;
}): Promise<bigint | null> {
  const { rpcUrl, poolAddress, tokenInLookup, amountIn, traderForView } = params;
  try {
    const provider = new JsonRpcProvider(rpcUrl);
    const pool = new Contract(poolAddress, POOL_ABI, provider);
    const base = (await pool._BASE_TOKEN_()).toString().toLowerCase();
    const quote = (await pool._QUOTE_TOKEN_()).toString().toLowerCase();
    const ti = tokenInLookup.toLowerCase();
    if (ti === base) {
      const [out] = await pool.querySellBase(traderForView, amountIn);
      return BigInt(out.toString());
    }
    if (ti === quote) {
      const [out] = await pool.querySellQuote(traderForView, amountIn);
      return BigInt(out.toString());
    }
    return null;
  } catch {
    return null;
  }
}

/** RPC for PMM eth_call quotes on Chain 138 (optional; unset = skip on-chain override). */
export function resolvePmmQuoteRpcUrl(): string {
  return (
    process.env.TOKEN_AGGREGATION_PMM_RPC_URL ||
    process.env.TOKEN_AGGREGATION_CHAIN138_RPC_URL ||
    process.env.RPC_URL_138 ||
    ''
  ).trim();
}

export function resolvePmmQuoteTrader(): string {
  return (
    process.env.TOKEN_AGGREGATION_PMM_QUERY_TRADER ||
    '0x4A666F96fC8764181194447A7dFdb7d471b301C8'
  ).trim();
}
