/**
 * Player Statistics and Photo Album System
 *
 * Tracks lifetime statistics and captures memorable life moments.
 * Supports 15+ different statistics and integrates with achievement system.
 */

export type StatName =
  | 'lifetimeEarnings'
  | 'lifetimeSpending'
  | 'totalRelationships'
  | 'totalActivities'
  | 'totalConversations'
  | 'totalYearsLived'
  | 'totalDeaths'
  | 'highestJobLevel'
  | 'maxAffinityReached'
  | 'peopleDated'
  | 'timesFired'
  | 'yearsMarried'
  | 'jobCount'
  | 'childrenCount'
  | 'friendsCount';

export type BooleanStatName = 'everMarried';

export interface PlayerStatistics {
  playerId: string;
  lifetimeEarnings: number;
  lifetimeSpending: number;
  totalRelationships: number;
  totalActivities: number;
  totalConversations: number;
  totalYearsLived: number;
  totalDeaths: number;
  highestJobLevel: number;
  maxAffinityReached: number;
  peopleDated: number;
  timesFired: number;
  yearsMarried: number;
  jobCount: number;
  childrenCount: number;
  friendsCount: number;
  everMarried: boolean;
}

export interface PhotoMemory {
  id: string;
  eventType: string;
  eventDescription: string;
  gameDate: string;
  characterAge: number;
  snapshotData: Record<string, unknown>;
  createdAt: string;
}

// In-memory player statistics storage (replace with database in production)
const playerStats: Map<string, PlayerStatistics> = new Map();
const photoAlbum: Map<string, PhotoMemory[]> = new Map();
let photoIdCounter = 0;

/**
 * Get default statistics
 */
function getDefaultStatistics(playerId: string): PlayerStatistics {
  return {
    playerId,
    lifetimeEarnings: 0,
    lifetimeSpending: 0,
    totalRelationships: 0,
    totalActivities: 0,
    totalConversations: 0,
    totalYearsLived: 0,
    totalDeaths: 0,
    highestJobLevel: 0,
    maxAffinityReached: 0,
    peopleDated: 0,
    timesFired: 0,
    yearsMarried: 0,
    jobCount: 0,
    childrenCount: 0,
    friendsCount: 0,
    everMarried: false,
  };
}

/**
 * Create initial statistics record for new player
 */
export function initializePlayerStatistics(playerId: string): boolean {
  if (playerStats.has(playerId)) {
    return true; // Already initialized
  }

  playerStats.set(playerId, getDefaultStatistics(playerId));
  console.log(`Initialized statistics for player ${playerId}`);
  return true;
}

/**
 * Increment a player statistic by a specified amount
 */
export function incrementStat(playerId: string, statName: StatName, amount = 1): boolean {
  if (amount <= 0) {
    console.error(`Invalid increment amount for player ${playerId}: ${amount} (must be positive)`);
    return false;
  }

  let stats = playerStats.get(playerId);
  if (!stats) {
    initializePlayerStatistics(playerId);
    stats = playerStats.get(playerId);
  }

  if (!stats) return false;

  stats[statName] += amount;
  console.log(`Player ${playerId}: ${statName} incremented by ${amount}`);
  return true;
}

/**
 * Set a player statistic to a specific value
 * Used for 'highest' or 'max' type stats that track records
 */
export function updateStat(playerId: string, statName: StatName, value: number): boolean {
  let stats = playerStats.get(playerId);
  if (!stats) {
    initializePlayerStatistics(playerId);
    stats = playerStats.get(playerId);
  }

  if (!stats) return false;

  stats[statName] = value;
  console.log(`Player ${playerId}: ${statName} set to ${value}`);
  return true;
}

/**
 * Set a boolean statistic
 */
export function setBooleanStat(playerId: string, statName: BooleanStatName, value: boolean): boolean {
  let stats = playerStats.get(playerId);
  if (!stats) {
    initializePlayerStatistics(playerId);
    stats = playerStats.get(playerId);
  }

  if (!stats) return false;

  stats[statName] = value;
  console.log(`Player ${playerId}: ${statName} set to ${value}`);
  return true;
}

/**
 * Get all statistics for a player
 */
export function getPlayerStatistics(playerId: string): PlayerStatistics {
  let stats = playerStats.get(playerId);
  if (!stats) {
    initializePlayerStatistics(playerId);
    stats = playerStats.get(playerId);
  }

  return stats ?? getDefaultStatistics(playerId);
}

// =====================================================
// PHOTO ALBUM SYSTEM
// =====================================================

/**
 * Capture a memorable life moment in the photo album
 */
export function capturePhotoMemory(
  playerId: string,
  eventType: string,
  description: string,
  snapshotData: Record<string, unknown>,
  characterAge?: number,
  gameDate?: Date
): string | null {
  try {
    // Generate unique photo ID
    const photoId = `photo_${++photoIdCounter}_${Date.now()}`;

    const memory: PhotoMemory = {
      id: photoId,
      eventType,
      eventDescription: description,
      gameDate: (gameDate ?? new Date()).toISOString(),
      characterAge: characterAge ?? 0,
      snapshotData,
      createdAt: new Date().toISOString(),
    };

    let album = photoAlbum.get(playerId);
    if (!album) {
      album = [];
      photoAlbum.set(playerId, album);
    }

    album.push(memory);

    console.log(`Captured photo memory for player ${playerId}: ${eventType} - ${description}`);
    return photoId;
  } catch (error) {
    console.error(`Error capturing photo memory for player ${playerId}:`, error);
    return null;
  }
}

/**
 * Get photo memories for a player
 */
export function getPhotoAlbum(playerId: string, limit = 50, offset = 0): PhotoMemory[] {
  const album = photoAlbum.get(playerId);
  if (!album) return [];

  // Sort by game date descending
  const sorted = [...album].sort(
    (a, b) => new Date(b.gameDate).getTime() - new Date(a.gameDate).getTime()
  );

  return sorted.slice(offset, offset + limit);
}

/**
 * Get total count of photo memories for a player
 */
export function getPhotoAlbumCount(playerId: string): number {
  const album = photoAlbum.get(playerId);
  return album?.length ?? 0;
}

/**
 * Get all photo memories of a specific type for a player
 */
export function getPhotosByType(playerId: string, eventType: string): PhotoMemory[] {
  const album = photoAlbum.get(playerId);
  if (!album) return [];

  return album
    .filter(photo => photo.eventType === eventType)
    .sort((a, b) => new Date(b.gameDate).getTime() - new Date(a.gameDate).getTime());
}

// =====================================================
// INTEGRATION HELPERS
// =====================================================

/**
 * Track money earned by player
 */
export function trackMoneyEarned(playerId: string, amount: number): void {
  incrementStat(playerId, 'lifetimeEarnings', amount);
}

/**
 * Track money spent by player
 */
export function trackMoneySpent(playerId: string, amount: number): void {
  incrementStat(playerId, 'lifetimeSpending', amount);
}

/**
 * Track new relationship formed
 */
export function trackRelationshipFormed(playerId: string): void {
  incrementStat(playerId, 'totalRelationships', 1);
}

/**
 * Track activity completion
 */
export function trackActivityCompleted(playerId: string): void {
  incrementStat(playerId, 'totalActivities', 1);
}

/**
 * Track conversation with NPC
 */
export function trackConversation(playerId: string): void {
  incrementStat(playerId, 'totalConversations', 1);
}

/**
 * Track death event
 */
export function trackDeath(playerId: string, yearsLived: number): void {
  incrementStat(playerId, 'totalDeaths', 1);
  incrementStat(playerId, 'totalYearsLived', yearsLived);
}

/**
 * Track job obtained
 */
export function trackJobObtained(playerId: string): void {
  incrementStat(playerId, 'jobCount', 1);
}

/**
 * Track getting fired
 */
export function trackFired(playerId: string): void {
  incrementStat(playerId, 'timesFired', 1);
}

/**
 * Track child born
 */
export function trackChildBorn(playerId: string): void {
  incrementStat(playerId, 'childrenCount', 1);
}

/**
 * Track friend made
 */
export function trackFriendMade(playerId: string): void {
  incrementStat(playerId, 'friendsCount', 1);
}

/**
 * Track dating
 */
export function trackDating(playerId: string): void {
  incrementStat(playerId, 'peopleDated', 1);
}

/**
 * Track marriage
 */
export function trackMarriage(playerId: string): void {
  setBooleanStat(playerId, 'everMarried', true);
  incrementStat(playerId, 'yearsMarried', 1);
}

/**
 * Update highest job level if new level is higher
 */
export function trackJobLevel(playerId: string, level: number): void {
  const stats = getPlayerStatistics(playerId);
  if (level > stats.highestJobLevel) {
    updateStat(playerId, 'highestJobLevel', level);
  }
}

/**
 * Update max affinity if new affinity is higher
 */
export function trackAffinity(playerId: string, affinity: number): void {
  const stats = getPlayerStatistics(playerId);
  if (affinity > stats.maxAffinityReached) {
    updateStat(playerId, 'maxAffinityReached', affinity);
  }
}

/**
 * Clear player statistics (for testing or new game)
 */
export function clearPlayerStatistics(playerId: string): void {
  playerStats.delete(playerId);
  photoAlbum.delete(playerId);
}

/**
 * Clear all statistics (for testing)
 */
export function clearAllStatistics(): void {
  playerStats.clear();
  photoAlbum.clear();
  photoIdCounter = 0;
}
