// Branded types for IDs
export type PageId = string & { readonly __brand: 'PageId' };
export type DatabaseId = string & { readonly __brand: 'DatabaseId' };
export type BlockId = string & { readonly __brand: 'BlockId' };
export type UserId = string & { readonly __brand: 'UserId' };
export type CommentId = string & { readonly __brand: 'CommentId' };

// Color types
export type Color =
  | 'default'
  | 'gray'
  | 'brown'
  | 'orange'
  | 'yellow'
  | 'green'
  | 'blue'
  | 'purple'
  | 'pink'
  | 'red'
  | 'gray_background'
  | 'brown_background'
  | 'orange_background'
  | 'yellow_background'
  | 'green_background'
  | 'blue_background'
  | 'purple_background'
  | 'pink_background'
  | 'red_background';

// RichText types
export interface RichTextAnnotations {
  bold: boolean;
  italic: boolean;
  strikethrough: boolean;
  underline: boolean;
  code: boolean;
  color: Color;
}

export type RichText =
  | {
      type: 'text';
      text: {
        content: string;
        link: { url: string } | null;
      };
      annotations: RichTextAnnotations;
      plain_text: string;
      href: string | null;
    }
  | {
      type: 'mention';
      mention:
        | { type: 'user'; user: User }
        | { type: 'page'; page: { id: PageId } }
        | { type: 'database'; database: { id: DatabaseId } }
        | { type: 'date'; date: DateValue }
        | { type: 'link_preview'; link_preview: { url: string } }
        | { type: 'template_mention'; template_mention: { type: 'template_mention_date' | 'template_mention_user' } };
      annotations: RichTextAnnotations;
      plain_text: string;
      href: string | null;
    }
  | {
      type: 'equation';
      equation: {
        expression: string;
      };
      annotations: RichTextAnnotations;
      plain_text: string;
      href: string | null;
    };

// Date types
export interface DateValue {
  start: string;
  end: string | null;
  time_zone: string | null;
}

// User types
export type User =
  | {
      object: 'user';
      id: UserId;
      type: 'person';
      person: { email: string };
      name: string | null;
      avatar_url: string | null;
    }
  | {
      object: 'user';
      id: UserId;
      type: 'bot';
      bot: Record<string, unknown> | { owner: { type: 'workspace'; workspace: true } | { type: 'user'; user: User } };
      name: string | null;
      avatar_url: string | null;
    };

export type Person = Extract<User, { type: 'person' }>;
export type Bot = Extract<User, { type: 'bot' }>;

// Parent types
export type Parent =
  | { type: 'database_id'; database_id: DatabaseId }
  | { type: 'page_id'; page_id: PageId }
  | { type: 'workspace'; workspace: true }
  | { type: 'block_id'; block_id: BlockId };

// File types
export type FileObject =
  | {
      type: 'external';
      external: { url: string };
      name?: string;
    }
  | {
      type: 'file';
      file: { url: string; expiry_time: string };
      name?: string;
    };

// Emoji and Icon types
export type Icon =
  | { type: 'emoji'; emoji: string }
  | { type: 'external'; external: { url: string } }
  | { type: 'file'; file: { url: string; expiry_time: string } };

// Property value types for Pages
export type PageProperty =
  | { id: string; type: 'title'; title: RichText[] }
  | { id: string; type: 'rich_text'; rich_text: RichText[] }
  | { id: string; type: 'number'; number: number | null }
  | { id: string; type: 'select'; select: { id: string; name: string; color: Color } | null }
  | { id: string; type: 'multi_select'; multi_select: Array<{ id: string; name: string; color: Color }> }
  | { id: string; type: 'date'; date: DateValue | null }
  | { id: string; type: 'people'; people: User[] }
  | { id: string; type: 'files'; files: FileObject[] }
  | { id: string; type: 'checkbox'; checkbox: boolean }
  | { id: string; type: 'url'; url: string | null }
  | { id: string; type: 'email'; email: string | null }
  | { id: string; type: 'phone_number'; phone_number: string | null }
  | { id: string; type: 'formula'; formula: { type: 'string'; string: string | null } | { type: 'number'; number: number | null } | { type: 'boolean'; boolean: boolean | null } | { type: 'date'; date: DateValue | null } }
  | { id: string; type: 'relation'; relation: Array<{ id: PageId }> }
  | { id: string; type: 'rollup'; rollup: { type: 'number'; number: number | null; function: string } | { type: 'date'; date: DateValue | null; function: string } | { type: 'array'; array: PageProperty[]; function: string } }
  | { id: string; type: 'created_time'; created_time: string }
  | { id: string; type: 'created_by'; created_by: User }
  | { id: string; type: 'last_edited_time'; last_edited_time: string }
  | { id: string; type: 'last_edited_by'; last_edited_by: User }
  | { id: string; type: 'status'; status: { id: string; name: string; color: Color } | null }
  | { id: string; type: 'unique_id'; unique_id: { number: number; prefix: string | null } };

// Database property schema types
export type DatabaseProperty =
  | { id: string; name: string; type: 'title'; title: Record<string, unknown> }
  | { id: string; name: string; type: 'rich_text'; rich_text: Record<string, unknown> }
  | { id: string; name: string; type: 'number'; number: { format: 'number' | 'number_with_commas' | 'percent' | 'dollar' | 'canadian_dollar' | 'euro' | 'pound' | 'yen' | 'ruble' | 'rupee' | 'won' | 'yuan' | 'real' | 'lira' | 'rupiah' | 'franc' | 'hong_kong_dollar' | 'new_zealand_dollar' | 'krona' | 'norwegian_krone' | 'mexican_peso' | 'rand' | 'new_taiwan_dollar' | 'danish_krone' | 'zloty' | 'baht' | 'forint' | 'koruna' | 'shekel' | 'chilean_peso' | 'philippine_peso' | 'dirham' | 'colombian_peso' | 'riyal' | 'ringgit' | 'leu' | 'argentine_peso' | 'uruguayan_peso' } }
  | { id: string; name: string; type: 'select'; select: { options: Array<{ id: string; name: string; color: Color }> } }
  | { id: string; name: string; type: 'multi_select'; multi_select: { options: Array<{ id: string; name: string; color: Color }> } }
  | { id: string; name: string; type: 'date'; date: Record<string, unknown> }
  | { id: string; name: string; type: 'people'; people: Record<string, unknown> }
  | { id: string; name: string; type: 'files'; files: Record<string, unknown> }
  | { id: string; name: string; type: 'checkbox'; checkbox: Record<string, unknown> }
  | { id: string; name: string; type: 'url'; url: Record<string, unknown> }
  | { id: string; name: string; type: 'email'; email: Record<string, unknown> }
  | { id: string; name: string; type: 'phone_number'; phone_number: Record<string, unknown> }
  | { id: string; name: string; type: 'formula'; formula: { expression: string } }
  | { id: string; name: string; type: 'relation'; relation: { database_id: DatabaseId; synced_property_id?: string; synced_property_name?: string } }
  | { id: string; name: string; type: 'rollup'; rollup: { relation_property_id: string; relation_property_name: string; rollup_property_id: string; rollup_property_name: string; function: 'count_all' | 'count_values' | 'count_unique_values' | 'count_empty' | 'count_not_empty' | 'percent_empty' | 'percent_not_empty' | 'sum' | 'average' | 'median' | 'min' | 'max' | 'range' | 'show_original' } }
  | { id: string; name: string; type: 'created_time'; created_time: Record<string, unknown> }
  | { id: string; name: string; type: 'created_by'; created_by: Record<string, unknown> }
  | { id: string; name: string; type: 'last_edited_time'; last_edited_time: Record<string, unknown> }
  | { id: string; name: string; type: 'last_edited_by'; last_edited_by: Record<string, unknown> }
  | { id: string; name: string; type: 'status'; status: { options: Array<{ id: string; name: string; color: Color }>; groups: Array<{ id: string; name: string; color: Color; option_ids: string[] }> } }
  | { id: string; name: string; type: 'unique_id'; unique_id: { prefix: string | null } };

// Block types - comprehensive discriminated union
export type Block =
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'paragraph';
      paragraph: {
        rich_text: RichText[];
        color: Color;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'heading_1';
      heading_1: {
        rich_text: RichText[];
        color: Color;
        is_toggleable: boolean;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'heading_2';
      heading_2: {
        rich_text: RichText[];
        color: Color;
        is_toggleable: boolean;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'heading_3';
      heading_3: {
        rich_text: RichText[];
        color: Color;
        is_toggleable: boolean;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'bulleted_list_item';
      bulleted_list_item: {
        rich_text: RichText[];
        color: Color;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'numbered_list_item';
      numbered_list_item: {
        rich_text: RichText[];
        color: Color;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'to_do';
      to_do: {
        rich_text: RichText[];
        checked: boolean;
        color: Color;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'toggle';
      toggle: {
        rich_text: RichText[];
        color: Color;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'code';
      code: {
        rich_text: RichText[];
        caption: RichText[];
        language: string;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'callout';
      callout: {
        rich_text: RichText[];
        icon: Icon;
        color: Color;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'quote';
      quote: {
        rich_text: RichText[];
        color: Color;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'divider';
      divider: Record<string, unknown>;
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'table_of_contents';
      table_of_contents: {
        color: Color;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'breadcrumb';
      breadcrumb: Record<string, unknown>;
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'image';
      image: FileObject & { caption?: RichText[] };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'video';
      video: FileObject & { caption?: RichText[] };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'file';
      file: FileObject & { caption?: RichText[] };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'pdf';
      pdf: FileObject & { caption?: RichText[] };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'bookmark';
      bookmark: {
        url: string;
        caption: RichText[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'embed';
      embed: {
        url: string;
        caption?: RichText[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'link_preview';
      link_preview: {
        url: string;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'equation';
      equation: {
        expression: string;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'table';
      table: {
        table_width: number;
        has_column_header: boolean;
        has_row_header: boolean;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'table_row';
      table_row: {
        cells: RichText[][];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'column_list';
      column_list: Record<string, unknown>;
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'column';
      column: Record<string, unknown>;
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'synced_block';
      synced_block: {
        synced_from: { block_id: BlockId } | null;
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'template';
      template: {
        rich_text: RichText[];
        children?: Block[];
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'child_page';
      child_page: {
        title: string;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'child_database';
      child_database: {
        title: string;
      };
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    }
  | {
      object: 'block';
      id: BlockId;
      parent: Parent;
      type: 'unsupported';
      unsupported: Record<string, unknown>;
      created_time: string;
      created_by: User;
      last_edited_time: string;
      last_edited_by: User;
      has_children: boolean;
      archived: boolean;
    };

// Page type
export interface Page {
  object: 'page';
  id: PageId;
  created_time: string;
  created_by: User;
  last_edited_time: string;
  last_edited_by: User;
  archived: boolean;
  icon: Icon | null;
  cover: FileObject | null;
  properties: Record<string, PageProperty>;
  parent: Parent;
  url: string;
}

// Database type
export interface Database {
  object: 'database';
  id: DatabaseId;
  created_time: string;
  created_by: User;
  last_edited_time: string;
  last_edited_by: User;
  title: RichText[];
  description: RichText[];
  icon: Icon | null;
  cover: FileObject | null;
  properties: Record<string, DatabaseProperty>;
  parent: Parent;
  url: string;
  archived: boolean;
  is_inline: boolean;
}

// Comment type
export interface Comment {
  object: 'comment';
  id: CommentId;
  parent: { type: 'page_id'; page_id: PageId } | { type: 'block_id'; block_id: BlockId };
  discussion_id: string;
  created_time: string;
  created_by: User;
  last_edited_time: string;
  rich_text: RichText[];
}

// Search result type
export type SearchResult = Page | Database;

// Pagination types
export interface PaginatedResults<T> {
  object: 'list';
  results: T[];
  next_cursor: string | null;
  has_more: boolean;
  type?: string;
}

// Filter types for database queries
export type PropertyFilter =
  | { property: string; rich_text: { equals?: string; does_not_equal?: string; contains?: string; does_not_contain?: string; starts_with?: string; ends_with?: string; is_empty?: boolean; is_not_empty?: boolean } }
  | { property: string; number: { equals?: number; does_not_equal?: number; greater_than?: number; less_than?: number; greater_than_or_equal_to?: number; less_than_or_equal_to?: number; is_empty?: boolean; is_not_empty?: boolean } }
  | { property: string; checkbox: { equals?: boolean; does_not_equal?: boolean } }
  | { property: string; select: { equals?: string; does_not_equal?: string; is_empty?: boolean; is_not_empty?: boolean } }
  | { property: string; multi_select: { contains?: string; does_not_contain?: string; is_empty?: boolean; is_not_empty?: boolean } }
  | { property: string; status: { equals?: string; does_not_equal?: string; is_empty?: boolean; is_not_empty?: boolean } }
  | { property: string; date: { equals?: string; before?: string; after?: string; on_or_before?: string; on_or_after?: string; is_empty?: boolean; is_not_empty?: boolean; past_week?: Record<string, unknown>; past_month?: Record<string, unknown>; past_year?: Record<string, unknown>; next_week?: Record<string, unknown>; next_month?: Record<string, unknown>; next_year?: Record<string, unknown> } }
  | { property: string; people: { contains?: UserId; does_not_contain?: UserId; is_empty?: boolean; is_not_empty?: boolean } }
  | { property: string; files: { is_empty?: boolean; is_not_empty?: boolean } }
  | { property: string; relation: { contains?: PageId; does_not_contain?: PageId; is_empty?: boolean; is_not_empty?: boolean } }
  | { property: string; formula: { string?: { equals?: string; does_not_equal?: string; contains?: string; does_not_contain?: string; starts_with?: string; ends_with?: string; is_empty?: boolean; is_not_empty?: boolean }; checkbox?: { equals?: boolean; does_not_equal?: boolean }; number?: { equals?: number; does_not_equal?: number; greater_than?: number; less_than?: number; greater_than_or_equal_to?: number; less_than_or_equal_to?: number; is_empty?: boolean; is_not_empty?: boolean }; date?: { equals?: string; before?: string; after?: string; on_or_before?: string; on_or_after?: string; is_empty?: boolean; is_not_empty?: boolean } } };

export type CompoundFilter =
  | { and: Array<PropertyFilter | CompoundFilter> }
  | { or: Array<PropertyFilter | CompoundFilter> };

export type Filter = PropertyFilter | CompoundFilter;

// Sort types
export interface Sort {
  property?: string;
  timestamp?: 'created_time' | 'last_edited_time';
  direction: 'ascending' | 'descending';
}
