/**
 * Yield protocol constants — contract addresses, function selectors, and types
 * for Aave V3 and Morpho Blue vault integrations.
 */

// ── Supported chains for yield ──
export type SupportedYieldChain = "1" | "8453";
export type YieldProtocol = "aave-v3" | "morpho-blue";
export type StablecoinSymbol = "USDC" | "USDT" | "DAI";

export interface YieldOpportunity {
	protocol: YieldProtocol;
	chainId: SupportedYieldChain;
	asset: StablecoinSymbol;
	assetAddress: string;
	vaultAddress: string; // aToken for Aave, vault for Morpho
	apy: number;
	apy7d?: number;
	apy30d?: number;
	apyBase?: number;
	tvl?: number;
	poolId?: string; // DeFi Llama pool ID
	vaultName?: string;
}

export interface YieldPosition {
	protocol: YieldProtocol;
	chainId: SupportedYieldChain;
	asset: StablecoinSymbol;
	assetAddress: string;
	vaultAddress: string;
	shares: string; // raw shares/aToken balance
	underlying: string; // underlying asset value
	decimals: number;
	apy: number;
	dailyEarnings: number;
	annualEarnings: number;
}

export interface YieldSuggestion {
	type: "deposit" | "rebalance";
	priority: "high" | "medium" | "low";
	from?: { protocol: YieldProtocol; chainId: SupportedYieldChain; vaultAddress: string; apy: number };
	to: YieldOpportunity;
	amount: string;
	amountUSD: number;
	reason: string;
	estimatedGasCostUSD: number;
}

// ── Stablecoin addresses per chain ──
export const STABLECOIN_ADDRESSES: Record<SupportedYieldChain, Record<StablecoinSymbol, string>> = {
	"1": {
		USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
		USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
		DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
	},
	"8453": {
		USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
		USDT: "0x0000000000000000000000000000000000000000", // not on Base
		DAI: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
	},
};

export const STABLECOIN_DECIMALS: Record<StablecoinSymbol, number> = {
	USDC: 6,
	USDT: 6,
	DAI: 18,
};

// ── Aave V3 ──
export const AAVE_V3_POOL: Record<SupportedYieldChain, string> = {
	"1": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
	"8453": "0xA238Dd80C259a72e81d7e4664a9801593F98d1c5",
};

// aToken addresses (receipt tokens for deposits)
export const AAVE_ATOKENS: Record<SupportedYieldChain, Partial<Record<StablecoinSymbol, string>>> = {
	"1": {
		USDC: "0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c",
		USDT: "0x23878914EFE38d27C4D67Ab83ed1b93A74D4086a",
		DAI: "0x018008bfb33d285247A21d44E50697654f754e63",
	},
	"8453": {
		USDC: "0x4e65fE4DbA92790696d040ac24Aa414708F5c0AB",
		DAI: "0x0a1d576f3eFeF75b330424287a95A366e8281D54",
	},
};

// ── Morpho Blue Vaults ──
export interface MorphoVaultInfo {
	address: string;
	name: string;
	asset: StablecoinSymbol;
}

export const MORPHO_VAULTS: Record<SupportedYieldChain, MorphoVaultInfo[]> = {
	"1": [
		{ address: "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", name: "Steakhouse USDC", asset: "USDC" },
		{ address: "0x2371e134e3455e0593363cBF89d3b6cf53740618", name: "Steakhouse USDT", asset: "USDT" },
	],
	"8453": [
		{ address: "0xc1256Ae5FF1cf2719D4937adb3bbCCab2E00A2Ca", name: "Moonwell Flagship USDC", asset: "USDC" },
	],
};

// ── MultiSend (for batched approve+deposit) ──
export const MULTISEND_CALL_ONLY: Record<SupportedYieldChain, string> = {
	"1": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
	"8453": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
};

// ── Function selectors ──
export const SELECTORS = {
	// ERC-20
	approve: "0x095ea7b3",           // approve(address,uint256)
	balanceOf: "0x70a08231",         // balanceOf(address)
	// Aave V3 Pool
	supply: "0x617ba037",            // supply(address,uint256,address,uint16)
	withdraw: "0x69328dec",          // withdraw(address,uint256,address)
	getReserveData: "0x35ea6a75",    // getReserveData(address)
	// ERC-4626 (Morpho vaults)
	deposit: "0x6e553f65",           // deposit(uint256,address)
	redeem: "0xba087652",            // redeem(uint256,address,address)
	convertToAssets: "0x07a2d13a",   // convertToAssets(uint256)
	maxDeposit: "0x402d267d",        // maxDeposit(address)
	// MultiSend
	multiSend: "0x8d80ff0a",        // multiSend(bytes)
} as const;

// ── ABI encoding helpers ──
export function padAddress(addr: string): string {
	return addr.slice(2).toLowerCase().padStart(64, "0");
}

export function padUint256(value: bigint): string {
	return value.toString(16).padStart(64, "0");
}

export function encodeApprove(spender: string, amount: bigint): string {
	return `${SELECTORS.approve}${padAddress(spender)}${padUint256(amount)}`;
}

export function encodeAaveSupply(asset: string, amount: bigint, onBehalfOf: string): string {
	return `${SELECTORS.supply}${padAddress(asset)}${padUint256(amount)}${padAddress(onBehalfOf)}${padUint256(0n)}`;
}

export function encodeAaveWithdraw(asset: string, amount: bigint, to: string): string {
	return `${SELECTORS.withdraw}${padAddress(asset)}${padUint256(amount)}${padAddress(to)}`;
}

export function encodeMorphoDeposit(amount: bigint, receiver: string): string {
	return `${SELECTORS.deposit}${padUint256(amount)}${padAddress(receiver)}`;
}

export function encodeMorphoRedeem(shares: bigint, receiver: string, owner: string): string {
	return `${SELECTORS.redeem}${padUint256(shares)}${padAddress(receiver)}${padAddress(owner)}`;
}

export function encodeBalanceOf(address: string): string {
	return `${SELECTORS.balanceOf}${padAddress(address)}`;
}

export function encodeConvertToAssets(shares: bigint): string {
	return `${SELECTORS.convertToAssets}${padUint256(shares)}`;
}

export function encodeMaxDeposit(receiver: string): string {
	return `${SELECTORS.maxDeposit}${padAddress(receiver)}`;
}

// ── Chain display names ──
export const YIELD_CHAIN_NAMES: Record<SupportedYieldChain, string> = {
	"1": "Ethereum",
	"8453": "Base",
};
