const router = require('express').Router();
const { body, validationResult } = require('express-validator');
const prisma = require('../config/db');
const { requireAuth, requireRole } = require('../middleware/auth');
const { writeAuditLog } = require('../middleware/audit');

// 모든 admin 라우트는 admin 역할 필요
router.use(requireAuth, requireRole('admin'));

// GET /api/admin/projects/pending
router.get('/projects/pending', async (_req, res) => {
  try {
    const projects = await prisma.project.findMany({
      where: { status: 'pending' },
      orderBy: { updatedAt: 'asc' },
      include: {
        user: { select: { id: true, email: true, nickname: true } },
        files: { where: { fileType: 'image' }, take: 1 },
        _count: { select: { files: true } },
      },
    });
    res.json(projects);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// GET /api/admin/projects — 전체 목록 (필터)
router.get('/projects', async (req, res) => {
  try {
    const page   = Math.max(1, parseInt(req.query.page) || 1);
    const limit  = Math.min(100, parseInt(req.query.limit) || 30);
    const skip   = (page - 1) * limit;
    const where  = {};
    if (req.query.status) where.status = req.query.status;

    const [projects, total] = await Promise.all([
      prisma.project.findMany({
        where, skip, take: limit,
        orderBy: { updatedAt: 'desc' },
        include: { user: { select: { id: true, email: true, nickname: true } } },
      }),
      prisma.project.count({ where }),
    ]);
    res.json({ projects, total, page, pages: Math.ceil(total / limit) });
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// POST /api/admin/projects/:id/approve
router.post('/projects/:id/approve', [
  body('commissionRate').optional().isFloat({ min: 0, max: 1 }),
  body('price').isInt({ min: 100 }),
], async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) return res.status(400).json({ error: errors.array()[0].msg });

  const { commissionRate = 0.1, price } = req.body;
  try {
    const project = await prisma.project.findUnique({ where: { id: req.params.id } });
    if (!project) return res.status(404).json({ error: '프로젝트를 찾을 수 없습니다' });
    if (project.status !== 'pending') return res.status(400).json({ error: '검토 대기 상태가 아닙니다' });

    // 트랜잭션: 프로젝트 승인 + 상품 자동 생성
    const [updated] = await prisma.$transaction([
      prisma.project.update({
        where: { id: req.params.id },
        data: { status: 'approved', commissionRate: parseFloat(commissionRate), adminNote: null },
      }),
      prisma.product.upsert({
        where: { projectId: req.params.id },
        update: { price: parseInt(price), isOnSale: true },
        create: { projectId: req.params.id, price: parseInt(price) },
      }),
    ]);

    await writeAuditLog({
      userId: req.user.id, action: 'ADMIN_APPROVE',
      targetType: 'Project', targetId: req.params.id,
      req, metadata: { commissionRate, price }, responseStatus: 200,
    });
    res.json(updated);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: '서버 오류' });
  }
});

// POST /api/admin/projects/:id/reject
router.post('/projects/:id/reject', [
  body('adminNote').trim().isLength({ min: 5 }),
], async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) return res.status(400).json({ error: errors.array()[0].msg });

  try {
    const project = await prisma.project.findUnique({ where: { id: req.params.id } });
    if (!project) return res.status(404).json({ error: '프로젝트를 찾을 수 없습니다' });

    const updated = await prisma.project.update({
      where: { id: req.params.id },
      data: { status: 'rejected', adminNote: req.body.adminNote },
    });

    await writeAuditLog({
      userId: req.user.id, action: 'ADMIN_REJECT',
      targetType: 'Project', targetId: req.params.id,
      req, responseStatus: 200,
    });
    res.json(updated);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// GET /api/admin/users
router.get('/users', async (req, res) => {
  try {
    const page  = Math.max(1, parseInt(req.query.page) || 1);
    const limit = Math.min(100, parseInt(req.query.limit) || 30);
    const skip  = (page - 1) * limit;
    const where = {};
    if (req.query.role) where.role = req.query.role;
    if (req.query.q) {
      where.OR = [
        { email: { contains: req.query.q, mode: 'insensitive' } },
        { nickname: { contains: req.query.q, mode: 'insensitive' } },
      ];
    }

    const [users, total] = await Promise.all([
      prisma.user.findMany({
        where, skip, take: limit,
        orderBy: { createdAt: 'desc' },
        select: { id: true, email: true, nickname: true, role: true, isActive: true, createdAt: true, lastLoginAt: true },
      }),
      prisma.user.count({ where }),
    ]);
    res.json({ users, total, page, pages: Math.ceil(total / limit) });
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// PUT /api/admin/users/:id/toggle — 활성/비활성
router.put('/users/:id/toggle', async (req, res) => {
  try {
    const user = await prisma.user.findUnique({ where: { id: req.params.id } });
    if (!user) return res.status(404).json({ error: '사용자를 찾을 수 없습니다' });
    if (user.role === 'admin') return res.status(400).json({ error: '관리자 계정은 비활성화할 수 없습니다' });

    const updated = await prisma.user.update({
      where: { id: req.params.id },
      data: { isActive: !user.isActive },
      select: { id: true, email: true, isActive: true },
    });
    await writeAuditLog({
      userId: req.user.id, action: updated.isActive ? 'ADMIN_USER_ACTIVATE' : 'ADMIN_USER_DEACTIVATE',
      targetType: 'User', targetId: req.params.id, req, responseStatus: 200,
    });
    res.json(updated);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// PUT /api/admin/users/:id/role — 역할 변경
router.put('/users/:id/role', [
  body('role').isIn(['admin', 'seller', 'buyer']),
], async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) return res.status(400).json({ error: errors.array()[0].msg });

  try {
    const updated = await prisma.user.update({
      where: { id: req.params.id },
      data: { role: req.body.role },
      select: { id: true, email: true, role: true },
    });
    await writeAuditLog({
      userId: req.user.id, action: 'ADMIN_ROLE_CHANGE',
      targetType: 'User', targetId: req.params.id,
      req, metadata: { newRole: req.body.role }, responseStatus: 200,
    });
    res.json(updated);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// GET /api/admin/logs
router.get('/logs', async (req, res) => {
  try {
    const page   = Math.max(1, parseInt(req.query.page) || 1);
    const limit  = Math.min(200, parseInt(req.query.limit) || 50);
    const skip   = (page - 1) * limit;
    const where  = {};
    if (req.query.action) where.action = req.query.action;
    if (req.query.userId) where.userId = req.query.userId;
    if (req.query.from || req.query.to) {
      where.createdAt = {};
      if (req.query.from) where.createdAt.gte = new Date(req.query.from);
      if (req.query.to)   where.createdAt.lte = new Date(req.query.to);
    }

    const [logs, total] = await Promise.all([
      prisma.auditLog.findMany({
        where, skip, take: limit,
        orderBy: { createdAt: 'desc' },
        include: { user: { select: { email: true, nickname: true } } },
      }),
      prisma.auditLog.count({ where }),
    ]);
    res.json({ logs, total, page, pages: Math.ceil(total / limit) });
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// GET /api/admin/stats
router.get('/stats', async (_req, res) => {
  try {
    const [
      totalUsers, totalProjects, pendingProjects,
      totalOrders, paidOrders,
    ] = await Promise.all([
      prisma.user.count(),
      prisma.project.count(),
      prisma.project.count({ where: { status: 'pending' } }),
      prisma.order.count(),
      prisma.order.aggregate({ where: { status: 'paid' }, _sum: { amount: true }, _count: true }),
    ]);

    res.json({
      users:    totalUsers,
      projects: { total: totalProjects, pending: pendingProjects },
      revenue:  { total: paidOrders._sum.amount || 0, orders: paidOrders._count },
    });
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

module.exports = router;
