/**
 * Banking Application Store
 * Redux-like state management for bank and ATM interfaces
 */

// ============================================================================
// REDUX CORE IMPLEMENTATION
// ============================================================================

/**
 * Creates a Redux-like store.
 * @param {Function} reducer - A function that returns the next state tree
 * @returns {Object} The store object with methods: getState, dispatch, subscribe
 */
function createStore(reducer) {
    let state;
    let listeners = [];

    const getState = () => state;

    const dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach(listener => listener());
    };

    const subscribe = (listener) => {
        listeners.push(listener);
        return () => {
            listeners = listeners.filter(l => l !== listener);
        };
    };

    // Initialize state
    dispatch({});

    return { getState, dispatch, subscribe };
}

// ============================================================================
// STATE
// ============================================================================

const initialState = {
    uid: '',
    accounts: {
        bank: 0,
        cash: 0,
        org: 0
    },
    pin: '1234',
    transactions: []
};

// ============================================================================
// ACTION TYPES
// ============================================================================

const DEPOSIT = 'DEPOSIT';
const WITHDRAW = 'WITHDRAW';
const TRANSFER = 'TRANSFER';
const UPDATE_ACCOUNTS = 'UPDATE_ACCOUNTS';
const UPDATE_PIN = 'UPDATE_PIN';

// ============================================================================
// ACTION CREATORS
// ============================================================================

const deposit = (amount) => ({
    type: DEPOSIT,
    payload: amount
});

const withdraw = (amount) => ({
    type: WITHDRAW,
    payload: amount
});

const transfer = (from, amount, target) => ({
    type: TRANSFER,
    from: from,
    payload: amount,
    target: target
});

const updateAccounts = (accounts) => ({
    type: UPDATE_ACCOUNTS,
    payload: accounts
});

const updatePin = (pin) => ({
    type: UPDATE_PIN,
    payload: pin
});

// ============================================================================
// REDUCER
// ============================================================================

function appReducer(state = initialState, action) {
    switch (action.type) {
        case DEPOSIT:
            if (state.accounts.cash < action.payload) {
                console.warn('Insufficient cash!');
                return state;
            }
            return {
                ...state,
                accounts: {
                    ...state.accounts,
                    bank: state.accounts.bank + action.payload,
                    cash: state.accounts.cash - action.payload
                },
                transactions: [
                    ...state.transactions,
                    {
                        type: 'Deposit',
                        amount: action.payload,
                        date: new Date().toLocaleString()
                    }
                ]
            };

        case WITHDRAW:
            if (state.accounts.bank < action.payload) {
                console.warn('Insufficient funds!');
                return state;
            }
            return {
                ...state,
                accounts: {
                    ...state.accounts,
                    bank: state.accounts.bank - action.payload,
                    cash: state.accounts.cash + action.payload
                },
                transactions: [
                    ...state.transactions,
                    {
                        type: 'Withdraw',
                        amount: action.payload,
                        date: new Date().toLocaleString()
                    }
                ]
            };

        case TRANSFER:
            const fromAccount = action.from;
            if (state.accounts[fromAccount] < action.payload) {
                console.warn('Insufficient funds!');
                return state;
            }

            const newAccounts = { ...state.accounts };
            newAccounts[fromAccount] -= action.payload;

            return {
                ...state,
                accounts: newAccounts,
                transactions: [
                    ...state.transactions,
                    {
                        type: 'Transfer',
                        amount: action.payload,
                        from: fromAccount,
                        target: action.target,
                        date: new Date().toLocaleString()
                    }
                ]
            };

        case UPDATE_ACCOUNTS:
            return {
                ...state,
                accounts: {
                    ...state.accounts,
                    ...action.payload
                }
            };

        case UPDATE_PIN:
            return {
                ...state,
                pin: String(action.payload)
            };

        case 'SET_UID':
            return {
                ...state,
                uid: action.payload
            };

        default:
            return state;
    }
}

// ============================================================================
// STORE INSTANCE
// ============================================================================

const store = createStore(appReducer);

// ============================================================================
// ARMA 3 INTEGRATION
// ============================================================================

/**
 * Sends an event to Arma 3
 * @param {string} event - Event name
 * @param {Object} data - Event data
 */
function sendEvent(event, data) {
    if (typeof A3API !== 'undefined') {
        A3API.SendAlert(JSON.stringify({
            event: event,
            data: data
        }));
    } else {
        console.log('Event:', event, 'Data:', data);
    }
}

/**
 * Syncs account data from Arma 3 into the store
 * @param {Object} data - Account data from Arma 3
 */
function syncDataFromArma(data) {
    if (data && typeof data === 'object') {
        const accounts = {};

        if (data.cash !== undefined) accounts.cash = data.cash;
        if (data.bank !== undefined) accounts.bank = data.bank;
        if (data.org !== undefined) accounts.org = data.org;
        if (data.players !== undefined) accounts.players = data.players;

        if (Object.keys(accounts).length > 0) {
            store.dispatch(updateAccounts(accounts));
        }

        // Update UID if provided
        if (data.uid !== undefined && data.uid !== store.getState().uid) {
            store.dispatch({ type: 'SET_UID', payload: data.uid });
        }

        // Update pin if provided
        if (data.pin !== undefined) {
            store.dispatch(updatePin(data.pin));
        }

        console.log('[Store] Synced data from Arma:', store.getState().accounts);
    } else {
        console.warn('[Store] Invalid data received:', data);
    }
}

// ============================================================================
// INITIALIZATION
// ============================================================================

// Request initial data from Arma on load
if (typeof A3API !== 'undefined') {
    // Delay request slightly to ensure everything is loaded
    setTimeout(() => {
        sendEvent('bank::sync', {});
    }, 100);
}

// Expose sync function globally for Arma to call
if (typeof window !== 'undefined') {
    window.syncDataFromArma = syncDataFromArma;
}
