/**
 * Sessions Store
 * Zustand store for session management
 */

import { create } from 'zustand';
import { devtools } from 'zustand/middleware';
import {
  authService,
  type ActiveSession,
} from '../services/auth.service';

// ============================================================================
// Types
// ============================================================================

interface SessionsState {
  // State
  sessions: ActiveSession[];
  loading: boolean;
  error: string | null;
  revoking: Set<string>;

  // Actions
  fetchSessions: () => Promise<void>;
  revokeSession: (sessionId: string) => Promise<void>;
  revokeAllSessions: () => Promise<void>;
  clearError: () => void;
}

// ============================================================================
// Store
// ============================================================================

export const useSessionsStore = create<SessionsState>()(
  devtools(
    (set, get) => ({
      // Initial state
      sessions: [],
      loading: false,
      error: null,
      revoking: new Set(),

      // Fetch all active sessions
      fetchSessions: async () => {
        set({ loading: true, error: null });

        try {
          const sessions = await authService.getSessions();
          set({ sessions, loading: false });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to fetch sessions';
          set({ error: errorMessage, loading: false });
          console.error('Error fetching sessions:', error);
        }
      },

      // Revoke a specific session
      revokeSession: async (sessionId: string) => {
        const state = get();

        // Check if this is the current session
        const session = state.sessions.find(s => s.id === sessionId);
        if (session?.isCurrent) {
          // If revoking current session, logout
          await authService.logout();
          window.location.href = '/login';
          return;
        }

        // Add to revoking set
        set({ revoking: new Set(state.revoking).add(sessionId), error: null });

        try {
          await authService.revokeSession(sessionId);

          // Remove from sessions list
          set({
            sessions: state.sessions.filter(s => s.id !== sessionId),
            revoking: new Set([...state.revoking].filter(id => id !== sessionId)),
          });
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to revoke session';
          set({
            error: errorMessage,
            revoking: new Set([...state.revoking].filter(id => id !== sessionId)),
          });
          console.error('Error revoking session:', error);
          throw error;
        }
      },

      // Revoke all sessions (logout from all devices)
      revokeAllSessions: async () => {
        set({ loading: true, error: null });

        try {
          await authService.revokeAllSessions();

          // Clear local auth and redirect to login
          localStorage.removeItem('token');
          localStorage.removeItem('refreshToken');
          window.location.href = '/login';
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : 'Failed to revoke all sessions';
          set({ error: errorMessage, loading: false });
          console.error('Error revoking all sessions:', error);
          throw error;
        }
      },

      // Clear error
      clearError: () => {
        set({ error: null });
      },
    }),
    {
      name: 'sessions-store',
    }
  )
);

// ============================================================================
// Selectors
// ============================================================================

export const useSessions = () => useSessionsStore((state) => state.sessions);
export const useSessionsLoading = () => useSessionsStore((state) => state.loading);
export const useSessionsError = () => useSessionsStore((state) => state.error);
export const useRevoking = () => useSessionsStore((state) => state.revoking);

export default useSessionsStore;
