import type Database from 'better-sqlite3';

export interface Post {
  id: number; title: string; slug: string; category: string; excerpt: string;
  body_html: string; cover: string | null; draft: number; author_id: number | null;
  published_at: string | null; created_at: string; updated_at: string;
}

export interface PostInput {
  title: string; slug: string; category: string; excerpt: string;
  body_html: string; cover?: string | null; draft: boolean; author_id?: number | null;
}

export function createPost(db: Database.Database, input: PostInput): number {
  const res = db.prepare(
    `INSERT INTO posts (title, slug, category, excerpt, body_html, cover, draft, author_id, published_at)
     VALUES (@title, @slug, @category, @excerpt, @body_html, @cover, @draft, @author_id,
             CASE WHEN @draft = 0 THEN datetime('now') ELSE NULL END)`
  ).run({ ...input, cover: input.cover ?? null, author_id: input.author_id ?? null, draft: input.draft ? 1 : 0 });
  return Number(res.lastInsertRowid);
}

export function updatePost(db: Database.Database, id: number, input: PostInput): void {
  db.prepare(
    `UPDATE posts SET title = @title, slug = @slug, category = @category,
       excerpt = @excerpt, body_html = @body_html, cover = @cover, draft = @draft,
       published_at = CASE WHEN @draft = 0 AND published_at IS NULL THEN datetime('now') ELSE published_at END,
       updated_at = datetime('now')
     WHERE id = @id`
  ).run({ ...input, id, cover: input.cover ?? null, draft: input.draft ? 1 : 0 });
}

export function deletePost(db: Database.Database, id: number): void {
  db.prepare('DELETE FROM posts WHERE id = ?').run(id);
}

export function getPostById(db: Database.Database, id: number): Post | undefined {
  return db.prepare('SELECT * FROM posts WHERE id = ?').get(id) as Post | undefined;
}

export function getPublishedBySlug(db: Database.Database, slug: string): Post | undefined {
  return db.prepare('SELECT * FROM posts WHERE slug = ? AND draft = 0').get(slug) as Post | undefined;
}

export function listPublished(
  db: Database.Database,
  opts: { category?: string; page?: number; perPage?: number } = {},
): { items: Post[]; total: number } {
  const { category, page = 1, perPage = 9 } = opts;
  const where = category ? 'WHERE draft = 0 AND category = @category' : 'WHERE draft = 0';
  const total = (db.prepare(`SELECT COUNT(*) AS n FROM posts ${where}`)
    .get({ category }) as { n: number }).n;
  const items = db.prepare(
    `SELECT * FROM posts ${where} ORDER BY published_at DESC LIMIT @limit OFFSET @offset`
  ).all({ category, limit: perPage, offset: (page - 1) * perPage }) as Post[];
  return { items, total };
}

export function listAllPosts(db: Database.Database): Post[] {
  return db.prepare('SELECT * FROM posts ORDER BY updated_at DESC').all() as Post[];
}

export function listRecent(db: Database.Database, limit = 4): Post[] {
  return db.prepare(
    'SELECT * FROM posts WHERE draft = 0 ORDER BY published_at DESC LIMIT ?'
  ).all(limit) as Post[];
}

export function listArchiveMonths(db: Database.Database): { month: string; count: number }[] {
  return db.prepare(
    `SELECT strftime('%Y-%m', published_at) AS month, COUNT(*) AS count
     FROM posts WHERE draft = 0 GROUP BY month ORDER BY month DESC`
  ).all() as { month: string; count: number }[];
}

export function listByAuthor(db: Database.Database, authorId: number): Post[] {
  return db.prepare('SELECT * FROM posts WHERE author_id = ? ORDER BY updated_at DESC').all(authorId) as Post[];
}

export function canModifyPost(role: string, userId: number, post: { author_id: number | null }): boolean {
  if (role === 'admin' || role === 'superuser') return true;
  return post.author_id === userId;
}
