import { scan, map, tap } from "rxjs/operators";
import { useEffect, useMemo, useCallback, useState } from "react";
import { log } from "@ledgerhq/logs";
import { UserRefusedDeviceNameChange } from "@ledgerhq/errors";
import { useReplaySubject } from "../../observable";
import { currentMode } from "./app";
import { getDeviceModel } from "@ledgerhq/devices";
import { getImplementation } from "./implementations";
const mapResult = (status) => status.name;
const getInitialState = (device) => ({
    isLoading: !!device,
    allowRenamingRequested: false,
    unresponsive: false,
    name: "",
    device,
    deviceInfo: null,
    error: null,
    completed: false,
});
const reducer = (state, e) => {
    switch (e.type) {
        case "unresponsiveDevice":
            return { ...state, unresponsive: true, isLoading: false };
        case "deviceChange":
            return getInitialState(e.device);
        case "disconnected":
            return {
                ...getInitialState(state.device),
                isLoading: !!e.expected,
            };
        case "error":
            return {
                ...getInitialState(state.device),
                error: e.error,
                isLoading: false,
            };
        case "permission-requested":
            return {
                ...state,
                allowRenamingRequested: true,
                unresponsive: false,
                isLoading: false,
            };
        case "device-renamed":
            return {
                ...getInitialState(state.device),
                name: e.name,
                completed: true,
                isLoading: false,
            };
    }
    return state;
};
export const createAction = (task) => {
    const useHook = (device, request) => {
        const [state, setState] = useState(() => getInitialState(device));
        const [resetIndex, setResetIndex] = useState(0);
        const deviceSubject = useReplaySubject(device);
        // Changing the nonce causing a refresh of the useEffect
        const onRetry = useCallback(() => {
            setResetIndex(i => i + 1);
            setState(getInitialState(device));
        }, [device]);
        const productName = useMemo(() => (device ? getDeviceModel(device.modelId).productName : ""), [device]);
        useEffect(() => {
            if (state.completed)
                return;
            const impl = getImplementation(currentMode)({
                deviceSubject,
                task,
                request,
            });
            const sub = impl
                .pipe(tap((e) => log("actions-rename-device-event", e.type, e)), map((e) => {
                if (productName &&
                    e.type === "error" &&
                    e.error instanceof UserRefusedDeviceNameChange) {
                    e.error = new UserRefusedDeviceNameChange(undefined, {
                        productName,
                    });
                }
                return e;
            }), scan(reducer, getInitialState()))
                .subscribe(setState);
            return () => {
                sub.unsubscribe();
            };
        }, [deviceSubject, state.completed, resetIndex, productName, request]);
        return {
            ...state,
            onRetry,
        };
    };
    return {
        useHook,
        mapResult,
    };
};
//# sourceMappingURL=renameDevice.js.map