// ─── Core entities ───────────────────────────────────────────────────────────

export interface MediaFile {
  id: string;
  title: string | null;
  description: string | null;
  filename: string;
  mime_type: string | null;
  filesize: number | null;
  duration: number | null;
  uploaded_by: string | null;
  date_created: Date;
}

export interface User {
  id: string;
  email: string;
  first_name: string | null;
  last_name: string | null;
  artist_name: string | null;
  slug: string | null;
  description: string | null;
  tags: string[] | null;
  role: "model" | "viewer" | "admin";
  is_admin: boolean;
  /** UUID of the avatar file */
  avatar: string | null;
  /** UUID of the banner file */
  banner: string | null;
  /** UUID of the dedicated model profile/card image */
  photo: string | null;
  email_verified: boolean;
  date_created: Date;
}

export type CurrentUser = User;

// ─── Video ───────────────────────────────────────────────────────────────────

export interface VideoModel {
  id: string;
  artist_name: string | null;
  slug: string | null;
  avatar: string | null;
  description: string | null;
}

export interface VideoFile {
  id: string;
  filename: string;
  mime_type: string | null;
  duration: number | null;
}

export interface Video {
  id: string;
  slug: string;
  title: string;
  description: string | null;
  image: string | null;
  movie: string | null;
  tags: string[] | null;
  upload_date: Date;
  premium: boolean | null;
  featured: boolean | null;
  likes_count: number | null;
  plays_count: number | null;
  models?: VideoModel[];
  movie_file?: VideoFile | null;
}

// ─── Model ───────────────────────────────────────────────────────────────────

export interface ModelPhoto {
  id: string;
  filename: string;
}

export interface Model {
  id: string;
  slug: string | null;
  artist_name: string | null;
  description: string | null;
  avatar: string | null;
  banner: string | null;
  /** UUID of the dedicated model profile/card image (distinct from avatar) */
  photo: string | null;
  tags: string[] | null;
  date_created: Date;
  photos?: ModelPhoto[];
}

// ─── Article ─────────────────────────────────────────────────────────────────

export interface Article {
  id: string;
  slug: string;
  title: string;
  excerpt: string | null;
  content: string | null;
  image: string | null;
  tags: string[] | null;
  publish_date: Date;
  category: string | null;
  featured: boolean | null;
  author?: VideoModel | null;
}

// ─── Comment ─────────────────────────────────────────────────────────────────

export interface CommentUser {
  id: string;
  first_name: string | null;
  last_name: string | null;
  artist_name: string | null;
  avatar: string | null;
}

export interface Comment {
  id: number;
  collection: string;
  item_id: string;
  comment: string;
  user_id: string;
  date_created: Date;
  user?: CommentUser | null;
}

// ─── Stats ───────────────────────────────────────────────────────────────────

export interface Stats {
  videos_count: number;
  models_count: number;
  viewers_count: number;
}

// ─── Recording ───────────────────────────────────────────────────────────────

export interface RecordedEvent {
  timestamp: number;
  device_index: number;
  device_name: string;
  actuator_index: number;
  actuator_type: string;
  value: number;
}

export interface DeviceInfo {
  name: string;
  index: number;
  capabilities: string[];
}

export interface Recording {
  id: string;
  title: string;
  description: string | null;
  slug: string;
  duration: number;
  events: object[] | null;
  device_info: object[] | null;
  user_id: string;
  status: "draft" | "published" | "archived";
  tags: string[] | null;
  linked_video: string | null;
  featured: boolean | null;
  public: boolean | null;
  original_recording_id?: string | null;
  date_created: Date;
  date_updated: Date | null;
}

// ─── Video interactions ───────────────────────────────────────────────────────

export interface VideoLikeStatus {
  liked: boolean;
}

export interface VideoPlayRecord {
  id: string;
  video_id: string;
  duration_watched?: number;
  completed: boolean;
}

export interface VideoLikeResponse {
  liked: boolean;
  likes_count: number;
}

export interface VideoPlayResponse {
  success: boolean;
  play_id: string;
  plays_count: number;
}

// ─── Analytics ───────────────────────────────────────────────────────────────

export interface VideoAnalytics {
  id: string;
  title: string;
  slug: string;
  upload_date: Date;
  likes: number;
  plays: number;
  completed_plays: number;
  completion_rate: number;
  avg_watch_time: number;
}

export interface Analytics {
  total_videos: number;
  total_likes: number;
  total_plays: number;
  plays_by_date: Record<string, number>;
  likes_by_date: Record<string, number>;
  videos: VideoAnalytics[];
}

// ─── Gamification ────────────────────────────────────────────────────────────

export interface LeaderboardEntry {
  user_id: string;
  display_name: string | null;
  avatar: string | null;
  total_weighted_points: number | null;
  total_raw_points: number | null;
  recordings_count: number | null;
  playbacks_count: number | null;
  achievements_count: number | null;
  rank: number;
}

export interface UserStats {
  user_id: string;
  total_raw_points: number | null;
  total_weighted_points: number | null;
  recordings_count: number | null;
  playbacks_count: number | null;
  comments_count: number | null;
  achievements_count: number | null;
  rank: number;
}

export interface UserAchievement {
  id: string;
  code: string;
  name: string;
  description: string | null;
  icon: string | null;
  category: string | null;
  date_unlocked: Date;
  progress: number | null;
  required_count: number;
}

export interface RecentPoint {
  action: string;
  points: number;
  date_created: Date;
  recording_id: string | null;
}

export interface UserGamification {
  stats: UserStats | null;
  achievements: UserAchievement[];
  recent_points: RecentPoint[];
}

export interface Achievement {
  id: string;
  code: string;
  name: string;
  description: string | null;
  icon: string | null;
  category: string | null;
  required_count: number;
  points_reward: number;
}
