export { useNewsFeed, newsFeedReducer, createNewsFeedState } from '../hooks/useNewsFeed';
export type {
  HighlightReason,
  NewsArticle,
  NewsSentiment,
  NewsSourceStatus,
  QueryNewsFeedRequest,
  QueryNewsFeedResponse,
  RefreshNewsFeedRequest,
  RefreshNewsFeedResult,
  UpdateNewsArticleStateRequest,
} from '../types/news';

import type {
  HighlightReason,
  NewsArticle,
  NewsSentiment,
} from '../types/news';

const compareNewsArticles = (left: NewsArticle, right: NewsArticle) => {
  if (right.publishedTs !== left.publishedTs) {
    return right.publishedTs - left.publishedTs;
  }

  if (left.highlightReason && !right.highlightReason) {
    return -1;
  }

  if (!left.highlightReason && right.highlightReason) {
    return 1;
  }

  return left.id.localeCompare(right.id);
};

export const sortNewsArticlesChronologically = (articles: NewsArticle[]) =>
  [...articles].sort(compareNewsArticles);

export const partitionNewsSummaryArticles = (
  articles: NewsArticle[],
): { highlights: NewsArticle[]; recent: NewsArticle[] } => {
  const sortedArticles = sortNewsArticlesChronologically(articles);
  const highlights = sortedArticles
    .filter((article) => article.highlightReason)
    .slice(0, 4);
  const highlightIds = new Set(highlights.map((article) => article.id));
  const recent = sortedArticles
    .filter((article) => !highlightIds.has(article.id))
    .slice(0, 6);

  return { highlights, recent };
};

export const formatNewsRelativeTime = (publishedAt: string, now = new Date()) => {
  const publishedDate = new Date(publishedAt);
  const diffMs = Math.max(0, now.getTime() - publishedDate.getTime());
  const minutes = Math.floor(diffMs / (1000 * 60));

  if (minutes < 1) {
    return 'just now';
  }
  if (minutes < 60) {
    return `${minutes}m ago`;
  }

  const hours = Math.floor(minutes / 60);
  if (hours < 24) {
    return `${hours}h ago`;
  }

  const days = Math.floor(hours / 24);
  return `${days}d ago`;
};

export const newsSentimentLabel = (sentiment: NewsSentiment) => {
  switch (sentiment) {
    case 'BULL':
      return 'Bullish';
    case 'BEAR':
      return 'Bearish';
    default:
      return 'Neutral';
  }
};

export const highlightReasonLabel = (reason?: HighlightReason) => {
  switch (reason) {
    case 'breaking_keyword':
      return 'Breaking';
    case 'macro_event':
      return 'Macro';
    case 'strong_sentiment':
      return 'High Conviction';
    case 'ticker_detected':
      return 'Ticker';
    case 'recent_high_value':
      return 'Fresh';
    default:
      return 'Standard';
  }
};

export const newsSentimentTone = (sentiment: NewsSentiment) => {
  switch (sentiment) {
    case 'BULL':
      return 'bullish';
    case 'BEAR':
      return 'bearish';
    default:
      return 'neutral';
  }
};

export const buildNewsTickerCommand = (ticker: string) => `/news ${ticker.trim().toUpperCase()}`;
