import { fetchNbpRate, FALLBACK_RATES } from '../logic/nbp'; const { DialogV2 } = foundry.applications.api as unknown as { DialogV2: any; }; class MoneyConverterDialog extends DialogV2 { rates: Record; constructor(options: any, rates: Record) { super(options); this.rates = rates; } protected override _onRender(context: any, options: any) { super._onRender(context, options); const html = this.element; const leftInput = html.querySelector('#hbm-conv-left') as HTMLInputElement; const rightInput = html.querySelector('#hbm-conv-right') as HTMLInputElement; const leftSelect = html.querySelector('#hbm-sf') as HTMLSelectElement; const rightSelect = html.querySelector('#hbm-st') as HTMLSelectElement; if (!leftInput || !rightInput || !leftSelect || !rightSelect) return; const calcRight = () => { const v = parseFloat(leftInput.value); if (Number.isNaN(v)) { rightInput.value = ''; return; } const lk = leftSelect.value; const rk = rightSelect.value; const res = v * this.rates[lk] / this.rates[rk]; rightInput.value = isFinite(res) ? res.toFixed(4) : ''; }; const calcLeft = () => { const v = parseFloat(rightInput.value); if (Number.isNaN(v)) { leftInput.value = ''; return; } const lk = leftSelect.value; const rk = rightSelect.value; const res = v * this.rates[rk] / this.rates[lk]; leftInput.value = isFinite(res) ? res.toFixed(4) : ''; }; leftInput.addEventListener('input', calcRight); leftSelect.addEventListener('change', calcRight); rightInput.addEventListener('input', calcLeft); rightSelect.addEventListener('change', calcRight); } } export async function showMoneyConverter(actor: any): Promise { const pln = actor.system.details?.money ?? 0; const currentYear = actor.system.details?.currentYear ?? 2026; const [eurData, usdData] = await Promise.all([fetchNbpRate('eur', currentYear), fetchNbpRate('usd', currentYear)]); const eurRate = eurData?.rate ?? FALLBACK_RATES.eur!; const usdRate = usdData?.rate ?? FALLBACK_RATES.usd!; const rateDate = eurData?.date ?? usdData?.date ?? 'default'; const isLive = !!(eurData || usdData); const CURRENCIES: Record }> = { PLN: { labelKey: 'HBM.moneyConverter.currencies.PLN', toPln: 1, noteKey: '' }, EUR: { labelKey: 'HBM.moneyConverter.currencies.EUR', toPln: eurRate, noteKey: 'HBM.moneyConverter.notes.nbp', noteParam: { date: rateDate } }, USD: { labelKey: 'HBM.moneyConverter.currencies.USD', toPln: usdRate, noteKey: 'HBM.moneyConverter.notes.nbp', noteParam: { date: rateDate } }, TH: { labelKey: 'HBM.moneyConverter.currencies.TH', toPln: eurRate, noteKey: 'HBM.moneyConverter.notes.th' }, FC: { labelKey: 'HBM.moneyConverter.currencies.FC', toPln: 2.0, noteKey: 'HBM.moneyConverter.notes.fc' }, ST: { labelKey: 'HBM.moneyConverter.currencies.ST', toPln: 240, noteKey: 'HBM.moneyConverter.notes.st' }, ZK: { labelKey: 'HBM.moneyConverter.currencies.ZK', toPln: 2880, noteKey: 'HBM.moneyConverter.notes.zk' }, PL: { labelKey: 'HBM.moneyConverter.currencies.PL', toPln: 34560, noteKey: 'HBM.moneyConverter.notes.pl' }, }; const currKeys = Object.keys(CURRENCIES); const optHtml = (sel: string) => currKeys.map(k => { const label = game.i18n.localize(CURRENCIES[k].labelKey); return ``; }).join(''); const ratesRows = currKeys.map(k => { const c = CURRENCIES[k]; const label = game.i18n.localize(c.labelKey); const note = c.noteKey ? game.i18n.format(c.noteKey, c.noteParam || {}) : ''; const fromPln = k === 'PLN' ? '1.0000' : (1 / c.toPln).toPrecision(4); return ` ${label} ${c.toPln === 1 ? '1.0000' : c.toPln.toFixed(4)} ${fromPln} ${note} `; }).join(''); const rates = Object.fromEntries(currKeys.map(k => [k, CURRENCIES[k].toPln])); const liveText = isLive ? game.i18n.format('HBM.moneyConverter.liveRates', { date: rateDate }) : game.i18n.localize('HBM.moneyConverter.defaultRates'); const initialEur = isFinite(pln / eurRate) ? (pln / eurRate).toFixed(4) : ''; const content = `

${liveText}

${game.i18n.localize('HBM.moneyConverter.actorCash')} ${pln} PLN (${game.i18n.format('HBM.moneyConverter.campaignYear', { year: currentYear })})
${game.i18n.localize('HBM.moneyConverter.calculator')}
⇄
▸ ${game.i18n.localize('HBM.moneyConverter.exchangeRatesTable')} ${ratesRows}
${game.i18n.localize('HBM.moneyConverter.currency')} ${game.i18n.localize('HBM.moneyConverter.ratePln')} ${game.i18n.localize('HBM.moneyConverter.onePlnEquals')} ${game.i18n.localize('HBM.moneyConverter.note')}
`; const dialog = new MoneyConverterDialog({ window: { title: game.i18n.localize('HBM.ui.moneyConverterTitle') }, content, buttons: [ { action: 'ok', label: game.i18n.localize('HBM.ui.confirm') || 'Ok', default: true } ], rejectClose: false }, rates); dialog.render(true); }