// ============================================
// API Type Definitions
// ============================================
// These types are globally available in all .ts files.
// No imports needed - just use the type names directly.
// ============================================

// Matches database.SearchMediaItemsRow from /api/media-items/search
// Source: internal/database/queries.sql.go:6123-6170 SearchMediaItemsRow
// Endpoint: internal/handlers/media.go:SearchMediaItems()
// Note: internal/handlers/search.go has an unused MediaItemSummary - ignore it
// Used in: search.ts
interface MediaItemSummary {
  id: string;
  library_id: string;
  title: string;
  author?: string;
  isbn?: string;
  description?: string;
  file_path: string;
  file_size?: number;
  mime_type?: string;
  cover_image_path?: string;
  series?: string;
  series_number?: number;
  tags?: string[];
  asin?: string;
  date_published?: string;
  publisher?: string;
  contributors?: string[];
  language?: string;
  edition?: string;
  page_count?: number;
  genre?: string;
  copyright_year?: number;
  goodreads_id?: string;
  openlibrary_id?: string;
  google_books_id?: string;
  added_by_admin_id?: string;
  created_at: string;
  updated_at: string;
  format_group: string;
  format_mimetype?: string;
  is_reflowable?: boolean;
  has_fixed_layout?: boolean;
  total_characters?: number;
  chapter_count?: number;
  entitlement_id?: string;
  revision_number?: number;
  kobo_content_id?: string;
  kobo_metadata?: string;
  tags_search?: string[];
  contributors_search?: string[];
  file_sha256?: string;
  opf_identifier?: string;
  opf_uuid?: string;
  hash_confidence?: string;
  library_name: string;
  library_type_name: string;

  // NEW: Reading direction fields for manga/comics
  manga_type?: 'unknown' | 'no' | 'yes' | 'yes_and_right_to_left';
  reading_direction?: 'auto' | 'ltr' | 'rtl' | 'vertical';

  // NEW: Universal metadata fields (apply to ebooks, audiobooks, comics)
  series_count?: number;
  volume?: number;
  imprint?: string;
  age_rating?: string; // 'Everyone' | 'Teen' | 'Mature' | 'Adult'
  web_url?: string;
  metadata_notes?: string;
  community_rating?: number;

  // NEW: Comic-specific fields
  story_arc?: string;
  is_black_and_white?: boolean;
  alternate_info?: { alternate_series?: string; alternate_number?: number; alternate_count?: number };
  scan_information?: string;
  summary?: string;
}

// Matches handlers.CollectionData / CollectionResponse JSON response
// Source: internal/handlers/collections.go:123-131 CollectionResponse
// Used in: collections.ts
interface CollectionData {
  id: string;
  name: string;
  description: string;
  color: string;
  icon: string;
  auto_assign_rules?: unknown;
  created_at: string;
  book_count?: number;
}

// Matches handlers.BookInfo JSON response (internal/handlers/collections.go:66-71)
// JSON tags: media_item_id, title, author, cover_image_path, has_conflict
// Used in: collections.templ (server-rendered), collections.ts, dashboard.ts
interface BookInfo {
  media_item_id: string;
  title: string;
  author: string;
  cover_image_path: string;
  has_conflict: boolean;
}

// Dashboard type definitions
// CRITICAL: Must match Go handler return types EXACTLY
// Source: handlers.SectionData in collections.go (lines 73-81)
// Used in: dashboard API responses, TypeScript dashboard components
interface SectionData {
  id: string;
  is_system: boolean;
  title: string;
  description: string;
  icon: string;
  items: BookInfo[];
  view_all_url: string;
  priority: number;
}

// Matches database.UserDashboardPreferences and dashboard preferences API
// Source: internal/database/models.go:381-390
// Used in: dashboard preferences API
interface DashboardPreferences {
  library_id: string;
  hidden_collections: string[];
  collection_order: string[];
  items_per_section: number;
}

// Matches handlers.UnlinkedBookData JSON response
// Used in: unlinked_books.ts, unlinked_books.templ
interface UnlinkedBookData {
  progress_id: string;
  device_id: string;
  device_name: string;
  device_type: "koreader" | "kobo" | "web";
  title_from_device: string;
  file_path: string;
  sha256: string;
  last_sync_time: string;
  confidence_score: number;
  potential_matches: PotentialMatchData[];
}

interface PotentialMatchData {
  media_item_id: string;
  title: string;
  author: string;
  confidence: number;
  cover_image_path?: string;
}

// Matches collection rule objects
// Used in: collection_rules.ts
interface CollectionRule {
  id: string;
  field:
    | "genre"
    | "series"
    | "author"
    | "language"
    | "publisher"
    | "copyright_year"
    | "tags";
  operator:
    | "equals"
    | "not_equals"
    | "contains"
    | "not_contains"
    | "starts_with"
    | "ends_with"
    | "greater_than"
    | "less_than";
  value: string;
  enabled: boolean;
  priority: number;
}

// Matches API test rule responses
// Used in: collection_rules.ts (test results)
interface TestRuleMatch {
  title: string;
  author: string;
  cover_image_path?: string;
  match_reason?: string;
}

// Matches handlers.SearchResponse (internal/handlers/search.go)
interface SearchResponse {
  results: SearchBookResponse[];
  total: number;
}

interface SearchBookResponse {
  id: string;
  title: string;
  authors: SearchAuthor[];
}

interface SearchAuthor {
  first_name: string;
  last_name: string;
}

// Matches AuthResponse (internal/handlers/auth.go:59-65)
interface AuthResponse {
  access_token: string;
  refresh_token?: string;
  token_type: string;
  expires_in: number;
  user: UserProfile;
}

interface UserProfile {
  id: string;
  email: string;
  username: string;
  first_name?: string;
  last_name?: string;
  role: string;
  theme?: string;
}

// Matches handlers.ReadingStatsResponse (internal/handlers/analytics.go:26-35)
// Used in: analytics.ts
interface ReadingStatsResponse {
  total_books_read: number;
  total_pages_read: number;
  total_reading_time_minutes: number;
  average_session_time_minutes: number;
  longest_session_minutes: number;
  most_active_day_of_week: string;
  completion_rate: number;
  daily_reading_minutes: DailyReading[];
}

interface DailyReading {
  date: string;
  minutes: number;
  pages: number;
}

// Matches handlers.DeviceUsageResponse (internal/handlers/analytics.go:43-45)
// Note: Response is wrapped: { devices: DeviceUsage[] }
// Used in: analytics.ts
interface DeviceUsageResponse {
  devices: DeviceUsage[];
}

interface DeviceUsage {
  device_id: string;
  device_name: string;
  device_type: string;
  sync_count: number;
  last_sync: string;
  total_time_seconds: number;
  total_time_minutes: number;
}

// Matches handlers.PopularBooksResponse (internal/handlers/analytics.go:57-59)
// Note: Response is wrapped: { books: PopularBook[] }
// Used in: analytics.ts
interface PopularBooksResponse {
  books: PopularBook[];
}

interface PopularBook {
  media_item_id: string;
  title: string;
  author: string;
  read_count: number;
  avg_completion: number;
  last_read: string;
}

// Matches handlers.QueueItemResponse (internal/handlers/queue.go:35-51)
// Used in: queue.ts
interface QueueItemResponse {
  id: string;
  device_id: string;
  device_name: string;
  device_type: string;
  media_item_id?: string;
  media_title?: string;
  user_email: string;
  sync_type: string;
  priority: number;
  attempts: number;
  max_attempts: number;
  status: string;
  error_message?: string;
  created_at: string;
  processed_at?: string;
}

// Matches handlers.QueueStatsResponse (internal/handlers/queue.go:27-33)
// Used in: queue.ts
interface QueueStatsResponse {
  pending_count: number;
  processing_count: number;
  failed_count: number;
  completed_count: number;
  total_count: number;
}

// Matches handlers.ConflictDetailResponse (internal/handlers/conflicts.go:42-53)
// Used in: conflicts.ts
interface ConflictDetailResponse {
  id: string;
  media_item_id: string;
  media_item_title: string;
  conflict_type: string;
  conflict_data: Record<string, ConflictSourceData>;
  resolution_status: string;
  resolution_data?: Record<string, unknown>;
  resolved_by?: string;
  resolved_at?: string;
  created_at: string;
}

// Matches handlers.ConflictSourceData (internal/handlers/conflicts.go:36-40)
interface ConflictSourceData {
  source: string;
  timestamp: string;
  data: Record<string, unknown>;
}

// Matches handlers.ConflictListResponse (internal/handlers/conflicts.go:55-59)
// Used in: conflicts.ts
interface ConflictListResponse {
  conflicts: ConflictDetailResponse[];
  total: number;
  unresolved: number;
}

// Matches handlers.ConflictResolveResponse (internal/handlers/conflicts.go:61-65)
// Used in: conflicts.ts
interface ConflictResolveResponse {
  conflict_resolved: boolean;
  applied_to: Record<string, boolean>;
  devices_synced: string[];
}

// Matches handlers.BulkResolveResponse (internal/handlers/conflicts.go:424-429)
// Used in: conflicts.ts
interface BulkResolveResponse {
  results: ConflictResult[];
  total: number;
  success: number;
  failed: number;
}

// Matches handlers.ConflictResult (internal/handlers/conflicts.go:431-436)
interface ConflictResult {
  conflict_id: string;
  status: string;
  error?: string;
  winner?: string;
}
