import * as Redux from "@reduxjs/toolkit"
// import { cloneDeep } from "lodash"
import { diff } from "deep-diff";
// action components style
import AsyncStorage from '@react-native-async-storage/async-storage'
import { executionActions } from "@/redux/currentApp/executionTree/executionSlice";
import { CUSTOM_STORAGE_PREFIX } from "@/redux/currentApp/executionTree/executionReducer";

export const reduxAsync: Redux.Middleware = (store) => (next) => async (action) => {
    const result = next(action)
    if (
        action.type === executionActions.setLocalStorageInExecutionReducer.type &&
        action.payload
    ) {
        try {
            
            const state= store.getState()
            const updatedStorage =  state.currentApp.execution.result.localStorage;
            await AsyncStorage.setItem(
                CUSTOM_STORAGE_PREFIX, 
                JSON.stringify(updatedStorage)
            );
        } catch (err) {
            console.error('AsyncStorage persistence failed:', err);
        }
    }
    if (action.type === executionActions.clearLocalStorageInExecutionReducer.type) {
        try {
            await AsyncStorage.removeItem(CUSTOM_STORAGE_PREFIX);
        } catch (err) {
            console.error('Failed to clear AsyncStorage:', err);
        }
    }

    return result;
}


export function deepDiffToJsonPatch(lhs: any, rhs: any): any[] {
    const differences = diff(lhs, rhs);
    if (!differences) return [];

    return differences.map(change => {
        const path = "/" + change.path?.join("/"); // Convert path array to JSON Patch format

        switch (change.kind) {
            case "N": // New property added
                return { op: "add", path, value: change.rhs };

            case "D": // Property deleted
                return { op: "remove", path };

            case "E": // Property edited (changed value)
                return { op: "replace", path, value: change.rhs };

            case "A": // Array modification
                if (change.item.kind === "N") {
                    return { op: "add", path: `${path}/${change.index}`, value: change.item.rhs };
                }
                if (change.item.kind === "D") {
                    return { op: "remove", path: `${path}/${change.index}` };
                }
                if (change.item.kind === "E") {
                    return { op: "replace", path: `${path}/${change.index}`, value: change.item.rhs };
                }
        }
    }).filter(Boolean); // Remove undefined values
}
