export type LoopStatus =
  | "IDLE"
  | "RUNNING"
  | "WAITING_DELAY"
  | "STOPPED"
  | "ERROR"
  | "COMPLETED";

export type EnforcementMode = "aggressive-soft";

export interface User {
  username: string;
  passwordHash: string;
  createdAt: string;
}

export interface Settings {
  pollIntervalMs: number;
  enforceIntervalMs: number;
  defaultDelayMs: number;
  maxLoopLimit: number;
}

export interface LoopJob {
  id: string;
  torrentHash: string;
  name: string;
  sizeBytes: number;
  magnet?: string;
  torrentFilePath?: string;
  allowIp: string;
  targetLoops: number;
  doneLoops: number;
  delayMs: number;
  profileName?: string;
  profileId?: string;
  deleteDataBetweenLoops: boolean;
  enforcementMode: EnforcementMode;
  status: LoopStatus;
  currentRun?: {
    startedAt: string;
    lastProgress: number;
    lastProgressAt?: string;
    stalledSince?: string;
    downloadedThisRunBytes: number;
    avgSpeed: number;
  };
  totals: {
    totalDownloadedBytes: number;
    totalTimeMs: number;
  };
  bans: {
    bannedIps: string[];
    lastBanAt?: string;
  };
  nextRunAt?: string;
  createdAt: string;
  updatedAt: string;
  lastError?: string;
}

export interface Profile {
  id: string;
  name: string;
  allowIp: string;
  delayMs: number;
  profileName?: string;
  profileId?: string;
  targetLoops: number;
  createdAt: string;
}

export interface TimerRule {
  id: string;
  tags: string[];
  seedLimitSeconds: number;
  deleteFiles: boolean;
  createdAt: string;
}

export interface TimerLog {
  id: string;
  hash: string;
  name: string;
  sizeBytes: number;
  tracker?: string;
  tags: string[];
  category?: string;
  seedingTimeSeconds: number;
  uploadedBytes: number;
  deletedAt: string;
}

export interface TimerSummary {
  totalDeleted: number;
  totalSeededSeconds: number;
  totalUploadedBytes: number;
  updatedAt: string;
}

export type WatcherTracker = string;

export type WatcherItemStatus =
  | "bookmarked"
  | "downloading_torrent"
  | "sending_to_qbit"
  | "sent_to_qbit"
  | "downloading"
  | "completed"
  | "failed";

export interface Watcher {
  id: string;
  tracker: WatcherTracker;
  trackerLabel: string;
  wishlistUrl?: string;
  category?: string;
  cookieEncrypted: string;
  cookieHint: string;
  intervalMinutes: number;
  enabled: boolean;
  lastRunAt?: string;
  lastSuccessAt?: string;
  lastError?: string;
  nextRunAt?: string;
  totalImported: number;
  totalSeen: number;
  createdAt: string;
  updatedAt: string;
}

export interface WatcherItem {
  id: string;
  watcherId: string;
  tracker: WatcherTracker;
  trackerLabel: string;
  sourceKey: string;
  pageUrl: string;
  title: string;
  imageUrl?: string;
  downloadUrl?: string;
  removeToken?: string;
  status: WatcherItemStatus;
  statusLabel: string;
  qbitHash?: string;
  qbitName?: string;
  qbitProgress?: number;
  qbitState?: string;
  qbitCategory?: string;
  sizeBytes?: number;
  seeders?: number;
  leechers?: number;
  trackerTorrentId?: string;
  seenAt: string;
  downloadedAt?: string;
  importedAt?: string;
  lastSyncAt: string;
  errorMessage?: string;
}

export interface WatcherRun {
  id: string;
  watcherId: string;
  startedAt: string;
  finishedAt?: string;
  status: "RUNNING" | "SUCCESS" | "FAILED";
  newBookmarks: number;
  importedCount: number;
  failedCount: number;
  message?: string;
}

export interface WatcherSummary {
  activeWatchers: number;
  totalImported: number;
  totalSeen: number;
  trackedLabels: string[];
  lastRunAt?: string;
  lastSuccessAt?: string;
  nextRunAt?: string;
  lastError?: string;
  updatedAt: string;
}

export interface AuditLog {
  id: string;
  level: "INFO" | "WARN" | "ERROR";
  event:
    | "JOB_STARTED"
    | "JOB_COMPLETED_LOOP"
    | "JOB_COMPLETED_ALL"
    | "JOB_RESTARTED"
    | "PEER_BANNED"
    | "QBIT_RELOGIN"
    | "ARCHIVE_SUCCESS"
    | "ARCHIVE_FAIL";
  message: string;
  createdAt: string;
}

export interface ArchiveStatus {
  hash: string;
  status: "PENDING" | "READY" | "FAILED" | "MISSING";
  torrentFilePath?: string;
  source?: "manual" | "generated" | "exported";
  lastError?: string;
  updatedAt: string;
}

export interface DbSchema {
  users: User[];
  settings: Settings;
  loopJobs: LoopJob[];
  profiles: Profile[];
  auditLogs: AuditLog[];
  archives: Record<string, ArchiveStatus>;
  timerRules?: TimerRule[];
  timerLogs?: TimerLog[];
  timerSummary?: TimerSummary;
  watchers?: Watcher[];
  watcherItems?: WatcherItem[];
  watcherRuns?: WatcherRun[];
  watcherSummary?: WatcherSummary;
}
