import type { StateCreator } from "zustand";
import type { AppState, TransferRecord } from "../types";
import { normalizeTerminal } from "../helpers";

export type TransferSlice = Pick<
    AppState,
    "activeTransfers" | "history" | "upsertTransfer" | "completeTransfer" | "removeTransfer"
>;

// EMA 平滑系数：瞬时速率抖动大（10Hz 采样 + chunk 边界），取 0.3 让显示稳又不过钝。
const RATE_EMA_ALPHA = 0.3;

// withRate 在记录落库前算出瞬时传输速度。bytesTransferred 与 lastProgressAt 配对——
// 后者只在前者增长时刷新为当时墙钟（见 p2p pushUpdate），故相邻两次「有增长」样本的
// 差分即瞬时速率，再做 EMA 平滑。无增长（仅 iceStats / phase 等更新）则原样保留上次
// 速率（next 由 {...cur} 展开本就带着它），不污染。
function withRate(prev: TransferRecord | undefined, next: TransferRecord): TransferRecord
{
    if (!prev) { return next; }
    const prevBytes = prev.bytesTransferred ?? 0;
    const nextBytes = next.bytesTransferred ?? 0;
    const prevAt = prev.lastProgressAt ?? 0;
    const nextAt = next.lastProgressAt ?? 0;
    if (nextBytes <= prevBytes || nextAt <= prevAt) { return next; }
    const instant = (nextBytes - prevBytes) / ((nextAt - prevAt) / 1000);
    const prevRate = prev.bytesPerSec ?? instant;
    return { ...next, bytesPerSec: RATE_EMA_ALPHA * instant + (1 - RATE_EMA_ALPHA) * prevRate };
}

export const createTransferSlice: StateCreator<AppState, [], [], TransferSlice> = (set) =>
({
    activeTransfers: {},
    history: [],

    upsertTransfer: (t) =>
    {
        set((s) =>
        ({
            activeTransfers: { ...s.activeTransfers, [t.sessionId]: withRate(s.activeTransfers[t.sessionId], t) },
        }));
    },

    completeTransfer: (sessionId, finalState) =>
    {
        set((s) =>
        {
            const cur = s.activeTransfers[sessionId];
            if (!cur) { return s; }
            const finalRec = normalizeTerminal(cur, finalState);
            const { [sessionId]: _, ...rest } = s.activeTransfers;
            return ({
                activeTransfers: rest,
                history: [ finalRec, ...s.history ].slice(0, 20),
            });
        });
    },

    removeTransfer: (sessionId) =>
    {
        set((s) =>
        {
            const { [sessionId]: _, ...rest } = s.activeTransfers;
            return ({
                activeTransfers: rest,
                history: s.history.filter((h) => h.sessionId !== sessionId),
            });
        });
    },
});
