// @ts-nocheck
import { getDeviceId } from '../lib/device';
import { DEFAULT_LOCALE } from '../i18n/messages';

export interface AchievementBadge {
  id: string;
  title: string;
  description: string;
  earned: boolean;
  progress: number;
  target: number;
}

export interface LeaderboardEntry {
  guest: string;
  photos: number;
  likes: number;
}

export interface TopPhotoHighlight {
  photoId: number;
  guest: string;
  likes: number;
  task?: string | null;
  createdAt: string;
  thumbnail: string | null;
}

export interface TrendingEmotionHighlight {
  emotionId: number;
  name: string;
  count: number;
}

export interface TimelinePoint {
  date: string;
  photos: number;
  guests: number;
}

export interface FeedEntry {
  photoId: number;
  guest: string;
  task?: string | null;
  likes: number;
  createdAt: string;
  thumbnail: string | null;
}

export interface AchievementsPayload {
  summary: {
    totalPhotos: number;
    uniqueGuests: number;
    tasksSolved: number;
    likesTotal: number;
  };
  personal: {
    guestName: string;
    photos: number;
    tasks: number;
    likes: number;
    badges: AchievementBadge[];
  } | null;
  leaderboards: {
    uploads: LeaderboardEntry[];
    likes: LeaderboardEntry[];
  };
  highlights: {
    topPhoto: TopPhotoHighlight | null;
    trendingEmotion: TrendingEmotionHighlight | null;
    timeline: TimelinePoint[];
  };
  feed: FeedEntry[];
}

function toNumber(value: unknown, fallback = 0): number {
  if (typeof value === 'number' && Number.isFinite(value)) {
    return value;
  }
  if (typeof value === 'string' && value !== '') {
    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : fallback;
  }
  return fallback;
}

function safeString(value: unknown): string {
  return typeof value === 'string' ? value : '';
}

type FetchAchievementsOptions = {
  guestName?: string;
  locale?: string;
  signal?: AbortSignal;
  forceRefresh?: boolean;
};

type AchievementsCacheEntry = {
  data: AchievementsPayload;
  etag: string | null;
};

const achievementsCache = new Map<string, AchievementsCacheEntry>();

export async function fetchAchievements(
  eventToken: string,
  options: FetchAchievementsOptions = {}
): Promise<AchievementsPayload> {
  const { guestName, signal, forceRefresh } = options;
  const locale = options.locale ?? DEFAULT_LOCALE;

  const params = new URLSearchParams();
  if (guestName && guestName.trim().length > 0) {
    params.set('guest_name', guestName.trim());
  }
  if (locale) {
    params.set('locale', locale);
  }

  const deviceId = getDeviceId();
  const cacheKey = [eventToken, locale, guestName?.trim() ?? '', deviceId].join(':');
  const cached = forceRefresh ? null : achievementsCache.get(cacheKey);

  const headers: HeadersInit = {
    'X-Device-Id': deviceId,
    'Cache-Control': 'no-store',
    Accept: 'application/json',
    'X-Locale': locale,
  };

  if (cached?.etag) {
    headers['If-None-Match'] = cached.etag;
  }

  const response = await fetch(`/api/v1/events/${encodeURIComponent(eventToken)}/achievements?${params.toString()}`, {
    method: 'GET',
    headers,
    signal,
  });

  if (response.status === 304 && cached) {
    return cached.data;
  }

  if (!response.ok) {
    const message = await response.text();
    throw new Error(message || 'Achievements request failed');
  }

  const json = await response.json();
  const summary = json.summary ?? {};
  const personalRaw = json.personal ?? null;
  const leaderboards = json.leaderboards ?? {};
  const highlights = json.highlights ?? {};
  const feedRaw = Array.isArray(json.feed) ? json.feed : [];

  const personal = personalRaw
    ? {
        guestName: safeString(personalRaw.guest_name),
        photos: toNumber(personalRaw.photos),
        tasks: toNumber(personalRaw.tasks),
        likes: toNumber(personalRaw.likes),
        badges: Array.isArray(personalRaw.badges)
          ? personalRaw.badges.map((badge): AchievementBadge => {
              const record = badge as Record<string, unknown>;
              return {
                id: safeString(record.id),
                title: safeString(record.title),
                description: safeString(record.description),
                earned: Boolean(record.earned),
                progress: toNumber(record.progress),
                target: toNumber(record.target, 1),
              };
            })
          : [],
      }
    : null;

  const uploadsBoard = Array.isArray(leaderboards.uploads)
    ? leaderboards.uploads.map((row): LeaderboardEntry => {
        const record = row as Record<string, unknown>;
        return {
          guest: safeString(record.guest),
          photos: toNumber(record.photos),
          likes: toNumber(record.likes),
        };
      })
    : [];

  const likesBoard = Array.isArray(leaderboards.likes)
    ? leaderboards.likes.map((row): LeaderboardEntry => {
        const record = row as Record<string, unknown>;
        return {
          guest: safeString(record.guest),
          photos: toNumber(record.photos),
          likes: toNumber(record.likes),
        };
      })
    : [];

  const topPhotoRaw = highlights.top_photo ?? null;
  const topPhoto = topPhotoRaw
    ? {
        photoId: toNumber(topPhotoRaw.photo_id),
        guest: safeString(topPhotoRaw.guest),
        likes: toNumber(topPhotoRaw.likes),
        task: topPhotoRaw.task ?? null,
        createdAt: safeString(topPhotoRaw.created_at),
        thumbnail: topPhotoRaw.thumbnail ? safeString(topPhotoRaw.thumbnail) : null,
      }
    : null;

  const trendingRaw = highlights.trending_emotion ?? null;
  const trendingEmotion = trendingRaw
    ? {
        emotionId: toNumber(trendingRaw.emotion_id),
        name: safeString(trendingRaw.name),
        count: toNumber(trendingRaw.count),
      }
    : null;

  const timeline = Array.isArray(highlights.timeline)
    ? highlights.timeline.map((row): TimelinePoint => {
        const record = row as Record<string, unknown>;
        return {
          date: safeString(record.date),
          photos: toNumber(record.photos),
          guests: toNumber(record.guests),
        };
      })
    : [];

  const feed = feedRaw.map((row): FeedEntry => {
    const record = row as Record<string, unknown>;
    return {
      photoId: toNumber(record.photo_id),
      guest: safeString(record.guest),
      task: (record as { task?: string }).task ?? null,
      likes: toNumber(record.likes),
      createdAt: safeString(record.created_at),
      thumbnail: record.thumbnail ? safeString(record.thumbnail) : null,
    };
  });

  const payload: AchievementsPayload = {
    summary: {
      totalPhotos: toNumber(summary.total_photos),
      uniqueGuests: toNumber(summary.unique_guests),
      tasksSolved: toNumber(summary.tasks_solved),
      likesTotal: toNumber(summary.likes_total),
    },
    personal,
    leaderboards: {
      uploads: uploadsBoard,
      likes: likesBoard,
    },
    highlights: {
      topPhoto,
      trendingEmotion,
      timeline,
    },
    feed,
  };

  achievementsCache.set(cacheKey, {
    data: payload,
    etag: response.headers.get('ETag'),
  });

  return payload;
}
