const express = require('express');
const router = express.Router();
const { PrismaClient } = require('@prisma/client');
const { authMiddleware, adminOnly, generateNIM } = require('../middleware/auth');
const { handleUpload } = require('../middleware/upload');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const fs = require('fs');
const path = require('path');

const prisma = new PrismaClient();

router.get('/dashboard/stats', authMiddleware, adminOnly, async (req, res) => {
  try {
    const totalStudents = await prisma.user.count({ where: { role: 'student' } });
    const statusCounts = await prisma.profile.groupBy({
      by: ['statusPendaftaran'],
      _count: { statusPendaftaran: true },
    });
    const docCounts = await prisma.document.aggregate({
      _sum: { isVerified: true },
      _count: { id: true },
    });
    const verifiedDocs = await prisma.document.count({ where: { isVerified: true } });
    const unverifiedDocs = await prisma.document.count({ where: { isVerified: false } });

    const statusMap = {};
    statusCounts.forEach(s => { statusMap[s.statusPendaftaran] = s._count.statusPendaftaran; });

    const activities = await prisma.activity.findMany({
      orderBy: { createdAt: 'desc' },
      take: 8,
      include: { user: { select: { fullName: true, email: true } } },
    });

    res.json({
      success: true,
      totalStudents,
      status: statusMap,
      documents: { verified: verifiedDocs, unverified: unverifiedDocs, total: docCounts._count.id },
      activities: activities.map(a => ({
        description: a.description,
        status: a.status,
        createdAt: a.createdAt,
        user: a.user ? `${a.user.fullName || a.user.email}` : 'Admin',
      })),
    });
  } catch (error) {
    console.error('Admin stats error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.get('/students', authMiddleware, adminOnly, async (req, res) => {
  try {
    const { search, status, jurusan, page = 1, limit = 10 } = req.query;
    const skip = (parseInt(page) - 1) * parseInt(limit);

    const where = { role: 'student' };
    if (search) {
      where.OR = [
        { email: { contains: search, mode: 'insensitive' } },
        { nim: { contains: search, mode: 'insensitive' } },
        { profile: { fullName: { contains: search, mode: 'insensitive' } } },
      ];
    }
    if (status) where.profile = { ...where.profile, statusPendaftaran: status };
    if (jurusan) where.profile = { ...where.profile, jurusan };

    const [students, total] = await Promise.all([
      prisma.user.findMany({
        where,
        include: {
          profile: true,
          documents: true,
          registrationStatus: true,
        },
        skip,
        take: parseInt(limit),
        orderBy: { createdAt: 'desc' },
      }),
      prisma.user.count({ where }),
    ]);

    const result = students.map(user => {
      const docsTotal = user.documents.length;
      const docsVerified = user.documents.filter(d => d.isVerified).length;
      return {
        id: user.id,
        email: user.email,
        nim: user.nim,
        fullName: user.profile?.fullName,
        jurusan: user.profile?.jurusan,
        asalSekolah: user.profile?.asalSekolah,
        statusPendaftaran: user.profile?.statusPendaftaran,
        registeredAt: user.createdAt,
        docsTotal,
        docsVerified,
      };
    });

    res.json({
      success: true,
      students: result,
      total,
      page: parseInt(page),
      pages: Math.ceil(total / parseInt(limit)),
    });
  } catch (error) {
    console.error('Get students error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.put('/students/:id/status', authMiddleware, adminOnly, async (req, res) => {
  try {
    const { id } = req.params;
    const { status, adminComment } = req.body;

    const validStatuses = ['approved', 'rejected'];
    if (!validStatuses.includes(status)) {
      return res.status(400).json({ success: false, message: 'Status tidak valid.' });
    }

    const student = await prisma.user.findUnique({
      where: { id: parseInt(id) },
      include: { profile: true, documents: true },
    });

    if (!student || student.role !== 'student') {
      return res.status(404).json({ success: false, message: 'Pendaftar tidak ditemukan.' });
    }

    if (status === 'approved') {
      const unverifiedDocs = student.documents.filter(d => !d.isVerified);
      if (unverifiedDocs.length > 0) {
        return res.status(400).json({ success: false, message: 'Masih ada dokumen yang belum diverifikasi.' });
      }
    }

    let nim = student.nim;
    if (status === 'approved' && !nim) {
      nim = generateNIM();
    }

    await prisma.$transaction([
      prisma.profile.update({
        where: { userId: parseInt(id) },
        data: { statusPendaftaran: status === 'approved' ? 'accepted' : 'rejected' },
      }),
      prisma.registrationStatus.upsert({
        where: { userId: parseInt(id) },
        update: {
          status,
          adminComment: adminComment || null,
          updatedBy: req.user.id,
        },
        create: {
          userId: parseInt(id),
          status,
          adminComment: adminComment || null,
          updatedBy: req.user.id,
        },
      }),
      prisma.user.update({
        where: { id: parseInt(id) },
        data: { nim: nim || null },
      }),
      prisma.activity.create({
        data: {
          userId: parseInt(id),
          description: `${status === 'approved' ? 'Pendaftaran disetujui' : 'Pendaftaran ditolak'}: ${student.profile?.fullName || student.email}`,
          status: status === 'approved' ? 'success' : 'error',
        },
      }),
    ]);

    res.json({
      success: true,
      message: status === 'approved' ? 'Pendaftar disetujui & NIM dibuat' : 'Pendaftaran ditolak',
      nim: nim || undefined,
    });
  } catch (error) {
    console.error('Update student status error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.get('/documents', authMiddleware, adminOnly, async (req, res) => {
  try {
    const { filter = 'all' } = req.query;

    const students = await prisma.user.findMany({
      where: { role: 'student' },
      include: {
        profile: { select: { fullName: true, jurusan: true, statusPendaftaran: true } },
        documents: {
          orderBy: { createdAt: 'asc' },
        },
      },
      orderBy: { createdAt: 'desc' },
    });

    let result = students;

    if (filter === 'waiting') {
      result = students.filter(s => s.documents.some(d => !d.isVerified && !d.adminNote));
    } else if (filter === 'verified') {
      result = students.filter(s => s.documents.length > 0 && s.documents.every(d => d.isVerified));
    }

    const formatted = result.map(s => ({
      student_id: s.id,
      full_name: s.profile?.fullName,
      email: s.email,
      jurusan: s.profile?.jurusan,
      status_pendaftaran: s.profile?.statusPendaftaran,
      documents: s.documents.map(d => ({
        id: d.id,
        document_type: d.documentType,
        file_path: d.filePath,
        original_name: d.originalName,
        is_verified: d.isVerified,
        admin_note: d.adminNote,
        verified_at: d.verifiedAt,
        created_at: d.createdAt,
      })),
    }));

    res.json({ success: true, students: formatted });
  } catch (error) {
    console.error('Get documents error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.get('/documents/:id/file', authMiddleware, adminOnly, async (req, res) => {
  try {
    const document = await prisma.document.findUnique({
      where: { id: parseInt(req.params.id) },
      include: { user: { select: { id: true, role: true } } },
    });

    if (!document || document.user.role !== 'student') {
      return res.status(404).json({ success: false, message: 'Dokumen tidak ditemukan.' });
    }

    const filePath = path.join(process.env.UPLOAD_DIR || './uploads', document.filePath);
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({ success: false, message: 'File tidak ditemukan.' });
    }

    res.sendFile(path.resolve(filePath));
  } catch (error) {
    console.error('Serve file error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.put('/documents/:id/verify', authMiddleware, adminOnly, async (req, res) => {
  try {
    const { id } = req.params;
    const { is_verified, admin_note } = req.body;

    const document = await prisma.document.findUnique({
      where: { id: parseInt(id) },
      include: { user: true },
    });

    if (!document || document.user.role !== 'student') {
      return res.status(404).json({ success: false, message: 'Dokumen tidak ditemukan.' });
    }

    const updated = await prisma.document.update({
      where: { id: parseInt(id) },
      data: {
        isVerified: is_verified,
        adminNote: admin_note || null,
        verifiedBy: req.user.id,
        verifiedAt: new Date(),
      },
    });

    res.json({ success: true, message: is_verified ? 'Dokumen disetujui.' : 'Dokumen ditolak.', document: updated });
  } catch (error) {
    console.error('Verify document error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.get('/announcements', authMiddleware, adminOnly, async (req, res) => {
  try {
    const announcements = await prisma.announcement.findMany({
      orderBy: [{ pinned: 'desc' }, { date: 'desc' }],
    });
    res.json({ success: true, announcements });
  } catch (error) {
    console.error('Get announcements error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.post('/announcements', authMiddleware, adminOnly, async (req, res) => {
  try {
    const { title, body, author, pinned, published } = req.body;
    const announcement = await prisma.announcement.create({
      data: { title, body, author: author || req.user.email, pinned: pinned || false, published: published !== false },
    });
    res.status(201).json({ success: true, message: 'Pengumuman berhasil dibuat.', announcement });
  } catch (error) {
    console.error('Create announcement error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.put('/announcements/:id', authMiddleware, adminOnly, async (req, res) => {
  try {
    const { id } = req.params;
    const { title, body, pinned, published } = req.body;

    const announcement = await prisma.announcement.update({
      where: { id: parseInt(id) },
      data: { title, body, pinned, published },
    });

    res.json({ success: true, message: 'Pengumuman berhasil diperbarui.', announcement });
  } catch (error) {
    console.error('Update announcement error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.delete('/announcements/:id', authMiddleware, adminOnly, async (req, res) => {
  try {
    await prisma.announcement.delete({ where: { id: parseInt(req.params.id) } });
    res.json({ success: true, message: 'Pengumuman berhasil dihapus.' });
  } catch (error) {
    console.error('Delete announcement error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.get('/reports/students', authMiddleware, adminOnly, async (req, res) => {
  try {
    const students = await prisma.user.findMany({
      where: { role: 'student' },
      include: { profile: true, documents: true },
      orderBy: { createdAt: 'desc' },
    });

    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Content-Disposition', 'attachment; filename=students-report.json');
    res.json({ success: true, data: students, exportedAt: new Date().toISOString() });
  } catch (error) {
    console.error('Export students error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.get('/settings', authMiddleware, adminOnly, async (req, res) => {
  try {
    const settings = await prisma.siteSetting.findMany();
    const settingsMap = {};
    settings.forEach(s => { settingsMap[s.key] = s.value; });

    res.json({ success: true, settings: settingsMap });
  } catch (error) {
    console.error('Get settings error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

router.put('/settings', authMiddleware, adminOnly, async (req, res) => {
  try {
    const { settings } = req.body;

    for (const [key, value] of Object.entries(settings)) {
      await prisma.siteSetting.upsert({
        where: { key },
        update: { value: String(value) },
        create: { key, value: String(value) },
      });
    }

    res.json({ success: true, message: 'Pengaturan berhasil disimpan.' });
  } catch (error) {
    console.error('Update settings error:', error);
    res.status(500).json({ success: false, message: 'Terjadi kesalahan server.' });
  }
});

module.exports = router;
