export interface AdminSessionResponse {
  authenticated: boolean
  username: string | null
  email: string | null
  auth_source: string | null
  auth_provider: string | null
  groups: string[]
  proxy_auth_enabled: boolean
  local_login_enabled: boolean
  can_logout: boolean
}

export interface AuditLogRecord {
  created_at: string
  updated_at: string
  id: number
  actor_username: string | null
  actor_email: string | null
  actor_source: string | null
  action: string
  target_type: string
  target_id: string | null
  target_label: string | null
  metadata: Record<string, unknown> | null
}

export interface PostRevisionRecord {
  id: number
  post_slug: string
  post_title: string | null
  operation: string
  revision_reason: string | null
  actor_username: string | null
  actor_email: string | null
  actor_source: string | null
  created_at: string
  has_markdown: boolean
  metadata: Record<string, unknown> | null
}

export interface PostRevisionDetail {
  item: PostRevisionRecord
  markdown: string | null
}

export interface RestoreRevisionResponse {
  restored: boolean
  revision_id: number
  post_slug: string
  mode: 'full' | 'markdown' | 'metadata' | string
}

export interface SubscriptionRecord {
  created_at: string
  updated_at: string
  id: number
  channel_type: string
  target: string
  display_name: string | null
  status: string
  filters: Record<string, unknown> | null
  metadata: Record<string, unknown> | null
  secret: string | null
  notes: string | null
  confirm_token: string | null
  manage_token: string | null
  verified_at: string | null
  last_notified_at: string | null
  failure_count: number | null
  last_delivery_status: string | null
}

export interface NotificationDeliveryRecord {
  created_at: string
  updated_at: string
  id: number
  subscription_id: number | null
  channel_type: string
  target: string
  event_type: string
  status: string
  provider: string | null
  response_text: string | null
  payload: Record<string, unknown> | null
  attempts_count: number
  next_retry_at: string | null
  last_attempt_at: string | null
  delivered_at: string | null
}

export interface SubscriptionListResponse {
  subscriptions: SubscriptionRecord[]
}

export interface DeliveryListResponse {
  deliveries: NotificationDeliveryRecord[]
}

export interface SubscriptionPayload {
  channelType: string
  target: string
  displayName?: string | null
  status?: string | null
  filters?: Record<string, unknown> | null
  metadata?: Record<string, unknown> | null
  secret?: string | null
  notes?: string | null
}

export interface SubscriptionUpdatePayload {
  channelType?: string | null
  target?: string | null
  displayName?: string | null
  status?: string | null
  filters?: Record<string, unknown> | null
  metadata?: Record<string, unknown> | null
  secret?: string | null
  notes?: string | null
}

export interface SubscriptionDigestResponse {
  period: string
  post_count: number
  queued: number
  skipped: number
}

export interface WorkerCatalogEntry {
  worker_name: string
  job_kind: string
  label: string
  description: string
  queue_name: string | null
  supports_cancel: boolean
  supports_retry: boolean
}

export interface WorkerStats {
  worker_name: string
  job_kind: string
  label: string
  queued: number
  running: number
  succeeded: number
  failed: number
  cancelled: number
  last_job_at: string | null
}

export interface WorkerOverview {
  total_jobs: number
  queued: number
  running: number
  succeeded: number
  failed: number
  cancelled: number
  active_jobs: number
  worker_stats: WorkerStats[]
  catalog: WorkerCatalogEntry[]
}

export interface WorkerJobRecord {
  created_at: string
  updated_at: string
  id: number
  parent_job_id: number | null
  job_kind: string
  worker_name: string
  display_name: string | null
  status: string
  queue_name: string | null
  requested_by: string | null
  requested_source: string | null
  trigger_mode: string | null
  payload: Record<string, unknown> | null
  result: Record<string, unknown> | null
  error_text: string | null
  tags: unknown[] | Record<string, unknown> | null
  related_entity_type: string | null
  related_entity_id: string | null
  attempts_count: number
  max_attempts: number
  cancel_requested: boolean
  queued_at: string | null
  started_at: string | null
  finished_at: string | null
  can_cancel: boolean
  can_retry: boolean
}

export interface WorkerJobListResponse {
  total: number
  jobs: WorkerJobRecord[]
}

export interface WorkerTaskActionResponse {
  queued: boolean
  job: WorkerJobRecord
}

export interface DashboardStats {
  total_posts: number
  total_comments: number
  pending_comments: number
  draft_posts: number
  scheduled_posts: number
  offline_posts: number
  expired_posts: number
  private_posts: number
  unlisted_posts: number
  total_categories: number
  total_tags: number
  total_reviews: number
  total_links: number
  pending_links: number
  ai_chunks: number
  ai_enabled: boolean
}

export interface DashboardPostItem {
  id: number
  title: string
  slug: string
  category: string
  post_type: string
  pinned: boolean
  status: string
  visibility: string
  created_at: string
}

export interface DashboardCommentItem {
  id: number
  author: string
  post_slug: string
  scope: string
  excerpt: string
  approved: boolean
  created_at: string
}

export interface DashboardFriendLinkItem {
  id: number
  site_name: string
  site_url: string
  category: string
  status: string
  created_at: string
}

export interface DashboardReviewItem {
  id: number
  title: string
  review_type: string
  rating: number
  status: string
  review_date: string
}

export interface DashboardSiteSummary {
  site_name: string
  site_url: string
  ai_enabled: boolean
  ai_chunks: number
  ai_last_indexed_at: string | null
}

export interface AdminDashboardResponse {
  stats: DashboardStats
  site: DashboardSiteSummary
  recent_posts: DashboardPostItem[]
  pending_comments: DashboardCommentItem[]
  pending_friend_links: DashboardFriendLinkItem[]
  recent_reviews: DashboardReviewItem[]
}

export interface AnalyticsOverview {
  total_searches: number
  total_ai_questions: number
  searches_last_24h: number
  ai_questions_last_24h: number
  searches_last_7d: number
  ai_questions_last_7d: number
  unique_search_terms_last_7d: number
  unique_ai_questions_last_7d: number
  avg_search_results_last_7d: number
  avg_ai_latency_ms_last_7d: number | null
}

export interface ContentAnalyticsOverview {
  total_page_views: number
  page_views_last_24h: number
  page_views_last_7d: number
  total_read_completes: number
  read_completes_last_7d: number
  avg_read_progress_last_7d: number
  avg_read_duration_ms_last_7d: number | null
}

export interface AnalyticsTopQuery {
  query: string
  count: number
  last_seen_at: string
}

export interface AnalyticsRecentEvent {
  id: number
  event_type: string
  query: string
  result_count: number | null
  success: boolean | null
  response_mode: string | null
  provider: string | null
  chat_model: string | null
  latency_ms: number | null
  created_at: string
}

export interface AnalyticsProviderBucket {
  provider: string
  count: number
}

export interface AnalyticsReferrerBucket {
  referrer: string
  count: number
}

export interface AnalyticsPopularPost {
  slug: string
  title: string
  page_views: number
  read_completes: number
  avg_progress_percent: number
  avg_duration_ms: number | null
}

export interface AnalyticsDailyBucket {
  date: string
  searches: number
  ai_questions: number
}

export interface AdminAnalyticsResponse {
  overview: AnalyticsOverview
  content_overview: ContentAnalyticsOverview
  top_search_terms: AnalyticsTopQuery[]
  top_ai_questions: AnalyticsTopQuery[]
  recent_events: AnalyticsRecentEvent[]
  providers_last_7d: AnalyticsProviderBucket[]
  top_referrers: AnalyticsReferrerBucket[]
  ai_referrers_last_7d: AnalyticsReferrerBucket[]
  ai_discovery_page_views_last_7d: number
  popular_posts: AnalyticsPopularPost[]
  daily_activity: AnalyticsDailyBucket[]
}

export interface AdminSiteSettingsResponse {
  id: number
  site_name: string | null
  site_short_name: string | null
  site_url: string | null
  site_title: string | null
  site_description: string | null
  hero_title: string | null
  hero_subtitle: string | null
  owner_name: string | null
  owner_title: string | null
  owner_bio: string | null
  owner_avatar_url: string | null
  social_github: string | null
  social_twitter: string | null
  social_email: string | null
  location: string | null
  tech_stack: string[]
  music_playlist: MusicTrack[]
  music_enabled: boolean
  maintenance_mode_enabled: boolean
  maintenance_access_code: string | null
  ai_enabled: boolean
  paragraph_comments_enabled: boolean
  comment_verification_mode: HumanVerificationMode
  comment_turnstile_enabled: boolean
  subscription_verification_mode: HumanVerificationMode
  subscription_turnstile_enabled: boolean
  web_push_enabled: boolean
  turnstile_site_key: string | null
  turnstile_secret_key: string | null
  web_push_vapid_public_key: string | null
  web_push_vapid_private_key: string | null
  web_push_vapid_subject: string | null
  ai_provider: string | null
  ai_api_base: string | null
  ai_api_key: string | null
  ai_chat_model: string | null
  ai_image_provider: string | null
  ai_image_api_base: string | null
  ai_image_api_key: string | null
  ai_image_model: string | null
  ai_providers: AiProviderConfig[]
  ai_active_provider_id: string | null
  ai_embedding_model: string | null
  ai_system_prompt: string | null
  ai_top_k: number | null
  ai_chunk_size: number | null
  ai_last_indexed_at: string | null
  ai_chunks_count: number
  ai_local_embedding: string
  media_storage_provider: string | null
  media_r2_account_id: string | null
  media_r2_bucket: string | null
  media_r2_public_base_url: string | null
  media_r2_access_key_id: string | null
  media_r2_secret_access_key: string | null
  seo_favicon_url: string | null
  seo_default_og_image: string | null
  seo_default_twitter_handle: string | null
  seo_wechat_share_qr_enabled: boolean
  notification_webhook_url: string | null
  notification_channel_type: 'webhook' | 'ntfy' | string
  notification_comment_enabled: boolean
  notification_friend_link_enabled: boolean
  subscription_popup_enabled: boolean
  subscription_popup_title: string
  subscription_popup_description: string
  subscription_popup_delay_seconds: number
  search_synonyms: string[]
}

export interface AiProviderConfig {
  id: string
  name: string
  provider: string
  api_base: string | null
  api_key: string | null
  chat_model: string | null
  image_model: string | null
}

export interface SiteSettingsPayload {
  siteName?: string | null
  siteShortName?: string | null
  siteUrl?: string | null
  siteTitle?: string | null
  siteDescription?: string | null
  heroTitle?: string | null
  heroSubtitle?: string | null
  ownerName?: string | null
  ownerTitle?: string | null
  ownerBio?: string | null
  ownerAvatarUrl?: string | null
  socialGithub?: string | null
  socialTwitter?: string | null
  socialEmail?: string | null
  location?: string | null
  techStack?: string[]
  musicPlaylist?: MusicTrack[]
  musicEnabled?: boolean
  maintenanceModeEnabled?: boolean
  maintenanceAccessCode?: string | null
  aiEnabled?: boolean
  paragraphCommentsEnabled?: boolean
  commentVerificationMode?: HumanVerificationMode | null
  commentTurnstileEnabled?: boolean
  subscriptionVerificationMode?: HumanVerificationMode | null
  subscriptionTurnstileEnabled?: boolean
  webPushEnabled?: boolean
  turnstileSiteKey?: string | null
  turnstileSecretKey?: string | null
  webPushVapidPublicKey?: string | null
  webPushVapidPrivateKey?: string | null
  webPushVapidSubject?: string | null
  aiProvider?: string | null
  aiApiBase?: string | null
  aiApiKey?: string | null
  aiChatModel?: string | null
  aiImageProvider?: string | null
  aiImageApiBase?: string | null
  aiImageApiKey?: string | null
  aiImageModel?: string | null
  aiProviders?: AiProviderConfig[]
  aiActiveProviderId?: string | null
  aiEmbeddingModel?: string | null
  aiSystemPrompt?: string | null
  aiTopK?: number | null
  aiChunkSize?: number | null
  mediaStorageProvider?: string | null
  mediaR2AccountId?: string | null
  mediaR2Bucket?: string | null
  mediaR2PublicBaseUrl?: string | null
  mediaR2AccessKeyId?: string | null
  mediaR2SecretAccessKey?: string | null
  seoFaviconUrl?: string | null
  seoDefaultOgImage?: string | null
  seoDefaultTwitterHandle?: string | null
  seoWechatShareQrEnabled?: boolean
  notificationWebhookUrl?: string | null
  notificationChannelType?: 'webhook' | 'ntfy' | string | null
  notificationCommentEnabled?: boolean
  notificationFriendLinkEnabled?: boolean
  subscriptionPopupEnabled?: boolean
  subscriptionPopupTitle?: string | null
  subscriptionPopupDescription?: string | null
  subscriptionPopupDelaySeconds?: number | null
  searchSynonyms?: string[]
}

export type HumanVerificationMode = 'off' | 'captcha' | 'turnstile' | string

export interface CategoryRecord {
  id: number
  name: string
  slug: string
  count: number
  description: string | null
  cover_image: string | null
  accent_color: string | null
  seo_title: string | null
  seo_description: string | null
  created_at: string
  updated_at: string
}

export interface TagRecord {
  id: number
  name: string
  slug: string
  count: number
  description: string | null
  cover_image: string | null
  accent_color: string | null
  seo_title: string | null
  seo_description: string | null
  created_at: string
  updated_at: string
}

export interface TaxonomyPayload {
  name: string
  slug?: string | null
  description?: string | null
  coverImage?: string | null
  accentColor?: string | null
  seoTitle?: string | null
  seoDescription?: string | null
}

export interface AdminAiProviderTestResponse {
  provider: string
  endpoint: string
  chat_model: string
  reply_preview: string
}

export interface AdminAiImageProviderTestResponse {
  provider: string
  endpoint: string
  image_model: string
  result_preview: string
}

export interface AdminImageUploadResponse {
  url: string
  key: string
}

export interface AdminR2ConnectivityResponse {
  bucket: string
  public_base_url: string
}

export interface AdminMediaObjectResponse {
  key: string
  url: string
  size_bytes: number
  last_modified: string | null
  title: string | null
  alt_text: string | null
  caption: string | null
  tags: string[]
  notes: string | null
}

export interface AdminMediaListResponse {
  provider: string
  bucket: string
  public_base_url: string
  items: AdminMediaObjectResponse[]
}

export interface AdminMediaDeleteResponse {
  deleted: boolean
  key: string
}

export interface AdminMediaUploadItem {
  key: string
  url: string
  size_bytes: number
}

export interface AdminMediaUploadResponse {
  uploaded: AdminMediaUploadItem[]
}

export interface AdminMediaBatchDeleteResponse {
  deleted: string[]
  failed: string[]
}

export interface AdminMediaReplaceResponse {
  key: string
  url: string
}

export interface MediaDownloadPayload {
  sourceUrl: string
  prefix?: string | null
  targetFormat?: 'original' | 'webp' | 'avif' | null
  title?: string | null
  altText?: string | null
  caption?: string | null
  tags?: string[]
  notes?: string | null
  sync?: boolean
}

export interface AdminMediaDownloadResponse {
  queued: boolean
  job_id: number | null
  status: string | null
  key: string | null
  url: string | null
  size_bytes: number | null
  content_type: string | null
}

export interface MediaAssetMetadataPayload {
  key: string
  title?: string | null
  altText?: string | null
  caption?: string | null
  tags?: string[]
  notes?: string | null
}

export interface AdminMediaMetadataResponse {
  saved: boolean
  key: string
  title: string | null
  alt_text: string | null
  caption: string | null
  tags: string[]
  notes: string | null
}

export interface SiteBackupDocument {
  version: string
  exported_at: string
  includes_storage_binaries: boolean
  warning: string
  site_settings: Record<string, unknown>
  categories: Record<string, unknown>[]
  tags: Record<string, unknown>[]
  reviews: Record<string, unknown>[]
  friend_links: Record<string, unknown>[]
  media_assets: Record<string, unknown>[]
  storage_manifest?: Record<string, unknown>[] | null
  posts: Array<{
    slug: string
    file_name: string
    markdown: string
  }>
}

export interface SiteBackupImportPayload {
  backup: SiteBackupDocument
  mode?: 'merge' | 'replace' | string
}

export interface SiteBackupImportResponse {
  imported: boolean
  mode: string
  site_settings_restored: boolean
  posts_written: number
  categories_upserted: number
  tags_upserted: number
  reviews_upserted: number
  friend_links_upserted: number
  media_assets_upserted: number
  storage_manifest_items: number
  includes_storage_binaries: boolean
  warning: string
}

export interface CommentBlacklistRecord {
  id: number
  matcher_type: 'ip' | 'email' | 'user_agent' | string
  matcher_value: string
  reason: string | null
  active: boolean
  expires_at: string | null
  created_at: string
  updated_at: string
  effective: boolean
}

export interface CommentPersonaAnalysisSample {
  id: number
  created_at: string
  post_slug: string
  author: string
  email: string
  approved: boolean
  content_preview: string
}

export interface CommentPersonaAnalysisResponse {
  matcher_type: 'ip' | 'email' | 'user_agent' | string
  matcher_value: string
  total_comments: number
  pending_comments: number
  first_seen_at: string | null
  latest_seen_at: string | null
  distinct_posts: number
  analysis: string
  samples: CommentPersonaAnalysisSample[]
}

export interface CommentPersonaAnalysisLogRecord {
  id: number
  matcher_type: 'ip' | 'email' | 'user_agent' | string
  matcher_value: string
  from_at: string | null
  to_at: string | null
  total_comments: number
  pending_comments: number
  distinct_posts: number
  analysis: string
  samples: CommentPersonaAnalysisSample[]
  created_at: string
}

export interface MusicTrack {
  title: string
  artist?: string | null
  album?: string | null
  url: string
  cover_image_url?: string | null
  accent_color?: string | null
  description?: string | null
}

export interface AdminPostMetadataResponse {
  title: string
  description: string
  category: string
  tags: string[]
  slug: string
}

export interface AdminPostPolishResponse {
  polished_markdown: string
}

export interface AdminPostLocalizeImagesFailure {
  source_url: string
  error: string
}

export interface AdminPostLocalizedImageItem {
  source_url: string
  localized_url: string
  key: string
}

export interface AdminPostLocalizeImagesResponse {
  markdown: string
  detected_count: number
  localized_count: number
  uploaded_count: number
  failed_count: number
  items: AdminPostLocalizedImageItem[]
  failures: AdminPostLocalizeImagesFailure[]
}

export interface AdminReviewPolishRequest {
  title: string
  reviewType: string
  rating: number
  reviewDate?: string | null
  status: string
  tags: string[]
  description: string
}

export interface AdminReviewPolishResponse {
  polished_description: string
}

export interface AdminPostCoverImageRequest {
  title: string
  description?: string | null
  category?: string | null
  tags: string[]
  postType: string
  slug?: string | null
  markdown: string
}

export interface AdminPostCoverImageResponse {
  image_url: string
  prompt: string
}

export interface PostRecord {
  created_at: string
  updated_at: string
  id: number
  title: string | null
  slug: string
  description: string | null
  content: string | null
  category: string | null
  tags: unknown
  post_type: string | null
  image: string | null
  images: string[] | null
  pinned: boolean | null
  status: string | null
  visibility: string | null
  publish_at: string | null
  unpublish_at: string | null
  canonical_url: string | null
  noindex: boolean | null
  og_image: string | null
  redirect_from: string[] | null
  redirect_to: string | null
}

export interface PostListQuery {
  slug?: string
  category?: string
  tag?: string
  search?: string
  postType?: string
  pinned?: boolean
  status?: string
  visibility?: string
  listedOnly?: boolean
  includePrivate?: boolean
  includeRedirects?: boolean
  preview?: boolean
  page?: number
  pageSize?: number
  sortBy?: 'created_at' | 'updated_at' | 'title' | string
  sortOrder?: 'asc' | 'desc' | string
}

export interface PostPageResponse {
  items: PostRecord[]
  page: number
  page_size: number
  total: number
  total_pages: number
  sort_by: string
  sort_order: string
}

export interface CreatePostPayload {
  title: string
  slug?: string | null
  description?: string | null
  content?: string | null
  category?: string | null
  tags?: string[]
  postType?: string | null
  image?: string | null
  images?: string[] | null
  pinned?: boolean
  status?: string | null
  visibility?: string | null
  publishAt?: string | null
  unpublishAt?: string | null
  canonicalUrl?: string | null
  noindex?: boolean
  ogImage?: string | null
  redirectFrom?: string[]
  redirectTo?: string | null
  published?: boolean
}

export interface UpdatePostPayload {
  title?: string | null
  slug: string
  description?: string | null
  content?: string | null
  category?: string | null
  tags?: unknown
  postType?: string | null
  image?: string | null
  images?: string[] | null
  pinned?: boolean | null
  status?: string | null
  visibility?: string | null
  publishAt?: string | null
  unpublishAt?: string | null
  canonicalUrl?: string | null
  noindex?: boolean | null
  ogImage?: string | null
  redirectFrom?: string[]
  redirectTo?: string | null
}

export interface MarkdownDocumentResponse {
  slug: string
  path: string
  markdown: string
}

export interface MarkdownDeleteResponse {
  slug: string
  deleted: boolean
}

export interface MarkdownImportResponse {
  count: number
  slugs: string[]
}

export interface CommentRecord {
  created_at: string
  updated_at: string
  id: number
  post_id: string | null
  post_slug: string | null
  author: string | null
  email: string | null
  avatar: string | null
  ip_address: string | null
  user_agent: string | null
  referer: string | null
  content: string | null
  scope: string
  paragraph_key: string | null
  paragraph_excerpt: string | null
  reply_to: string | null
  reply_to_comment_id: number | null
  approved: boolean | null
}

export interface CommentListQuery {
  postId?: string
  postSlug?: string
  scope?: string
  paragraphKey?: string
  approved?: boolean
}

export interface UpdateCommentPayload {
  post_id?: string | null
  post_slug?: string | null
  author?: string | null
  email?: string | null
  avatar?: string | null
  content?: string | null
  reply_to?: string | null
  reply_to_comment_id?: number | null
  scope?: string | null
  paragraph_key?: string | null
  paragraph_excerpt?: string | null
  approved?: boolean
}

export interface FriendLinkRecord {
  created_at: string
  updated_at: string
  id: number
  site_name: string | null
  site_url: string
  avatar_url: string | null
  description: string | null
  category: string | null
  status: string | null
}

export interface FriendLinkListQuery {
  status?: string
  category?: string
}

export interface FriendLinkPayload {
  siteName?: string | null
  siteUrl: string
  avatarUrl?: string | null
  description?: string | null
  category?: string | null
  status?: string | null
}

export interface ReviewRecord {
  id: number
  title: string | null
  review_type: string | null
  rating: number | null
  review_date: string | null
  status: string | null
  description: string | null
  tags: string | null
  cover: string | null
  link_url: string | null
  created_at: string
  updated_at: string
}

export interface CreateReviewPayload {
  title: string
  review_type: string
  rating: number
  review_date: string
  status: string
  description: string
  tags: string[]
  cover: string
  link_url?: string | null
}

export interface UpdateReviewPayload {
  title?: string
  review_type?: string
  rating?: number
  review_date?: string
  status?: string
  description?: string
  tags?: string[]
  cover?: string
  link_url?: string | null
}
