import jwt from 'jsonwebtoken';
import bcrypt from 'bcryptjs';
import { PrismaClient } from '@prisma/client';
import { asyncHandler } from '../utils/helpers';

const prisma = new PrismaClient();

export const authMiddleware = asyncHandler(async (req, res, next) => {
  const token = req.cookies.token || req.headers.authorization?.replace('Bearer ', '');
  if (!token) return res.status(401).json({ success: false, message: 'Akses ditolak. Silakan login.' });

  const decoded = jwt.verify(token, process.env.JWT_SECRET);
  const user = await prisma.user.findUnique({ where: { id: decoded.id }, include: { profile: true } });
  if (!user || !user.isActive) return res.status(401).json({ success: false, message: 'User tidak aktif atau tidak ditemukan.' });

  req.user = user;
  next();
});

export const adminOnly = (req, res, next) => {
  if (!['admin', 'super_admin'].includes(req.user.role)) {
    return res.status(403).json({ success: false, message: 'Akses ditolak. Hanya admin.' });
  }
  next();
};

export const generateTokens = (user) => {
  const accessToken = jwt.sign({ id: user.id, email: user.email, role: user.role }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRES_IN });
  const refreshToken = jwt.sign({ id: user.id }, process.env.REFRESH_TOKEN_SECRET, { expiresIn: process.env.REFRESH_TOKEN_EXPIRES_IN });
  return { accessToken, refreshToken };
};

export const hashPassword = async (password) => bcrypt.hash(password, 12);

export const comparePassword = async (password, hash) => bcrypt.compare(password, hash);

export const generateNIM = async (prisma) => {
  const year = new Date().getFullYear();
  let nim;
  let attempts = 0;
  do {
    const random = Math.floor(100000 + Math.random() * 900000);
    nim = `${year}${random}`;
    attempts++;
    if (attempts > 10) throw new Error('Gagal generate NIM unik');
  } while (await prisma.user.findUnique({ where: { nim } }));
  return nim;
};

export default prisma;
