import { Router } from 'express';
import { prisma } from '../../config/database.js';
import { requireModerator, requireAdmin, requireSuperAdmin } from '../../middleware/requireRole.js';
import { validate } from '../../middleware/validate.js';
import { banUserSchema, changeRoleSchema } from '../../validators/admin.js';
import { AppError } from '../../middleware/errorHandler.js';

const router = Router();

// GET /api/admin/users - List users
router.get('/', requireModerator, async (req, res, next) => {
  try {
    const { page = '1', pageSize = '20', search, role, status } = req.query;
    const skip = (parseInt(page as string) - 1) * parseInt(pageSize as string);
    const take = parseInt(pageSize as string);

    const where: any = {};
    if (search) {
      where.OR = [
        { fullName: { contains: search as string, mode: 'insensitive' } },
        { email: { contains: search as string, mode: 'insensitive' } },
      ];
    }
    if (role) where.role = role;
    if (status === 'banned') where.isBanned = true;
    if (status === 'active') where.isBanned = false;

    const [users, total] = await Promise.all([
      prisma.user.findMany({
        where,
        select: {
          id: true, email: true, fullName: true, nickname: true, avatar: true,
          role: true, isBanned: true, banReason: true, createdAt: true, location: true,
          _count: { select: { listings: true, sentOffers: true, reports: true } },
        },
        skip,
        take,
        orderBy: { createdAt: 'desc' },
      }),
      prisma.user.count({ where }),
    ]);

    res.json({
      data: users,
      total,
      page: parseInt(page as string),
      pageSize: take,
      totalPages: Math.ceil(total / take),
    });
  } catch (error) {
    next(error);
  }
});

// GET /api/admin/users/:id - User detail
router.get('/:id', requireModerator, async (req, res, next) => {
  try {
    const user = await prisma.user.findUnique({
      where: { id: req.params.id },
      select: {
        id: true, email: true, fullName: true, nickname: true, avatar: true,
        phone: true, location: true, bio: true, rating: true, ratingCount: true,
        role: true, isBanned: true, banReason: true, bannedAt: true, bannedBy: true,
        createdAt: true, updatedAt: true,
        _count: { select: { listings: true, sentOffers: true, receivedOffers: true, reports: true } },
      },
    });
    if (!user) throw new AppError(404, 'User not found');

    const moderationLogs = await prisma.moderationLog.findMany({
      where: { OR: [{ targetUserId: req.params.id }, { moderatorId: req.params.id }] },
      orderBy: { createdAt: 'desc' },
      take: 20,
      include: { moderator: { select: { id: true, fullName: true } } },
    });

    res.json({ user, moderationLogs });
  } catch (error) {
    next(error);
  }
});

// PATCH /api/admin/users/:id/role - Change role
router.patch('/:id/role', requireSuperAdmin, validate(changeRoleSchema), async (req, res, next) => {
  try {
    if (req.params.id === req.userId) {
      throw new AppError(400, 'Cannot change your own role');
    }

    const user = await prisma.user.update({
      where: { id: req.params.id },
      data: { role: req.body.role },
      select: { id: true, fullName: true, role: true },
    });

    await prisma.moderationLog.create({
      data: {
        moderatorId: req.userId!,
        targetUserId: req.params.id,
        action: 'WARNING',
        reason: `Role changed to ${req.body.role}`,
      },
    });

    res.json(user);
  } catch (error) {
    next(error);
  }
});

// POST /api/admin/users/:id/ban - Ban user
router.post('/:id/ban', requireAdmin, validate(banUserSchema), async (req, res, next) => {
  try {
    if (req.params.id === req.userId) {
      throw new AppError(400, 'Cannot ban yourself');
    }

    const target = await prisma.user.findUnique({ where: { id: req.params.id }, select: { role: true } });
    if (!target) throw new AppError(404, 'User not found');
    if (target.role === 'SUPER_ADMIN') throw new AppError(403, 'Cannot ban a super admin');

    const user = await prisma.user.update({
      where: { id: req.params.id },
      data: {
        isBanned: true,
        banReason: req.body.reason,
        bannedAt: new Date(),
        bannedBy: req.userId,
      },
      select: { id: true, fullName: true, isBanned: true, banReason: true },
    });

    await prisma.moderationLog.create({
      data: {
        moderatorId: req.userId!,
        targetUserId: req.params.id,
        action: 'BAN',
        reason: req.body.reason,
      },
    });

    await prisma.notification.create({
      data: {
        userId: req.params.id,
        type: 'ACCOUNT_BANNED',
        title: 'Account Suspended',
        body: `Your account has been suspended. Reason: ${req.body.reason}`,
      },
    });

    res.json(user);
  } catch (error) {
    next(error);
  }
});

// POST /api/admin/users/:id/unban - Unban user
router.post('/:id/unban', requireAdmin, async (req, res, next) => {
  try {
    const user = await prisma.user.update({
      where: { id: req.params.id },
      data: {
        isBanned: false,
        banReason: null,
        bannedAt: null,
        bannedBy: null,
      },
      select: { id: true, fullName: true, isBanned: true },
    });

    await prisma.moderationLog.create({
      data: {
        moderatorId: req.userId!,
        targetUserId: req.params.id,
        action: 'UNBAN',
        reason: 'Account unbanned',
      },
    });

    await prisma.notification.create({
      data: {
        userId: req.params.id,
        type: 'ACCOUNT_UNBANNED',
        title: 'Account Restored',
        body: 'Your account has been restored. You can now use the platform again.',
      },
    });

    res.json(user);
  } catch (error) {
    next(error);
  }
});

export default router;
