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

const upload = multer({
  storage: multer.memoryStorage(),
  limits: { fileSize: 64 * 1024 * 1024 }, // 64 MB
});

const FILE_WHITELIST = new Set([
  'image/jpeg', 'image/png', 'image/webp',
  'application/octet-stream',
  'application/pdf',
  'model/stl', 'application/sla',
  'video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/webm',
]);

// ── 공개 라우트 ─────────────────────────────────────────────────────────────

// GET /api/projects — 승인된 프로젝트 목록
router.get('/', async (req, res) => {
  try {
    const page  = Math.max(1, parseInt(req.query.page) || 1);
    const limit = Math.min(50, parseInt(req.query.limit) || 20);
    const skip  = (page - 1) * limit;

    const where = { status: 'approved' };
    if (req.query.difficulty) where.difficultyLevel = parseInt(req.query.difficulty);

    const [projects, total] = await Promise.all([
      prisma.project.findMany({
        where,
        skip,
        take: limit,
        orderBy: { createdAt: 'desc' },
        include: {
          user: { select: { id: true, nickname: true } },
          files: { where: { fileType: 'image' }, take: 1, orderBy: { displayOrder: 'asc' } },
          product: { select: { id: true, price: true, isOnSale: true, totalSales: true } },
        },
      }),
      prisma.project.count({ where }),
    ]);

    res.json({ projects, total, page, pages: Math.ceil(total / limit) });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: '서버 오류' });
  }
});

// GET /api/projects/:id — 프로젝트 상세
router.get('/:id', async (req, res) => {
  try {
    const project = await prisma.project.findUnique({
      where: { id: req.params.id },
      include: {
        user: { select: { id: true, nickname: true } },
        files: { orderBy: { displayOrder: 'asc' } },
        product: {
          select: {
            id: true, price: true, isOnSale: true, totalSales: true,
            reviews: {
              where: { isVisible: true },
              select: { rating: true },
            },
          },
        },
      },
    });
    if (!project) return res.status(404).json({ error: '프로젝트를 찾을 수 없습니다' });
    if (project.status !== 'approved') return res.status(403).json({ error: '비공개 프로젝트입니다' });
    res.json(project);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// ── 인증 필요 라우트 ────────────────────────────────────────────────────────

// GET /api/projects/my — 내 프로젝트 목록
router.get('/my/list', requireAuth, async (req, res) => {
  try {
    const projects = await prisma.project.findMany({
      where: { userId: req.user.id },
      orderBy: { createdAt: 'desc' },
      include: {
        files: { where: { fileType: 'image' }, take: 1 },
        product: { select: { id: true, price: true, totalSales: true } },
      },
    });
    res.json(projects);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// POST /api/projects — 새 프로젝트 생성
router.post('/', requireAuth, [
  body('title').trim().isLength({ min: 2, max: 100 }),
  body('description').trim().isLength({ min: 10 }),
  body('difficultyLevel').optional().isInt({ min: 1, max: 5 }),
], async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) return res.status(400).json({ error: errors.array()[0].msg });

  const { title, description, difficultyLevel, requiredParts } = req.body;
  try {
    const project = await prisma.project.create({
      data: {
        userId: req.user.id,
        title,
        description,
        difficultyLevel: difficultyLevel ? parseInt(difficultyLevel) : 3,
        requiredParts:   requiredParts || [],
      },
    });
    await writeAuditLog({ userId: req.user.id, action: 'PROJECT_CREATE', targetType: 'Project', targetId: project.id, req, responseStatus: 201 });
    res.status(201).json(project);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// PUT /api/projects/:id — 프로젝트 수정 (draft 상태만)
router.put('/:id', requireAuth, async (req, res) => {
  try {
    const project = await prisma.project.findUnique({ where: { id: req.params.id } });
    if (!project) return res.status(404).json({ error: '프로젝트를 찾을 수 없습니다' });
    if (project.userId !== req.user.id && req.user.role !== 'admin') {
      return res.status(403).json({ error: '권한이 없습니다' });
    }
    if (!['draft', 'rejected'].includes(project.status)) {
      return res.status(400).json({ error: '승인 대기/완료 상태에서는 수정할 수 없습니다' });
    }

    const { title, description, difficultyLevel, requiredParts } = req.body;
    const updated = await prisma.project.update({
      where: { id: req.params.id },
      data: {
        ...(title && { title }),
        ...(description && { description }),
        ...(difficultyLevel && { difficultyLevel: parseInt(difficultyLevel) }),
        ...(requiredParts !== undefined && { requiredParts }),
      },
    });
    res.json(updated);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// DELETE /api/projects/:id
router.delete('/:id', requireAuth, async (req, res) => {
  try {
    const project = await prisma.project.findUnique({
      where: { id: req.params.id },
      include: { files: true },
    });
    if (!project) return res.status(404).json({ error: '프로젝트를 찾을 수 없습니다' });
    if (project.userId !== req.user.id && req.user.role !== 'admin') {
      return res.status(403).json({ error: '권한이 없습니다' });
    }

    // MinIO 파일 삭제
    await Promise.all(project.files.map(f => deleteObject(f.url)));
    await prisma.project.delete({ where: { id: req.params.id } });
    await writeAuditLog({ userId: req.user.id, action: 'PROJECT_DELETE', targetType: 'Project', targetId: req.params.id, req, responseStatus: 200 });
    res.json({ success: true });
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// POST /api/projects/:id/submit — 검토 요청
router.post('/:id/submit', requireAuth, async (req, res) => {
  try {
    const project = await prisma.project.findUnique({ where: { id: req.params.id } });
    if (!project) return res.status(404).json({ error: '프로젝트를 찾을 수 없습니다' });
    if (project.userId !== req.user.id) return res.status(403).json({ error: '권한이 없습니다' });
    if (!['draft', 'rejected'].includes(project.status)) {
      return res.status(400).json({ error: '이미 검토 요청 중이거나 승인된 프로젝트입니다' });
    }

    const updated = await prisma.project.update({
      where: { id: req.params.id },
      data: { status: 'pending', adminNote: null },
    });
    await writeAuditLog({ userId: req.user.id, action: 'PROJECT_SUBMIT', targetType: 'Project', targetId: project.id, req, responseStatus: 200 });
    res.json(updated);
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

// POST /api/projects/:id/files — 파일 업로드
router.post('/:id/files', requireAuth, upload.array('files', 10), async (req, res) => {
  try {
    const project = await prisma.project.findUnique({ where: { id: req.params.id } });
    if (!project) return res.status(404).json({ error: '프로젝트를 찾을 수 없습니다' });
    if (project.userId !== req.user.id) return res.status(403).json({ error: '권한이 없습니다' });
    if (!req.files?.length) return res.status(400).json({ error: '파일이 없습니다' });

    const fileType = req.body.fileType || 'image'; // image|video|stl|wiring|firmware
    const results  = [];

    for (const file of req.files) {
      let stored;
      if (IMAGE_TYPES.has(file.mimetype)) {
        stored = await uploadImage(file.buffer, file.originalname, `projects/${project.id}`);
      } else {
        stored = await uploadRaw(file.buffer, file.originalname, file.mimetype, `projects/${project.id}`);
      }

      const pf = await prisma.projectFile.create({
        data: {
          projectId:    project.id,
          fileType,
          url:          stored.url,
          thumbnailUrl: stored.thumbnailUrl || null,
          fileSize:     stored.fileSize,
          mimeType:     stored.mimeType,
          originalName: file.originalname,
          displayOrder: results.length,
        },
      });
      results.push(pf);
    }

    res.status(201).json(results);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: '파일 업로드 실패: ' + err.message });
  }
});

// DELETE /api/projects/:id/files/:fileId
router.delete('/:id/files/:fileId', requireAuth, async (req, res) => {
  try {
    const file = await prisma.projectFile.findUnique({ where: { id: req.params.fileId } });
    if (!file || file.projectId !== req.params.id) return res.status(404).json({ error: '파일을 찾을 수 없습니다' });

    const project = await prisma.project.findUnique({ where: { id: req.params.id } });
    if (project.userId !== req.user.id && req.user.role !== 'admin') {
      return res.status(403).json({ error: '권한이 없습니다' });
    }

    await deleteObject(file.url);
    if (file.thumbnailUrl) await deleteObject(file.thumbnailUrl);
    await prisma.projectFile.delete({ where: { id: req.params.fileId } });
    res.json({ success: true });
  } catch (err) {
    res.status(500).json({ error: '서버 오류' });
  }
});

module.exports = router;
