/**
 * @format
 * @fileoverview State management system for the phone application. Implements a simple pub/sub pattern for managing global application state.
 */

/**
 * Initial application state containing mock data for development.
 * @type {Object}
 */
const initialAppState = {
    // Navigation state
    currentApp: 'home',
    showModal: false,

    // Contact management
    contacts: [
        {
            id: 1,
            name: 'John Doe',
            phone: '+1 (555) 123-4567',
            avatar: 'JD',
        },
        {
            id: 2,
            name: 'Jane Smith',
            phone: '+1 (555) 987-6543',
            avatar: 'JS',
        },
        {
            id: 3,
            name: 'Mike Johnson',
            phone: '+1 (555) 456-7890',
            avatar: 'MJ',
        },
        {
            id: 4,
            name: 'Sarah Wilson',
            phone: '+1 (555) 321-0987',
            avatar: 'SW',
        },
    ],

    // Message management
    messages: [
        {
            id: 1,
            contactId: 1,
            contactName: 'John Doe',
            lastMessage: 'Hey, how are you doing?',
            timestamp: new Date(Date.now() - 1000 * 60 * 30), // 30 minutes ago
            unread: 0,
            conversation: [
                {
                    id: 1,
                    text: 'Hey, how are you doing?',
                    sender: 'contact',
                    timestamp: new Date(Date.now() - 1000 * 60 * 30),
                },
                {
                    id: 2,
                    text: 'Are we still on for lunch tomorrow?',
                    sender: 'contact',
                    timestamp: new Date(Date.now() - 1000 * 60 * 25),
                },
            ],
        },
        {
            id: 2,
            contactId: 2,
            contactName: 'Jane Smith',
            lastMessage: 'Thanks for your help!',
            timestamp: new Date(Date.now() - 1000 * 60 * 60 * 2), // 2 hours ago
            unread: 0,
            conversation: [
                {
                    id: 1,
                    text: 'Can you help me with the project?',
                    sender: 'contact',
                    timestamp: new Date(Date.now() - 1000 * 60 * 60 * 3),
                },
                {
                    id: 2,
                    text: 'Sure, what do you need?',
                    sender: 'user',
                    timestamp: new Date(Date.now() - 1000 * 60 * 60 * 2.5),
                },
                {
                    id: 3,
                    text: 'Thanks for your help!',
                    sender: 'contact',
                    timestamp: new Date(Date.now() - 1000 * 60 * 60 * 2),
                },
            ],
        },
        {
            id: 3,
            contactId: 3,
            contactName: 'Mike Johnson',
            lastMessage: 'See you later!',
            timestamp: new Date(Date.now() - 1000 * 60 * 60 * 24), // 1 day ago
            unread: 0,
            conversation: [
                {
                    id: 1,
                    text: 'Meeting at 3 PM today',
                    sender: 'user',
                    timestamp: new Date(Date.now() - 1000 * 60 * 60 * 25),
                },
                {
                    id: 2,
                    text: 'Perfect, see you there!',
                    sender: 'contact',
                    timestamp: new Date(Date.now() - 1000 * 60 * 60 * 24.5),
                },
                {
                    id: 3,
                    text: 'See you later!',
                    sender: 'contact',
                    timestamp: new Date(Date.now() - 1000 * 60 * 60 * 24),
                },
            ],
        },
    ],

    // Server-synced data (non-UI mapped)
    // Keep raw server payloads separate to avoid breaking current UI
    rawMessages: [],
    emails: [],
    selectedConversationRaw: null,

    // UI state
    selectedContact: null,
    selectedConversation: null,
    newMessage: '',
    currentUid: null,
    
    // Clock state
    clockMode: 'world',
    worldClocks: [],
    timers: [],
    alarms: [],
    clockSettings: { format24h: true },
    
    // Notes state
    notes: [],
    currentNote: null,
    showNoteEditor: false,

    // Calendar state
    events: [],
    currentEvent: null,
    showEventEditor: false,
};

/**
 * Manages global application state using a publish/subscribe pattern.
 * Provides methods for accessing and updating state while notifying subscribers.
 *
 * @class
 * @example
 * const state = new StateManager({ count: 0 });
 * state.subscribe((newState, prevState) => {
 *   console.log('State changed:', newState);
 * });
 * state.setState({ count: 1 });
 */
class StateManager {
    /**
     * Creates a new StateManager instance.
     * @param {Object} initialState - Initial state object
     */
    constructor(initialState = {}) {
        /** @private */
        this.state = { ...initialState };
        /** @private */
        this.subscribers = new Set();
    }

    /**
     * Gets current state object.
     * @returns {Object} Copy of current state
     */
    getState() {
        return { ...this.state };
    }

    /**
     * Updates state and notifies subscribers.
     * @param {Object} updates - Object containing state updates
     */
    setState(updates) {
        const prevState = { ...this.state };
        this.state = { ...this.state, ...updates };
        this.notifySubscribers(prevState, this.state);
    }

    /**
     * Subscribes to state changes.
     * @param {Function} callback - Function to call when state changes
     * @returns {Function} Unsubscribe function
     */
    subscribe(callback) {
        this.subscribers.add(callback);
        return () => this.subscribers.delete(callback);
    }

    /**
     * Notifies subscribers of state changes.
     * @private
     * @param {Object} prevState - Previous state
     * @param {Object} newState - New state
     */
    notifySubscribers(prevState, newState) {
        this.subscribers.forEach((callback) => {
            callback(newState, prevState);
        });
    }
}

// Create and export global state instance
const globalState = new StateManager(initialAppState);
