import React, { createContext, useContext, useEffect, useMemo, useState, useCallback } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import type { PostSummary } from '@ai-radar/shared';

/**
 * Saved stories.
 *
 * On-device only. Syncing reading state would mean accounts, which the
 * brief rules out — and the value of Saved is "read this on the train",
 * which one device satisfies completely.
 *
 * The whole summary is stored, not just the slug, so the Saved list
 * renders offline and survives the story dropping out of the API's
 * recency window.
 */
const KEY = 'airadar.saved';
const LIMIT = 200;

interface SavedStore {
  items: PostSummary[];
  isSaved: (slug: string) => boolean;
  toggle: (post: PostSummary) => void;
  clear: () => void;
  ready: boolean;
}

const SavedContext = createContext<SavedStore | null>(null);

export function SavedProvider({ children }: { children: React.ReactNode }) {
  const [items, setItems] = useState<PostSummary[]>([]);
  const [ready, setReady] = useState(false);

  useEffect(() => {
    (async () => {
      try {
        const raw = await AsyncStorage.getItem(KEY);
        if (raw) {
          const parsed: unknown = JSON.parse(raw);
          if (Array.isArray(parsed)) setItems(parsed as PostSummary[]);
        }
      } catch {
        // Corrupt or unavailable storage: start empty rather than crash.
        // Losing a saved list is bad; refusing to open the app is worse.
      } finally {
        setReady(true);
      }
    })();
  }, []);

  const persist = useCallback((next: PostSummary[]) => {
    setItems(next);
    void AsyncStorage.setItem(KEY, JSON.stringify(next)).catch(() => {});
  }, []);

  const isSaved = useCallback((slug: string) => items.some((i) => i.slug === slug), [items]);

  const toggle = useCallback(
    (post: PostSummary) => {
      const exists = items.some((i) => i.slug === post.slug);
      // Newest first, and capped: an unbounded list in AsyncStorage grows
      // until reads get slow, and nobody scrolls past 200 saved stories.
      const next = exists
        ? items.filter((i) => i.slug !== post.slug)
        : [post, ...items].slice(0, LIMIT);
      persist(next);
    },
    [items, persist],
  );

  const clear = useCallback(() => persist([]), [persist]);

  const value = useMemo<SavedStore>(
    () => ({ items, isSaved, toggle, clear, ready }),
    [items, isSaved, toggle, clear, ready],
  );

  return <SavedContext.Provider value={value}>{children}</SavedContext.Provider>;
}

export function useSaved(): SavedStore {
  const ctx = useContext(SavedContext);
  if (!ctx) throw new Error('useSaved must be used inside SavedProvider');
  return ctx;
}
