/**
 * Local storage utilities for chat persistence
 * Provides fast local access while syncing with the database
 */

interface Message {
  id: string;
  role: 'user' | 'assistant';
  content: string;
}

interface Chat {
  id: string;
  title: string;
  updatedAt: string;
  messages: Message[];
  pinned?: boolean;
}

const CHATS_STORAGE_KEY = 'chat-gpz-chats';

/**
 * Get all chats from localStorage
 */
export function getLocalChats(): Chat[] {
  if (typeof window === 'undefined') {
    return [];
  }
  try {
    const stored = localStorage.getItem(CHATS_STORAGE_KEY);
    if (!stored) {
      return [];
    }
    return JSON.parse(stored) as Chat[];
  } catch (e) {
    console.error('Failed to parse local chats:', e);
    return [];
  }
}

/**
 * Save all chats to localStorage
 */
export function setLocalChats(chats: Chat[]): void {
  if (typeof window === 'undefined') {
    return;
  }
  try {
    localStorage.setItem(CHATS_STORAGE_KEY, JSON.stringify(chats));
  } catch (e) {
    console.error('Failed to save local chats:', e);
  }
}

/**
 * Get a single chat by ID from localStorage
 */
export function getLocalChat(chatId: string): Chat | null {
  const chats = getLocalChats();
  return chats.find((c) => c.id === chatId) || null;
}

/**
 * Save or update a single chat in localStorage
 */
export function saveLocalChat(chat: Chat): void {
  const chats = getLocalChats();
  const existingIndex = chats.findIndex((c) => c.id === chat.id);

  if (existingIndex >= 0) {
    chats[existingIndex] = chat;
  } else {
    chats.unshift(chat); // Add to beginning (most recent)
  }

  setLocalChats(chats);
}

/**
 * Add a message to an existing chat in localStorage
 */
export function addMessageToLocalChat(chatId: string, message: Message): void {
  const chats = getLocalChats();
  const chat = chats.find((c) => c.id === chatId);

  if (chat) {
    chat.messages.push(message);
    chat.updatedAt = new Date().toISOString();
    setLocalChats(chats);
  }
}

/**
 * Delete a chat from localStorage
 */
export function deleteLocalChat(chatId: string): void {
  const chats = getLocalChats();
  const filtered = chats.filter((c) => c.id !== chatId);
  setLocalChats(filtered);
}

/**
 * Merge remote chats with local chats
 * Remote chats take precedence for conflicts (based on updatedAt)
 */
export function mergeChats(localChats: Chat[], remoteChats: Chat[]): Chat[] {
  const chatMap = new Map<string, Chat>();

  // Add local chats first
  for (const chat of localChats) {
    chatMap.set(chat.id, chat);
  }

  // Override with remote chats (they're the source of truth)
  for (const chat of remoteChats) {
    const local = chatMap.get(chat.id);
    if (!local || new Date(chat.updatedAt) >= new Date(local.updatedAt)) {
      chatMap.set(chat.id, chat);
    }
  }

  // Sort by updatedAt descending
  return Array.from(chatMap.values()).sort(
    (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
  );
}

/**
 * Clear all local chats (useful for logout)
 */
export function clearLocalChats(): void {
  if (typeof window === 'undefined') {
    return;
  }
  localStorage.removeItem(CHATS_STORAGE_KEY);
}

// ============================================
// Scroll Position Storage
// ============================================

const SCROLL_POSITIONS_KEY = 'chat-gpz-scroll-positions';

interface ScrollPositions {
  [chatId: string]: number;
}

/**
 * Get all stored scroll positions
 */
function getScrollPositions(): ScrollPositions {
  if (typeof window === 'undefined') {
    return {};
  }
  try {
    const stored = localStorage.getItem(SCROLL_POSITIONS_KEY);
    if (!stored) {
      return {};
    }
    return JSON.parse(stored) as ScrollPositions;
  } catch {
    return {};
  }
}

/**
 * Save scroll positions to localStorage
 */
function setScrollPositions(positions: ScrollPositions): void {
  if (typeof window === 'undefined') {
    return;
  }
  try {
    localStorage.setItem(SCROLL_POSITIONS_KEY, JSON.stringify(positions));
  } catch {
    // Ignore storage errors
  }
}

/**
 * Get scroll position for a specific chat
 * Returns null if no position saved (indicating should scroll to bottom for new chats)
 */
export function getScrollPosition(chatId: string): number | null {
  const positions = getScrollPositions();
  return positions[chatId] ?? null;
}

/**
 * Save scroll position for a specific chat
 */
export function saveScrollPosition(chatId: string, position: number): void {
  const positions = getScrollPositions();
  positions[chatId] = position;
  setScrollPositions(positions);
}

/**
 * Delete scroll position for a chat (when chat is deleted)
 */
export function deleteScrollPosition(chatId: string): void {
  const positions = getScrollPositions();
  delete positions[chatId];
  setScrollPositions(positions);
}
