import { format, formatDistanceToNow } from 'date-fns';

const toValidDate = (date: string | Date | null | undefined): Date | null => {
  if (!date) return null;
  const d = new Date(date);
  return isNaN(d.getTime()) ? null : d;
};

export const formatDate = (date: string | Date | null | undefined) => {
  const d = toValidDate(date);
  return d ? format(d, 'MMMM d, yyyy') : '—';
};

export const formatDateTime = (date: string | Date | null | undefined) => {
  const d = toValidDate(date);
  return d ? format(d, 'MMM d, yyyy h:mm a') : '—';
};

export const timeAgo = (date: string | Date | null | undefined) => {
  const d = toValidDate(date);
  return d ? formatDistanceToNow(d, { addSuffix: true }) : '';
};

export const slugify = (text: string) =>
  text.toLowerCase().trim().replace(/[\s\W-]+/g, '-').replace(/^-+|-+$/g, '').substring(0, 200);

export const truncate = (text: string, length = 150) =>
  text.length > length ? text.substring(0, length) + '...' : text;

export const readingTime = (html: string | null | undefined) => {
  if (!html) return 1;
  const words = html.replace(/<[^>]*>/g, ' ').trim().split(/\s+/).filter(Boolean).length;
  return Math.max(1, Math.round(words / 200));
};

export const getImageUrl = (path: string | null | undefined) => {
  if (!path) return '/placeholder-news.svg';
  if (path.startsWith('http')) return path;
  // Uploaded media (`/uploads/...`) is served by the backend, which now exposes
  // it at `<API_URL>/uploads/...` (the backend serves both /uploads and
  // /api/uploads), so keep the API base intact rather than stripping `/api`.
  const base = process.env.NEXT_PUBLIC_API_URL || '';
  return `${base}${path}`;
};

export const ROLES = ['super_admin', 'admin', 'editor', 'author', 'moderator', 'reader'] as const;
export type Role = typeof ROLES[number];

export const hasRole = (userRole: Role, ...allowedRoles: Role[]) =>
  allowedRoles.includes(userRole);
