import { Router } from 'express';
import { z } from 'zod';
import type { DatabaseSync } from 'node:sqlite';
import { requireAuth } from '../middleware/auth.ts';
import {
  listUserItems,
  markItemRead,
  markItemUnread,
  markItemsRead,
  markItemsUnread,
  getUserUnreadCount,
} from '../services/items.ts';
import { encodeCursor, decodeCursor } from '../services/cursor.ts';

const bulkSchema = z.object({ ids: z.array(z.number().int().positive()).min(1) });

type BulkBody = z.infer<typeof bulkSchema>;

export function createItemsRouter(db: DatabaseSync): Router {
  const router = Router();
  router.use(requireAuth);

  router.get('/', (req, res) => {
    const limit = Math.min(Number(req.query.limit) || 30, 100);
    const cursor = decodeCursor(req.query.cursor);
    const feedId = req.query.feedId ? Number(req.query.feedId) : null;
    const items = listUserItems(db, req.session.userId!, { cursor, limit, feedId });
    const nextCursor = items.length ? encodeCursor(items[items.length - 1]) : null;
    res.json({ items, nextCursor });
  });

  router.post('/:id/read', (req, res) => {
    markItemRead(db, req.session.userId!, Number(req.params.id));
    res.status(204).end();
  });

  router.post('/:id/unread', (req, res) => {
    markItemUnread(db, req.session.userId!, Number(req.params.id));
    res.status(204).end();
  });

  router.post('/read', (req, res) => {
    try {
      const body: BulkBody = bulkSchema.parse(req.body);
      markItemsRead(db, req.session.userId!, body.ids);
      res.status(204).end();
    } catch (e) {
      if (e instanceof z.ZodError) return res.status(400).json({ error: e.errors });
      res.status(400).json({ error: e instanceof Error ? e.message : String(e) });
    }
  });

  router.post('/unread', (req, res) => {
    try {
      const body: BulkBody = bulkSchema.parse(req.body);
      markItemsUnread(db, req.session.userId!, body.ids);
      res.status(204).end();
    } catch (e) {
      if (e instanceof z.ZodError) return res.status(400).json({ error: e.errors });
      res.status(400).json({ error: e instanceof Error ? e.message : String(e) });
    }
  });

  router.get('/unread-count', (req, res) => {
    res.json({ count: getUserUnreadCount(db, req.session.userId!) });
  });

  return router;
}
