import { describe, expect, it } from 'bun:test';
import { createNewsFeedState, newsFeedReducer } from './useNewsFeed';
import type { NewsArticle } from '../types/news';

const sampleArticle: NewsArticle = {
  id: 'article-1',
  sourceId: 'sample',
  source: 'Sample Feed',
  headline: 'NVDA beats expectations',
  summary: 'Strong demand lifted guidance.',
  url: 'https://example.com/nvda',
  canonicalUrl: 'https://example.com/nvda',
  publishedAt: '2026-04-08T10:00:00Z',
  publishedTs: 1775642400,
  fetchedAt: '2026-04-08T10:01:00Z',
  sentiment: 'BULL',
  sentimentScore: 0.66,
  highlightReason: 'ticker_detected',
  tickers: ['NVDA'],
  isRead: false,
  isSaved: false,
};

describe('newsFeedReducer', () => {
  it('merges filter updates without dropping existing values', () => {
    const state = createNewsFeedState({ ticker: 'NVDA', limit: 20 });

    const nextState = newsFeedReducer(state, {
      type: 'filters_merged',
      filters: { onlyHighlighted: true },
    });

    expect(nextState.filters).toEqual({
      ticker: 'NVDA',
      limit: 20,
      onlyHighlighted: true,
      offset: 0,
    });
  });

  it('stores query results and clears loading flags', () => {
    const state = newsFeedReducer(createNewsFeedState(), {
      type: 'load_started',
      refresh: false,
    });

    const nextState = newsFeedReducer(state, {
      type: 'load_succeeded',
      articles: [sampleArticle],
      total: 1,
      lastSyncedAt: '2026-04-08T10:05:00Z',
      sources: [],
    });

    expect(nextState.isLoading).toBe(false);
    expect(nextState.total).toBe(1);
    expect(nextState.articles[0]?.id).toBe('article-1');
  });

  it('applies optimistic article state updates', () => {
    const state = newsFeedReducer(createNewsFeedState(), {
      type: 'load_succeeded',
      articles: [sampleArticle],
      total: 1,
      lastSyncedAt: '2026-04-08T10:05:00Z',
      sources: [],
    });

    const nextState = newsFeedReducer(state, {
      type: 'article_updated',
      articleId: 'article-1',
      patch: { isSaved: true, isRead: true },
    });

    expect(nextState.articles[0]?.isSaved).toBe(true);
    expect(nextState.articles[0]?.isRead).toBe(true);
  });
});
