// Video types
export interface MediaVideo {
  id: number;
  path: string;
  filename: string;
  producer: string | null;
  creator: string | null;
  title: string | null;
  durationSeconds: number | null;
  quality: string | null;
  orientation: 'H' | 'V' | null;
  hasAudio: boolean;
  fileSize: number | null;
  fileHash: string | null;
  lastValidated: Date | null;
  isValid: boolean;
  thumbnailPath: string | null;
  createdAt: Date;
  tags: string[] | null;
}

export interface MediaVideoFilters {
  producer?: string;
  creator?: string;
  orientation?: 'H' | 'V';
  hasAudio?: boolean;
  isValid?: boolean;
  search?: string;
  limit?: number;
  offset?: number;
}

export interface MediaVideoStats {
  totalVideos: number;
  totalDuration: number;
  byProducer: Record<string, number>;
  byOrientation: { H: number; V: number };
  byQuality: Record<string, number>;
}

// Compilation types
export interface Compilation {
  id: number;
  filename: string;
  path: string | null;
  durationSeconds: number | null;
  videoIds: number[];
  settings: CompilationSettings;
  createdAt: Date;
}

export interface CompilationSettings {
  targetDuration: number;
  middleOverlaySource: string;
  columns: {
    left: number[];
    center: number[];
    right: number[];
  };
}

// Job types
export type JobType = 'compilation' | 'scan' | 'organize';
export type JobStatus = 'pending' | 'running' | 'completed' | 'failed';

export interface Job {
  id: number;
  type: JobType;
  status: JobStatus;
  progress: number;
  log: string | null;
  params: Record<string, unknown> | null;
  startedAt: Date | null;
  completedAt: Date | null;
  createdAt: Date;
}

export interface CreateJobParams {
  type: JobType;
  params?: Record<string, unknown>;
}

// API response types
export interface PaginatedResponse<T> {
  data: T[];
  total: number;
  limit: number;
  offset: number;
}

export interface ApiError {
  error: string;
  message: string;
  statusCode: number;
}

// ============================================
// Public Gallery Types
// ============================================

export type MediaCategory = 'compilations' | 'curated' | 'playback' | 'videos';

export interface SharedMedia {
  id: number;
  path: string;
  filename: string;
  category: MediaCategory;
  durationSeconds: number | null;
  quality: string | null;
  orientation: 'H' | 'V' | null;
  thumbnailPath: string | null;
  viewCount: number;
  upvoteCount: number;
  commentCount: number;
  totalWatchTime: number;
  createdAt: Date;
  userUpvoted?: boolean;
  // Locked video system
  isLocked: boolean;
  lockedAt: Date | null;
  lockedBy: number | null;
}

export interface SharedMediaComment {
  id: number;
  mediaId: number;
  sessionId: string;
  content: string;
  createdAt: Date;
}

export interface UpvoteResponse {
  upvoted: boolean;
  upvoteCount: number;
}

export interface ViewResponse {
  viewCount: number;
  isNewView: boolean;
}

export interface MediaStats {
  viewCount: number;
  upvoteCount: number;
  commentCount: number;
  totalWatchTime: number;
}

export interface SharedMediaFilters {
  category?: MediaCategory;
  sort?: 'recent' | 'popular' | 'most_viewed';
  limit?: number;
  offset?: number;
}

// ============================================
// Activity Feed Types
// ============================================

export type ActivityEventType = 'upvote' | 'comment' | 'view' | 'new_media';

export interface ActivityEvent {
  type: ActivityEventType;
  mediaId: number;
  mediaTitle: string;
  username: string;
  timestamp: string;
  preview?: string;
  category?: MediaCategory;
}

export interface ActivityStreamMessage {
  type: 'initial' | 'event';
  events?: ActivityEvent[];
  event?: ActivityEvent;
}

// ============================================
// Achievement & Dashboard Types
// ============================================

export type AchievementRarity = 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary';

export interface Achievement {
  id: string;
  name: string;
  description: string;
  icon: string;
  rarity: AchievementRarity;
  threshold: number;
  isUnlocked: boolean;
  unlockedAt?: Date;
  progress: number;
  currentValue: number;
}

export interface UserStats {
  totalWatchTimeSeconds: number;
  totalVideosWatched: number;
  totalUpvotesGiven: number;
  totalCommentsMade: number;
  totalCompletions: number;
  currentDayStreak: number;
  longestDayStreak: number;
  longestSingleSession: number;
}

export interface DashboardData {
  stats: UserStats;
  recentAchievements: UnlockedAchievement[];
  achievementProgress: {
    unlocked: number;
    total: number;
    byCategory: Record<string, { unlocked: number; total: number }>;
  };
  achievements: Achievement[];
}

export interface UnlockedAchievement {
  id: string;
  name: string;
  description: string;
  icon: string;
  rarity: AchievementRarity;
  unlockedAt: Date;
}

export interface CompletionResponse {
  success: boolean;
  totalCompletions: number;
  unlockedAchievements: UnlockedAchievement[];
}

export interface AchievementsResponse {
  achievements: Achievement[];
  byCategory: Record<string, Achievement[]>;
  summary: {
    unlocked: number;
    total: number;
  };
}

// ============================================
// Digest Prompt Types
// ============================================

export {
  DESCRIPTION_STAGE_PROMPT,
  TAGGING_STAGE_PROMPT,
  CLASSIFICATION_STAGE_PROMPT,
  SYNTHESIS_STAGE_TEMPLATE,
  PROMPT_PLACEHOLDERS,
  SYNTHESIS_PROMPT_INFO,
  DEFAULT_PROMPTS,
  type DefaultPrompts,
} from './prompts.js';

// ============================================
// Utility Functions
// ============================================

/**
 * Format duration in seconds to H:MM:SS or M:SS format
 * Used for video player displays
 */
export function formatDuration(seconds: number): string {
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = Math.floor(seconds % 60);
  if (hours > 0) {
    return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
  }
  return `${minutes}:${secs.toString().padStart(2, '0')}`;
}

/**
 * Format duration in seconds to compact H:MM or Xm format
 * Used for list displays where space is limited
 */
export function formatDurationCompact(seconds: number): string {
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  if (hours > 0) {
    return `${hours}:${minutes.toString().padStart(2, '0')}`;
  }
  return `${minutes}m`;
}

/**
 * Format time in seconds to M:SS format
 * Used for scene/clip time displays
 */
export function formatTime(seconds: number): string {
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins}:${secs.toString().padStart(2, '0')}`;
}

// ============================================
// Reaction Types
// ============================================

export const MEDIA_REACTION_TYPES = ['like', 'love', 'laugh', 'wow', 'sad', 'angry'] as const;
export type MediaReactionType = typeof MEDIA_REACTION_TYPES[number];

export interface MediaReaction {
  id: number;
  userId: number;
  mediaId: number;
  reactionType: MediaReactionType;
  timestamp: number; // Video timestamp in seconds where reaction occurred
  createdAt: Date;
}

// ============================================
// Shared Constants
// ============================================

/**
 * Public directory badge configuration
 * Maps directory types to display labels and colors
 */
export const PUBLIC_DIR_BADGES: Record<string, { label: string; color: string }> = {
  videos: { label: 'V', color: 'bg-green-600' },
  curated: { label: 'C', color: 'bg-blue-600' },
  compilations: { label: 'P', color: 'bg-purple-600' },
  playback: { label: 'B', color: 'bg-indigo-600' },
  highlights: { label: 'H', color: 'bg-pink-600' },
};
