/**
 * user-store.js
 * User state management store
 * Manages current logged-in user, preferences, and integrations
 * MVP3: Integrates with backend API while maintaining localStorage persistence
 */

import apiClient from '../services/api-client.js';

export class UserStore {
  constructor() {
    // Current user state
    this.currentUser = this.loadUserFromStorage();
    this.isAuthenticated = !!this.currentUser;
    this.isLoading = false;

    // User preferences
    this.preferences = this.loadPreferencesFromStorage() || this.getDefaultPreferences();

    // User integrations (API keys, tokens)
    this.integrations = this.loadIntegrationsFromStorage() || {};

    // Event listeners
    this.listeners = new Set();

    // Try to verify current user with API on initialization
    if (this.isAuthenticated) {
      this.verifyUserWithAPI();
    }
  }

  /**
   * Get default user preferences
   * @returns {Object} Default preferences
   */
  getDefaultPreferences() {
    return {
      theme: 'dark',
      language: 'en',
      lastTeam: 'ui',
      chatCollapsedState: true,
      notifications: {
        enabled: true,
        email: true,
        desktop: true
      },
      layout: {
        showChat: true,
        showPanel: true,
        sidebarWidth: 250
      },
      editor: {
        fontSize: 13,
        fontFamily: 'Monaco, Menlo, Ubuntu Mono, monospace',
        lineHeight: 1.6
      }
    };
  }

  /**
   * Load user from localStorage
   * @returns {Object|null} User object or null
   */
  loadUserFromStorage() {
    try {
      const stored = localStorage.getItem('current_user');
      return stored ? JSON.parse(stored) : null;
    } catch (error) {
      console.warn('[UserStore] Failed to parse stored user:', error);
      return null;
    }
  }

  /**
   * Load preferences from localStorage
   * @returns {Object|null} Preferences or null
   */
  loadPreferencesFromStorage() {
    try {
      const stored = localStorage.getItem('user_preferences');
      return stored ? JSON.parse(stored) : null;
    } catch (error) {
      console.warn('[UserStore] Failed to parse stored preferences:', error);
      return null;
    }
  }

  /**
   * Load integrations from localStorage
   * @returns {Object} Integrations object
   */
  loadIntegrationsFromStorage() {
    try {
      const stored = localStorage.getItem('user_integrations');
      return stored ? JSON.parse(stored) : {};
    } catch (error) {
      console.warn('[UserStore] Failed to parse stored integrations:', error);
      return {};
    }
  }

  /**
   * Persist user to localStorage
   */
  persistUser() {
    if (this.currentUser) {
      localStorage.setItem('current_user', JSON.stringify(this.currentUser));
    } else {
      localStorage.removeItem('current_user');
    }
  }

  /**
   * Persist preferences to localStorage
   */
  persistPreferences() {
    localStorage.setItem('user_preferences', JSON.stringify(this.preferences));
  }

  /**
   * Persist integrations to localStorage
   */
  persistIntegrations() {
    localStorage.setItem('user_integrations', JSON.stringify(this.integrations));
  }

  /**
   * Verify current user with API
   */
  async verifyUserWithAPI() {
    try {
      const user = await apiClient.getMe();
      this.currentUser = user;
      this.isAuthenticated = true;
      this.persistUser();
      this.notifyListeners();
    } catch (error) {
      console.warn('[UserStore] Failed to verify user with API:', error);
      // Fall back to localStorage user
    }
  }

  /**
   * Register new user
   * @param {string} email - User email
   * @param {string} password - User password
   * @param {string} name - User name
   * @returns {Object} Created user
   */
  async register(email, password, name) {
    this.isLoading = true;
    this.notifyListeners();

    try {
      const user = await apiClient.register(email, password, name);
      this.currentUser = user;
      this.isAuthenticated = true;
      this.persistUser();
      this.notifyListeners();
      return user;
    } catch (error) {
      this.isLoading = false;
      this.notifyListeners();
      throw error;
    }
  }

  /**
   * Login user
   * @param {string} email - User email
   * @param {string} password - User password
   * @returns {Object} Logged-in user
   */
  async login(email, password) {
    this.isLoading = true;
    this.notifyListeners();

    try {
      const user = await apiClient.login(email, password);
      this.currentUser = user;
      this.isAuthenticated = true;
      this.persistUser();
      this.isLoading = false;
      this.notifyListeners();
      return user;
    } catch (error) {
      this.isLoading = false;
      this.isAuthenticated = false;
      this.notifyListeners();
      throw error;
    }
  }

  /**
   * Logout user
   */
  async logout() {
    try {
      await apiClient.logout();
    } catch (error) {
      console.warn('[UserStore] API logout failed:', error);
    }

    this.currentUser = null;
    this.isAuthenticated = false;
    this.integrations = {};

    localStorage.removeItem('current_user');
    localStorage.removeItem('user_preferences');
    localStorage.removeItem('user_integrations');
    localStorage.removeItem('access_token');
    localStorage.removeItem('refresh_token');

    this.notifyListeners();
  }

  /**
   * Get current user
   * @returns {Object|null} Current user or null
   */
  getCurrentUser() {
    return this.currentUser;
  }

  /**
   * Check if user is authenticated
   * @returns {boolean} Authentication status
   */
  isLoggedIn() {
    return this.isAuthenticated;
  }

  /**
   * Update user profile
   * @param {Object} updates - {name, email, avatar, bio}
   * @returns {Object} Updated user
   */
  async updateProfile(updates) {
    try {
      // Try API first if authenticated
      if (this.isAuthenticated && apiClient.accessToken) {
        const updated = await apiClient.updateUser(this.currentUser.id, updates);
        this.currentUser = { ...this.currentUser, ...updated };
        this.persistUser();
        this.notifyListeners();
        return updated;
      }
    } catch (error) {
      console.warn('[UserStore] API profile update failed:', error);
    }

    // Fallback to local update
    this.currentUser = { ...this.currentUser, ...updates };
    this.persistUser();
    this.notifyListeners();
    return this.currentUser;
  }

  /**
   * Update user preferences
   * @param {Object} updates - Partial preference updates
   * @returns {Object} Updated preferences
   */
  updatePreferences(updates) {
    this.preferences = { ...this.preferences, ...updates };

    // Deep merge nested objects
    if (updates.notifications) {
      this.preferences.notifications = { ...this.preferences.notifications, ...updates.notifications };
    }
    if (updates.layout) {
      this.preferences.layout = { ...this.preferences.layout, ...updates.layout };
    }
    if (updates.editor) {
      this.preferences.editor = { ...this.preferences.editor, ...updates.editor };
    }

    this.persistPreferences();
    this.notifyListeners();
    return this.preferences;
  }

  /**
   * Get user preferences
   * @returns {Object} Current preferences
   */
  getPreferences() {
    return { ...this.preferences };
  }

  /**
   * Add or update integration
   * @param {string} service - Service name (figma, jira, github, slack, storybook)
   * @param {string} apiKey - API key or token for the service
   * @param {Object} metadata - Additional metadata (e.g., {projectKey: 'ABC'})
   * @returns {Object} Updated integrations
   */
  setIntegration(service, apiKey, metadata = {}) {
    this.integrations[service] = {
      enabled: !!apiKey,
      apiKey,
      ...metadata,
      lastUpdated: new Date().toISOString()
    };
    this.persistIntegrations();
    this.notifyListeners();
    return this.integrations;
  }

  /**
   * Get specific integration
   * @param {string} service - Service name
   * @returns {Object|null} Integration config or null
   */
  getIntegration(service) {
    return this.integrations[service] || null;
  }

  /**
   * Get all integrations
   * @returns {Object} All integrations
   */
  getIntegrations() {
    return { ...this.integrations };
  }

  /**
   * Remove integration
   * @param {string} service - Service name
   * @returns {Object} Updated integrations
   */
  removeIntegration(service) {
    delete this.integrations[service];
    this.persistIntegrations();
    this.notifyListeners();
    return this.integrations;
  }

  /**
   * Get user avatar (with fallback)
   * @returns {string} Avatar URL or initials
   */
  getAvatar() {
    if (!this.currentUser) return null;
    if (this.currentUser.avatar) return this.currentUser.avatar;

    // Generate initials-based avatar
    const initials = (this.currentUser.name || this.currentUser.email)
      .split(' ')
      .map(n => n[0])
      .join('')
      .toUpperCase();

    return `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect fill='%23007acc' width='32' height='32'/%3E%3Ctext x='50%25' y='50%25' dominant-baseline='middle' text-anchor='middle' fill='white' font-size='14' font-weight='bold' font-family='sans-serif' transform='translate(0, 1)'%3E${initials}%3C/text%3E%3C/svg%3E`;
  }

  /**
   * Get user display name
   * @returns {string} Name or email
   */
  getDisplayName() {
    if (!this.currentUser) return 'Anonymous';
    return this.currentUser.name || this.currentUser.email;
  }

  /**
   * Subscribe to user state changes
   * @param {Function} callback - Called with {currentUser, preferences, integrations, isAuthenticated}
   * @returns {Function} Unsubscribe function
   */
  subscribe(callback) {
    this.listeners.add(callback);
    return () => this.listeners.delete(callback);
  }

  /**
   * Notify all listeners of state changes
   */
  notifyListeners() {
    this.listeners.forEach(listener => listener({
      currentUser: this.currentUser,
      preferences: this.getPreferences(),
      integrations: this.getIntegrations(),
      isAuthenticated: this.isAuthenticated
    }));
  }

  /**
   * Reset to default state
   */
  reset() {
    this.currentUser = null;
    this.isAuthenticated = false;
    this.preferences = this.getDefaultPreferences();
    this.integrations = {};

    localStorage.removeItem('current_user');
    localStorage.removeItem('user_preferences');
    localStorage.removeItem('user_integrations');

    this.notifyListeners();
  }
}

// Singleton instance
let userStoreInstance = null;

export function useUserStore() {
  if (!userStoreInstance) {
    userStoreInstance = new UserStore();
  }
  return userStoreInstance;
}
