/**
 * Per-skill bonding curve — demand/supply pricing for intent marketplace.
 *
 * Formula: price = BASE_SKILL_PRICE × (demandHours / supplyHours) ^ ELASTICITY
 *
 * High demand + low supply → higher price → incentivizes offers.
 * All prices in tokens per hour.
 */

import type { Skill } from './schemas';
import type { SkillCurvesDoc, SkillCurveEntry } from './schemas-intent';

// ── Curve parameters ──

/** Base price in tokens per hour */
export const BASE_SKILL_PRICE = 100;

/** Elasticity exponent — 0.5 = square root (moderate responsiveness) */
export const ELASTICITY = 0.5;

/** Minimum supply to avoid division by zero / extreme prices */
const MIN_SUPPLY = 1;

/** Maximum price cap (10x base) to prevent runaway pricing */
const MAX_PRICE = BASE_SKILL_PRICE * 10;

// ── Price functions ──

/**
 * Calculate the current price per hour for a skill.
 * Returns tokens per hour.
 */
export function getSkillPrice(skill: Skill, curves: SkillCurvesDoc): number {
	const curve = curves.curves[skill];
	if (!curve || curve.supplyHours <= 0) return BASE_SKILL_PRICE;

	const supply = Math.max(curve.supplyHours, MIN_SUPPLY);
	const demand = Math.max(curve.demandHours, 0);
	const ratio = demand / supply;

	const price = Math.round(BASE_SKILL_PRICE * Math.pow(ratio, ELASTICITY));
	return Math.min(price, MAX_PRICE);
}

/**
 * Calculate the total cost for a need intent (hours × skill price).
 */
export function calculateIntentCost(skill: Skill, hours: number, curves: SkillCurvesDoc): number {
	const price = getSkillPrice(skill, curves);
	return price * hours;
}

/**
 * Get all current skill prices.
 */
export function getAllSkillPrices(curves: SkillCurvesDoc): Record<Skill, number> {
	const skills: Skill[] = ['facilitation', 'design', 'tech', 'outreach', 'logistics'];
	const prices = {} as Record<Skill, number>;
	for (const skill of skills) {
		prices[skill] = getSkillPrice(skill, curves);
	}
	return prices;
}

/**
 * Create or update a skill curve entry after an intent is created/withdrawn.
 * Returns the updated curve entry.
 */
export function recalculateCurve(
	skill: Skill,
	supplyHours: number,
	demandHours: number,
): Omit<SkillCurveEntry, 'history'> {
	const supply = Math.max(supplyHours, MIN_SUPPLY);
	const demand = Math.max(demandHours, 0);
	const ratio = demand / supply;
	const price = Math.min(Math.round(BASE_SKILL_PRICE * Math.pow(ratio, ELASTICITY)), MAX_PRICE);

	return {
		skill,
		supplyHours,
		demandHours,
		currentPrice: price,
	};
}

/**
 * Get curve configuration for UI display.
 */
export function getSkillCurveConfig() {
	return {
		basePrice: BASE_SKILL_PRICE,
		elasticity: ELASTICITY,
		maxPrice: MAX_PRICE,
	};
}
