CREATE TABLE IF NOT EXISTS listings (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  platform TEXT NOT NULL,
  ai_provider TEXT NOT NULL,
  title TEXT,
  description TEXT,
  description_html TEXT,
  tags TEXT,
  photos TEXT,
  seller_notes TEXT,
  brand TEXT,
  category TEXT,
  size TEXT,
  color TEXT,
  condition TEXT,
  price REAL,
  status TEXT DEFAULT 'active',
  language TEXT DEFAULT 'de',
  created_by INTEGER,
  updated_by INTEGER,
  created_at TEXT DEFAULT (datetime('now')),
  updated_at TEXT
);

CREATE TABLE IF NOT EXISTS templates (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  platform TEXT,
  seller_notes TEXT,
  language TEXT DEFAULT 'de',
  default_tags TEXT,
  created_at TEXT DEFAULT (datetime('now'))
);

CREATE TABLE IF NOT EXISTS settings (
  key TEXT PRIMARY KEY,
  value TEXT
);

CREATE TABLE IF NOT EXISTS publish_log (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  listing_id INTEGER NOT NULL,
  platform TEXT NOT NULL,
  status TEXT DEFAULT 'pending',
  external_id TEXT,
  external_url TEXT,
  offer_id TEXT,
  sync_status TEXT,
  last_synced_at TEXT,
  ended_at TEXT,
  updated_at TEXT,
  published_at TEXT,
  created_at TEXT DEFAULT (datetime('now')),
  FOREIGN KEY (listing_id) REFERENCES listings(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_publish_log_external ON publish_log(platform, external_id);

INSERT OR IGNORE INTO settings (key, value) VALUES ('default_platform', 'vinted');
INSERT OR IGNORE INTO settings (key, value) VALUES ('default_ai', 'claude');
INSERT OR IGNORE INTO settings (key, value) VALUES ('seller_notes', '');
INSERT OR IGNORE INTO settings (key, value) VALUES ('default_language', 'de');

CREATE TABLE IF NOT EXISTS mobile_upload_sessions (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  token_hash TEXT NOT NULL UNIQUE,
  user_id INTEGER,
  listing_id INTEGER,
  context TEXT NOT NULL DEFAULT 'generator',
  files TEXT NOT NULL DEFAULT '[]',
  status TEXT NOT NULL DEFAULT 'active',
  expires_at TEXT NOT NULL,
  created_at TEXT DEFAULT (datetime('now')),
  updated_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_mobile_upload_token ON mobile_upload_sessions(token_hash);
CREATE INDEX IF NOT EXISTS idx_mobile_upload_expires ON mobile_upload_sessions(expires_at);


INSERT OR IGNORE INTO settings (key, value) VALUES ('ai_model_photos_enabled', '1');
INSERT OR IGNORE INTO settings (key, value) VALUES ('ai_model_photo_default_variants', '1');
INSERT OR IGNORE INTO settings (key, value) VALUES ('ai_model_photo_default_preset', 'mixed');
INSERT OR IGNORE INTO settings (key, value) VALUES ('ai_model_photo_block_underwear', '1');
INSERT OR IGNORE INTO settings (key, value) VALUES ('ai_model_photo_block_kids', '1');
INSERT OR IGNORE INTO settings (key, value) VALUES ('ai_model_photo_provider', 'openai');

CREATE TABLE IF NOT EXISTS ai_model_generations (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  listing_id INTEGER,
  context TEXT NOT NULL DEFAULT 'generator',
  preset TEXT NOT NULL,
  variants INTEGER NOT NULL DEFAULT 3,
  source_photos TEXT NOT NULL DEFAULT '[]',
  generated_photos TEXT NOT NULL DEFAULT '[]',
  prompt_summary TEXT,
  moderation_notes TEXT,
  safety_status TEXT NOT NULL DEFAULT 'pending',
  status TEXT NOT NULL DEFAULT 'pending',
  created_at TEXT DEFAULT (datetime('now')),
  updated_at TEXT,
  FOREIGN KEY (listing_id) REFERENCES listings(id) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_ai_model_generations_listing ON ai_model_generations(listing_id);

CREATE TABLE IF NOT EXISTS ai_model_photos (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  generation_id INTEGER NOT NULL,
  listing_id INTEGER,
  variant_index INTEGER NOT NULL DEFAULT 1,
  preset TEXT NOT NULL,
  image_path TEXT NOT NULL,
  source_photo TEXT,
  prompt TEXT,
  moderation_result TEXT,
  safety_status TEXT NOT NULL DEFAULT 'pending',
  created_at TEXT DEFAULT (datetime('now')),
  FOREIGN KEY (generation_id) REFERENCES ai_model_generations(id) ON DELETE CASCADE,
  FOREIGN KEY (listing_id) REFERENCES listings(id) ON DELETE SET NULL
);
CREATE INDEX IF NOT EXISTS idx_ai_model_photos_listing ON ai_model_photos(listing_id);


CREATE TABLE IF NOT EXISTS flux_images (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  prompt TEXT NOT NULL,
  image_path TEXT NOT NULL UNIQUE,
  width INTEGER,
  height INTEGER,
  seed INTEGER,
  steps INTEGER,
  style TEXT DEFAULT 'none',
  edited_from INTEGER,
  created_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_flux_images_created ON flux_images(created_at DESC);


CREATE TABLE IF NOT EXISTS quality_reports (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  listing_id INTEGER NOT NULL,
  score INTEGER NOT NULL DEFAULT 0,
  grade TEXT NOT NULL DEFAULT 'E',
  ready INTEGER NOT NULL DEFAULT 0,
  blockers INTEGER NOT NULL DEFAULT 0,
  warnings INTEGER NOT NULL DEFAULT 0,
  recommendations INTEGER NOT NULL DEFAULT 0,
  report_json TEXT NOT NULL DEFAULT '{}',
  analyzed_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY(listing_id) REFERENCES listings(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_quality_reports_listing ON quality_reports(listing_id, id DESC);
CREATE INDEX IF NOT EXISTS idx_quality_reports_score ON quality_reports(score, analyzed_at DESC);


CREATE TABLE IF NOT EXISTS publishing_jobs (
  id TEXT PRIMARY KEY,
  listing_id INTEGER NOT NULL,
  platform TEXT NOT NULL,
  mode TEXT NOT NULL DEFAULT 'api',
  action TEXT NOT NULL DEFAULT 'publish',
  status TEXT NOT NULL DEFAULT 'queued',
  phase TEXT NOT NULL DEFAULT 'queued',
  idempotency_key TEXT NOT NULL UNIQUE,
  external_id TEXT,
  external_url TEXT,
  offer_id TEXT,
  retries INTEGER NOT NULL DEFAULT 0,
  max_retries INTEGER NOT NULL DEFAULT 3,
  next_attempt_at TEXT,
  claimed_by TEXT,
  claimed_at TEXT,
  error_code TEXT,
  error_message TEXT,
  payload_json TEXT NOT NULL DEFAULT '{}',
  result_json TEXT NOT NULL DEFAULT '{}',
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  started_at TEXT,
  completed_at TEXT,
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY(listing_id) REFERENCES listings(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_publishing_jobs_status ON publishing_jobs(status, next_attempt_at, created_at);
CREATE INDEX IF NOT EXISTS idx_publishing_jobs_listing ON publishing_jobs(listing_id, platform, created_at DESC);

CREATE TABLE IF NOT EXISTS publishing_events (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  job_id TEXT,
  listing_id INTEGER NOT NULL,
  platform TEXT NOT NULL,
  level TEXT NOT NULL DEFAULT 'info',
  event_type TEXT NOT NULL,
  message TEXT NOT NULL,
  details_json TEXT NOT NULL DEFAULT '{}',
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY(job_id) REFERENCES publishing_jobs(id) ON DELETE SET NULL,
  FOREIGN KEY(listing_id) REFERENCES listings(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_publishing_events_job ON publishing_events(job_id, id DESC);
CREATE INDEX IF NOT EXISTS idx_publishing_events_listing ON publishing_events(listing_id, id DESC);


-- Mehrbenutzer- und Sicherheitsgrundlage 1.31.0
CREATE TABLE IF NOT EXISTS users (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  email TEXT UNIQUE NOT NULL,
  name TEXT NOT NULL DEFAULT '',
  password_hash TEXT,
  role TEXT NOT NULL DEFAULT 'editor',
  active INTEGER NOT NULL DEFAULT 1,
  avatar_color TEXT,
  last_active_at TEXT,
  failed_login_count INTEGER NOT NULL DEFAULT 0,
  locked_until TEXT,
  password_changed_at TEXT,
  created_at TEXT DEFAULT (datetime('now')),
  invited_by INTEGER
);

CREATE TABLE IF NOT EXISTS sessions (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  user_id INTEGER NOT NULL,
  token_hash TEXT UNIQUE NOT NULL,
  ip TEXT,
  user_agent TEXT,
  expires_at TEXT NOT NULL,
  last_seen_at TEXT,
  revoked_at TEXT,
  created_at TEXT DEFAULT (datetime('now')),
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS audit_log (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  user_id INTEGER,
  user_email TEXT,
  action TEXT NOT NULL,
  target_type TEXT,
  target_id TEXT,
  details TEXT,
  ip TEXT,
  created_at TEXT DEFAULT (datetime('now'))
);

CREATE TABLE IF NOT EXISTS resource_locks (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  resource_type TEXT NOT NULL,
  resource_id TEXT NOT NULL,
  user_id INTEGER NOT NULL,
  token_hash TEXT NOT NULL UNIQUE,
  acquired_at TEXT NOT NULL DEFAULT (datetime('now')),
  renewed_at TEXT NOT NULL DEFAULT (datetime('now')),
  expires_at TEXT NOT NULL,
  client_label TEXT,
  FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
  UNIQUE(resource_type, resource_id)
);
CREATE INDEX IF NOT EXISTS idx_resource_locks_expiry ON resource_locks(expires_at);
CREATE INDEX IF NOT EXISTS idx_resource_locks_user ON resource_locks(user_id, expires_at);

-- Natives Theme-Modul 1.36.0
CREATE TABLE IF NOT EXISTS theme_profiles (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL,
  base_theme TEXT NOT NULL DEFAULT 'light',
  values_json TEXT NOT NULL DEFAULT '{}',
  created_by INTEGER,
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY(created_by) REFERENCES users(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS user_theme_preferences (
  user_id INTEGER PRIMARY KEY,
  theme_id TEXT NOT NULL DEFAULT 'inherit',
  density TEXT NOT NULL DEFAULT 'comfortable',
  reduced_motion TEXT NOT NULL DEFAULT 'system',
  updated_at TEXT NOT NULL DEFAULT (datetime('now')),
  FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_theme_profiles_updated ON theme_profiles(updated_at DESC);
