// --- Core entities ---

export interface Human {
  id: string | null;
  email: string;
  email_prefix: string;
  created_at: string | null;
}

export type StreamStatus = "open" | "closed" | "unspecified";

export interface AckInfo {
  email: string;
  acked_at: string;
}

// --- Particle types ---

export type ParticleType =
  | "media"
  | "text"
  | "quest"
  | "paper"
  | "file"
  | "folder";

export interface MediaParticleData {
  object_id: string;
  duration_ms: number;
  mime_type: string;
}

export interface TextParticleData {
  content: string;
}

export interface QuestParticleData {
  title: string;
  description: string;
  status?: string;
  assigned_to?: string;
  due_date?: string;
}

export interface PaperParticleData {
  title: string;
  content: string;
}

export interface FileParticleData {
  object_id: string;
  filename: string;
  mime_type: string;
  size: number;
}

export interface FolderParticleData {
  name: string;
  color?: string;
}

export interface ParticleDataMap {
  media: MediaParticleData;
  text: TextParticleData;
  quest: QuestParticleData;
  paper: PaperParticleData;
  file: FileParticleData;
  folder: FolderParticleData;
}

export function getParticleData<T extends ParticleType>(
  particle: StreamParticle,
  type: T,
): ParticleDataMap[T] {
  return particle.data as ParticleDataMap[T];
}

export interface StreamParticle {
  id: string;
  type: ParticleType;
  data: unknown;
  created_by_email: string;
  seen: boolean;
  acks: AckInfo[];
  updated_at: string;
  created_at: string;
}

export interface Stream {
  id: string;
  name: string;
  description: string;
  status: StreamStatus;
  members?: string[];
  particles: StreamParticle[];
  unseen_count: number;
  updated_at: string;
  created_at: string;
}

export interface Network {
  id: string;
  name: string;
  admin_human: Human;
  humans: Human[];
  open_stream_count: number;
  open_stream_capacity: number;
  created_at: string;
}

export interface NetworkWithStreams extends Network {
  streams: Stream[];
}

// --- Depot types ---

export interface PrepareUploadRequest {
  network_id: string;
  name: string;
  content_type: string;
  content_length: number;
}

export interface PrepareUploadResponse {
  object_id: string;
  upload_url: string;
  upload_headers: Record<string, string>;
}

// --- Stream mutation types ---

export interface CreateStreamRequest {
  name: string;
  description: string;
  visibility: "network_all" | "custom";
  member_emails?: string[];
}

export interface CreateStreamParticleRequest {
  type: ParticleType;
  data: unknown;
}

export interface MarkSeenBatchRequest {
  particle_ids: string[];
}

// --- Auth types ---

export interface RequestCodeRequest {
  email: string;
}

export interface SignInRequest {
  email: string;
  code: string;
}

export interface SignInResponse {
  human: Human;
  token: string;
}

// --- Startup ---

export interface StartupResponse {
  networks: NetworkWithStreams[];
}
