import { Router, Request, Response } from 'express';
import { asyncHandler } from '../utils/asyncHandler';
import { db } from '../db';
import { users, userSettings, categories } from '../db/schema';
import { eq, and, ilike } from 'drizzle-orm';
import { authMiddleware } from '../utils/auth';
import { AppError } from '../middleware/errorHandler';
import { userSettingsSchema } from '../utils/validation';

const router = Router();

router.use(authMiddleware);

router.get('/me', asyncHandler(async (req: Request, res: Response) => {
  const userId = req.user!.userId;

  const user = await db.select().from(users).where(eq(users.id, userId)).limit(1);
  if (user.length === 0) {
    throw new AppError('NOT_FOUND', 'User not found', 404);
  }

  const settings = await db
    .select()
    .from(userSettings)
    .where(eq(userSettings.userId, userId))
    .limit(1);

  let defaultCategory = settings[0]?.defaultCategory;
  if (defaultCategory) {
    const cat = await db
      .select()
      .from(categories)
      .where(and(eq(categories.id, defaultCategory), eq(categories.userId, userId)))
      .limit(1);
    if (cat.length === 0) {
      defaultCategory = null;
    }
  }

  res.json({
    id: user[0].id,
    username: user[0].username,
    settings: {
      darkMode: settings[0]?.darkMode ?? false,
      notifications: settings[0]?.notifications ?? true,
      reminderTime: settings[0]?.reminderTime ?? '09:00',
      defaultCategory,
      sortBy: settings[0]?.sortBy ?? 'dueDate',
      sortOrder: settings[0]?.sortOrder ?? 'asc',
    },
    createdAt: user[0].createdAt,
  });
}));

router.patch('/me/settings', asyncHandler(async (req: Request, res: Response) => {
  const data = userSettingsSchema.parse(req.body);
  const userId = req.user!.userId;

  // Validate defaultCategory if provided
  if (data.defaultCategory) {
    const cat = await db
      .select()
      .from(categories)
      .where(and(eq(categories.id, data.defaultCategory), eq(categories.userId, userId)))
      .limit(1);
    if (cat.length === 0) {
      throw new AppError('NOT_FOUND', 'Default category not found', 404);
    }
  }

  const now = Date.now();
  const existing = await db
    .select()
    .from(userSettings)
    .where(eq(userSettings.userId, userId))
    .limit(1);

  if (existing.length === 0) {
    await db.insert(userSettings).values({
      userId,
      ...data,
      updatedAt: now,
    });
  } else {
    await db
      .update(userSettings)
      .set({ ...data, updatedAt: now })
      .where(eq(userSettings.userId, userId));
  }

  res.status(200).json({ success: true });
}));

router.get('/search', asyncHandler(async (req: Request, res: Response) => {
  const { q } = req.query;
  const userId = req.user!.userId;

  if (!q || typeof q !== 'string' || q.length < 2) {
    return res.json([]);
  }

  const results = await db
    .select({ id: users.id, username: users.username })
    .from(users)
    .where(and(ilike(users.username, `%${q}%`), eq(users.id, userId)))
    .limit(10);

  res.json(results);
}));

export default router;