import {
  HERO_ROTATION_START_DATE,
  HERO_ROTATION_TIMEZONE,
  type HeroVideoSource,
  getHeroVideoSets,
} from '@/config/heroVideos';

const MS_PER_DAY = 86_400_000;

const BUDAPEST_DATE_FORMATTER = new Intl.DateTimeFormat('en', {
  timeZone: HERO_ROTATION_TIMEZONE,
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
});

interface HeroVideoSelection {
  video: HeroVideoSource;
  activeIndex: number;
  total: number;
}

function parseIsoDateToUtcTimestamp(date: string): number {
  const [year, month, day] = date.split('-').map(Number);
  return Date.UTC(year, month - 1, day);
}

function positiveModulo(value: number, divisor: number): number {
  return ((value % divisor) + divisor) % divisor;
}

function getBudapestDateString(now: Date): string {
  const parts = BUDAPEST_DATE_FORMATTER.formatToParts(now);
  const year = parts.find((part) => part.type === 'year')?.value;
  const month = parts.find((part) => part.type === 'month')?.value;
  const day = parts.find((part) => part.type === 'day')?.value;

  if (!year || !month || !day) {
    throw new Error('Failed to resolve Budapest date parts');
  }

  return `${year}-${month}-${day}`;
}

function getRotatingIndex(now: Date, total: number): number {
  const todayDateInBudapest = getBudapestDateString(now);
  const startUtcTimestamp = parseIsoDateToUtcTimestamp(HERO_ROTATION_START_DATE);
  const todayUtcTimestamp = parseIsoDateToUtcTimestamp(todayDateInBudapest);
  const dayOffset = Math.floor((todayUtcTimestamp - startUtcTimestamp) / MS_PER_DAY);

  return positiveModulo(dayOffset, total);
}

export function getHeroVideoSelection(locale: string): HeroVideoSelection {
  const videos = getHeroVideoSets(locale);
  const total = videos.length;
  if (total === 0) {
    throw new Error('Hero videos are not configured');
  }

  const activeIndex = getRotatingIndex(new Date(), total);

  return {
    video: videos[activeIndex],
    activeIndex,
    total,
  };
}
