/**
 * 設備・料金の既定値（pl-aggregator server/config.mjs から移植。env 上書き（envNum）は廃止し素の定数に）。
 *
 * ■ 符号規約（全パッケージ共通・API 契約）:
 *   - powerKw / plannedKw / actualKw : 正 = 充電（系統→電池）, 負 = 放電（電池→系統）
 *   - エネルギーは kWh、30分コマは 0.5h、価格は 円/kWh
 */
/** 設備仕様（サイトマスタ。デモ既定値） */
interface Plant {
    id: string;
    name: string;
    lat: number;
    lon: number;
    /** 蓄電容量 [kWh] */
    capacityKwh: number;
    /** PCS 定格（充放電合計の絶対上限）[kW] */
    maxPowerKw: number;
    /** 一次調整力 契約ΔkW */
    contractGfKw: number;
    /** 往復効率（充放電で sqrt(eta) ずつ対称に分割） */
    roundTripEfficiency: number;
    /** 補機損失（常時）[kW] */
    auxLossKw: number;
}
declare const PLANT: Plant;
/** 料金・単価（契約値に合わせて呼び出し側で差し替える。ここはデモ既定値） */
interface Tariff {
    /** ΔkW 契約単価 [円/kW/h]（需給調整市場の平均的な約定水準を模した仮値） */
    balancingDeltaKwYenPerKwH: number;
    /** 容量市場 約定価格 [円/kW/年]（仮値） */
    capacityYenPerKwYear: number;
    /** インバランス料金 [円/kWh]（仮値。実際は30分ごとに変動） */
    imbalanceYenPerKwh: number;
    /** 託送料金 従量分 [円/kWh]（高圧の仮値） */
    wheelingYenPerKwh: number;
    /** 託送 基本料金 [円/kW/月] */
    wheelingYenPerKwMonth: number;
}
declare const TARIFF: Tariff;
/** 商品別の容量配分（pl-aggregator server/gen/schedule.mjs capacityAllocation から移植。デモ既定値） */
interface CapacityAllocationItem {
    product: string;
    allocatedMw: number;
    color: string;
}
interface CapacityAllocation {
    totalCapacityMw: number;
    allocations: CapacityAllocationItem[];
}
declare const CAPACITY_ALLOCATION: CapacityAllocation;

/**
 * 蓄電池の物理・市場ロジック（純関数）。pl-aggregator server/engine.mjs L82-137 から移植。
 *
 * ■ 符号規約: powerKw / plannedKw / actualKw は 正 = 充電（系統→電池）, 負 = 放電（電池→系統）。
 * ■ 往復効率は sqrt(eta) を充放電で対称に分割する。
 * ■ computePnl は actualKw しか見ない。buildDayPlan は actualKw: 0 を返すため、
 *   計画通り運転した想定で損益を出すには
 *   `slots.map((s) => ({ ...s, actualKw: s.plannedKw }))` を渡すこと（忘れると収益が全部 0 になる）。
 */

declare const clamp: (v: number, lo: number, hi: number) => number;
declare const round: (v: number | null | undefined, d?: number) => number;
interface SocStepOptions {
    /** 往復効率（既定: PLANT.roundTripEfficiency） */
    eta?: number;
    /** 蓄電容量 [kWh]（既定: PLANT.capacityKwh） */
    capacityKwh?: number;
    /** 補機損失 [kW]（既定: PLANT.auxLossKw。計画計算では 0 を渡す） */
    auxKw?: number;
}
/** SOC 更新（往復効率・補機損失込み）。powerKw: +充電/−放電。戻り値: 新SOC[%]（0..100 にクランプ） */
declare function socStep(soc: number, powerKw: number, dtSec: number, { eta, capacityKwh, auxKw, }?: SocStepOptions): number;
interface DayPlanSlot {
    /** "HH:MM" */
    time: string;
    /** 計画出力 [kW]（+充電/−放電） */
    plannedKw: number;
    /** 常に 0（実績は運用側で埋める。computePnl に渡す前に plannedKw をコピーすること） */
    actualKw: number;
    /** 計画 SOC [%]（コマ末） */
    socPercent: number;
    /** JEPX 価格 [円/kWh] */
    jepxPrice: number;
}
interface DayPlanOptions {
    /** 初期 SOC [%] */
    soc0?: number;
    /** 配分容量（コマ出力の上限）[kW] */
    capKw?: number;
    /** 往復効率 */
    eta?: number;
    /** SOC 下限 [%] */
    socLo?: number;
    /** SOC 上限 [%] */
    socHi?: number;
    /** 蓄電容量 [kWh] */
    capacityKwh?: number;
    /** 効率込みスプレッドの採用閾値 [円/kWh] */
    minSpreadYen?: number;
    /**
     * 1日の充放電サイクル数上限。1サイクル = capacityKwh 相当の AC 充電量
     * （計画上の充電 kWh 合計 ≤ maxCyclesPerDay × capacityKwh）。既定は無制限。
     */
    maxCyclesPerDay?: number;
    /** EPRX（需給調整市場）で確保する kW。JEPX 計画に使えるのは capKw − reservedKwForEprx。既定 0 */
    reservedKwForEprx?: number;
}
/**
 * 実価格から日次計画を生成（安値で充電・高値で放電、往復効率・SOC範囲・容量配分・サイクル上限を考慮）。
 *
 * v0.1.1: 30 分コマ単位の貪欲法（コマ出力 = useKw 固定）を最小費用流（LP の厳密解）に置換。
 * 旧実装は PCS×0.5h の 1 コマ分が SOC 幅を超える構成（1C など）で計画が空になり収益 0 になっていた。
 * 新実装はコマ出力を連続量で決めるので端数コマを許容し、PCS・容量に対して収益が単調非減少になる。
 * 各日は開始 SOC に戻る（売った分は必ず買っている）。
 */
declare function buildDayPlan(prices: readonly number[], options?: DayPlanOptions): DayPlanSlot[];
/** computePnl が参照する単価（Tariff の部分集合） */
type PnlTariff = Pick<Tariff, "balancingDeltaKwYenPerKwH" | "capacityYenPerKwYear" | "imbalanceYenPerKwh" | "wheelingYenPerKwh">;
interface PnlSlot {
    plannedKw: number;
    actualKw: number;
    jepxPrice: number;
}
interface PnlOptions {
    /**
     * ΔkW 契約量 [kW]。tariff.balancingDeltaKwYenPerKwH（円/kW/h の簡易単価）× 0.5h × コマ数の粗い可用性収入。
     * 需給調整市場の公表単位（円/ΔkW・30分）・上限価格・約定率で計算するには calcEprxRevenue を使うこと
     */
    balancingContractKw?: number;
    /** 容量市場の契約 kW */
    capacityKw?: number;
    tariff?: PnlTariff;
}
interface PnlResult {
    jepxRevenue: number;
    balancingRevenue: number;
    capacityRevenue: number;
    /** 負の値で返る */
    imbalanceCost: number;
    /** 負の値で返る */
    transmissionCost: number;
    netRevenue: number;
    chargedKwh: number;
    dischargedKwh: number;
    imbalanceKwh: number;
}
/** 日次収益計算（kWh・円）。slots: [{plannedKw, actualKw, jepxPrice}] 経過分のみ渡す。actualKw しか見ない点に注意 */
declare function computePnl(slots: readonly PnlSlot[], { balancingContractKw, capacityKw, tariff }?: PnlOptions): PnlResult;

/**
 * EPRX（需給調整市場）の ΔkW 確保（可用性）収益モデル。
 *
 * ■ 単位: 需給調整市場の ΔkW 価格・上限価格は「円/ΔkW・30分」（30 分コマ 1 つあたりの単価）。
 *   各コマ・各商品について `min(想定約定単価, 上限価格) × 確保kW × 約定率` を積み上げる。
 *   1 コマ = 30 分の単価なので ×0.5h はしない（1 日 48 コマ、1 年 17,520 コマ）。
 *   v0.1.0 までは 円/kW/h 扱いで ×0.5h していた（v0.1.1 で修正。同じ数値を渡すと収益は 2 倍になる）。
 *
 * ■ 上限価格（2026-09-01 実需給分〜）: 複合商品・一次調整力・二次調整力① が 15 → 10 円/ΔkW・30分。
 *   二次調整力②・三次調整力① は 7.21 円で据置、三次調整力② は上限なし。
 *   capPriceYen は数値（全商品共通）か商品別マップ（載っていない商品は上限なし）。
 *   出典: 電力需給調整力取引所「需給調整市場のΔkW上限価格について」（2026-02-05 公表・07-30 更新）、
 *         資源エネルギー庁 電力安定供給WG 第4回（2026-07-14）資料6。
 */
declare const EPRX_PRODUCTS: readonly ["一次", "二次①", "二次②", "三次①", "三次②", "複合"];
type EprxProduct = (typeof EPRX_PRODUCTS)[number];
/** 商品別の上限価格 [円/ΔkW・30分]。載っていない商品は上限なし */
type EprxCapPrices = Readonly<Partial<Record<EprxProduct, number>>>;
/** 2026-08-31 実需給分までの上限価格（三次② は上限なし） */
declare const EPRX_CAP_PRICES_BEFORE_2026_09: EprxCapPrices;
/** 2026-09-01 実需給分からの上限価格（一次・二次①・複合が 10 円へ。三次② は上限なし） */
declare const EPRX_CAP_PRICES_FROM_2026_09: EprxCapPrices;
/** 上限価格改定（15 → 10 円）の対象商品 */
declare const EPRX_CAP_CHANGE_PRODUCTS: readonly EprxProduct[];
interface EprxAllocation {
    product: EprxProduct;
    /** 確保 kW（ΔkW 契約量） */
    allocatedKw: number;
}
interface EprxSlot {
    /**
     * 想定約定単価 [円/ΔkW・30分]。
     * 数値なら全商品共通、マップなら商品別（載っていない商品は 0 円 = 未約定扱い）。
     * 負値は 0 円に切り上げる。
     */
    expectedPriceYen: number | Partial<Record<EprxProduct, number>>;
}
interface EprxRevenueOptions {
    /** 商品別の確保 kW。並び順を優先度とみなし、合計が capKw を超える分は後方から切り詰める */
    productMix: readonly EprxAllocation[];
    /** 確保 kW 合計の上限（PCS 定格など）。既定は無制限 */
    capKw?: number;
    /**
     * 上限価格 [円/ΔkW・30分]。数値なら全商品共通、マップなら商品別（載っていない商品は上限なし）。
     * 新旧制度の比較には EPRX_CAP_PRICES_BEFORE_2026_09 / EPRX_CAP_PRICES_FROM_2026_09 を渡す
     */
    capPriceYen: number | EprxCapPrices;
    /**
     * 想定約定率（落札率）0..1。既定 1（全コマ約定）。
     * 実務では上限付近の応札は一部不落になるため、目安の試算では 1 未満を推奨
     */
    awardRate?: number;
}
interface EprxRevenueResult {
    /** 合計収益 [円]（整数丸め） */
    revenueYen: number;
    /** 商品別収益 [円]（丸めなし） */
    byProduct: Record<EprxProduct, number>;
    /** capKw 切り詰め後の確保 kW 合計 */
    totalAllocatedKw: number;
    /** 上限価格クリップが発生した（コマ×商品）件数 */
    cappedCount: number;
    /** 計算に使った約定率 */
    awardRate: number;
}
/** EPRX の ΔkW 確保収益。slots は 30 分コマの列（1日なら 48 要素、1年なら 17,520 要素） */
declare function calcEprxRevenue(slots: readonly EprxSlot[], { productMix, capKw, capPriceYen, awardRate }: EprxRevenueOptions): EprxRevenueResult;

/**
 * 時刻ユーティリティ（JST 固定）。pl-aggregator server/config.mjs から移植。
 * 電力市場は JST の30分コマで動く。ホスト TZ に依存しないよう、
 * 明示的な timeZone 指定の Intl.DateTimeFormat のみを使う（process.env.TZ は変更しない）。
 */
declare const TZ = "Asia/Tokyo";
interface JstParts {
    y: number;
    m: number;
    d: number;
    H: number;
    M: number;
    S: number;
}
/** {y,m,d,H,M,S} in JST */
declare function jst(d?: Date): JstParts;
/** YYYY-MM-DD（JST） */
declare function ymd(d?: Date): string;
/** YYYY/MM/DD（JST） */
declare function ymdSlash(d?: Date): string;
/** 30分コマ index 0..47（JST） */
declare function slotOf(d?: Date | number): number;
/** コマ index → "HH:MM" */
declare function hhmm(slot: number): string;
/** コマ index → "HH:MM-HH:MM" */
declare function slotLabel(slot: number): string;
/** ISO 8601 with +09:00 offset */
declare function isoJst(d?: Date): string;
/** JST の指定日・時分を epoch ms に */
declare function jstDateTime(ymdStr: string, H?: number, M?: number): number;
/** YYYY-MM-DD に n 日加算（JST） */
declare function addDays(ymdStr: string, n: number): string;
/** 年度（4月始まり・JST） */
declare function fiscalYear(d?: Date): number;

export { CAPACITY_ALLOCATION, type CapacityAllocation, type CapacityAllocationItem, type DayPlanOptions, type DayPlanSlot, EPRX_CAP_CHANGE_PRODUCTS, EPRX_CAP_PRICES_BEFORE_2026_09, EPRX_CAP_PRICES_FROM_2026_09, EPRX_PRODUCTS, type EprxAllocation, type EprxCapPrices, type EprxProduct, type EprxRevenueOptions, type EprxRevenueResult, type EprxSlot, type JstParts, PLANT, type Plant, type PnlOptions, type PnlResult, type PnlSlot, type PnlTariff, type SocStepOptions, TARIFF, TZ, type Tariff, addDays, buildDayPlan, calcEprxRevenue, clamp, computePnl, fiscalYear, hhmm, isoJst, jst, jstDateTime, round, slotLabel, slotOf, socStep, ymd, ymdSlash };
