import db from './db';

export interface GuestbookEntry {
  id: number;
  display_name: string;
  message: string;
  website: string | null;
  ip_hash: string | null;
  status: 'pending' | 'approved' | 'rejected' | 'spam';
  created_at: string;
  moderated_at: string | null;
  moderation_note: string | null;
}

export interface SubmitData {
  display_name: string;
  message: string;
  website: string | null;
  ip_hash: string | null;
}

const PAGE_SIZE = 20;

export function getApprovedEntries(page = 1): { entries: GuestbookEntry[]; total: number; hasMore: boolean } {
  const offset = (page - 1) * PAGE_SIZE;
  const entries = db
    .prepare(
      `SELECT id, display_name, message, website, created_at
       FROM guestbook_entries
       WHERE status = 'approved'
       ORDER BY created_at DESC
       LIMIT ? OFFSET ?`
    )
    .all(PAGE_SIZE, offset) as GuestbookEntry[];

  const { total } = db
    .prepare(`SELECT COUNT(*) as total FROM guestbook_entries WHERE status = 'approved'`)
    .get() as { total: number };

  return { entries, total, hasMore: offset + PAGE_SIZE < total };
}

export function getPendingEntries(): GuestbookEntry[] {
  return db
    .prepare(
      `SELECT * FROM guestbook_entries WHERE status = 'pending' ORDER BY created_at ASC`
    )
    .all() as GuestbookEntry[];
}

export function getRecentModerated(limit = 30): GuestbookEntry[] {
  return db
    .prepare(
      `SELECT * FROM guestbook_entries
       WHERE status IN ('approved', 'rejected', 'spam')
       ORDER BY moderated_at DESC
       LIMIT ?`
    )
    .all(limit) as GuestbookEntry[];
}

export function submitEntry(data: SubmitData): number {
  const result = db
    .prepare(
      `INSERT INTO guestbook_entries (display_name, message, website, ip_hash)
       VALUES (?, ?, ?, ?)`
    )
    .run(data.display_name, data.message, data.website, data.ip_hash);

  return result.lastInsertRowid as number;
}

export function moderateEntry(
  id: number,
  status: 'approved' | 'rejected' | 'spam',
  note: string | null,
  sessionId: string
): boolean {
  const result = db
    .prepare(
      `UPDATE guestbook_entries
       SET status = ?, moderated_at = strftime('%Y-%m-%dT%H:%M:%SZ', 'now'), moderation_note = ?
       WHERE id = ? AND status = 'pending'`
    )
    .run(status, note, id);

  if (result.changes > 0) {
    db.prepare(
      `INSERT INTO audit_log (action, entry_id, admin_session, note) VALUES (?, ?, ?, ?)`
    ).run(`moderate:${status}`, id, sessionId, note);
  }

  return result.changes > 0;
}

export function checkRateLimit(ipHash: string): boolean {
  // Clean up old entries (>1 hour)
  db.prepare(
    `DELETE FROM rate_limit WHERE created_at < strftime('%Y-%m-%dT%H:%M:%SZ', 'now', '-1 hour')`
  ).run();

  const { count } = db
    .prepare(`SELECT COUNT(*) as count FROM rate_limit WHERE ip_hash = ?`)
    .get(ipHash) as { count: number };

  // Allow max 3 submissions per hour per IP hash
  return count < 3;
}

export function recordSubmission(ipHash: string): void {
  db.prepare(`INSERT INTO rate_limit (ip_hash) VALUES (?)`).run(ipHash);
}

export function isDuplicateSubmission(displayName: string, message: string): boolean {
  // Check for exact duplicate in last 24 hours (regardless of status)
  const row = db
    .prepare(
      `SELECT id FROM guestbook_entries
       WHERE display_name = ? AND message = ?
       AND created_at > strftime('%Y-%m-%dT%H:%M:%SZ', 'now', '-1 day')`
    )
    .get(displayName, message);

  return row !== undefined;
}
