// Auto-generated by create-backlist on <%= new Date().toISOString() %>
import { Request, Response } from 'express';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';

<% if (dbType === 'mongoose') { -%>
import User from '../models/User.model';
<% } else if (dbType === 'prisma') { -%>
import { prisma } from '../server';
<% } -%>

function signJwt(payload: any) {
  const secret = process.env.JWT_SECRET;
  if (!secret) {
    throw new Error('JWT_SECRET is not set');
  }
  const expiresIn = process.env.JWT_EXPIRES_IN || '5h';
  return jwt.sign(payload, secret, { expiresIn });
}

// @desc    Register a new user
export const registerUser = async (req: Request, res: Response) => {
  const { name, email, password } = req.body as { name: string; email: string; password: string };

  if (!name || !email || !password) {
    return res.status(400).json({ message: 'name, email, password are required' });
  }

  try {
    <% if (dbType === 'mongoose') { -%>
    const existing = await User.findOne({ email });
    if (existing) {
      return res.status(409).json({ message: 'User already exists' });
    }

    const hashedPassword = await bcrypt.hash(password, 10);

    const user = await User.create({ name, email, password: hashedPassword });

    const payload = { user: { id: user._id.toString() } };
    const token = signJwt(payload);

    return res.status(201).json({
      token,
      user: { id: user._id.toString(), name: user.name, email: user.email }
    });
    <% } else if (dbType === 'prisma') { -%>
    const existingUser = await prisma.user.findUnique({ where: { email } });
    if (existingUser) {
      return res.status(409).json({ message: 'User already exists' });
    }

    const hashedPassword = await bcrypt.hash(password, 10);

    const user = await prisma.user.create({
      data: { name, email, password: hashedPassword },
      select: { id: true, name: true, email: true } // never return password
    });

    const payload = { user: { id: user.id } };
    const token = signJwt(payload);

    return res.status(201).json({ token, user });
    <% } -%>
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: 'Server Error' });
  }
};

// @desc    Authenticate user & get token (Login)
export const loginUser = async (req: Request, res: Response) => {
  const { email, password } = req.body as { email: string; password: string };

  if (!email || !password) {
    return res.status(400).json({ message: 'email and password are required' });
  }

  try {
    <% if (dbType === 'mongoose') { -%>
    const user = await User.findOne({ email });
    <% } else if (dbType === 'prisma') { -%>
    // Need password for compare
    const user = await prisma.user.findUnique({ where: { email } });
    <% } -%>

    if (!user) {
      return res.status(401).json({ message: 'Invalid Credentials' });
    }

    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) {
      return res.status(401).json({ message: 'Invalid Credentials' });
    }

    <% if (dbType === 'mongoose') { -%>
    const userId = user._id.toString();
    const safeUser = { id: userId, name: user.name, email: user.email };
    <% } else if (dbType === 'prisma') { -%>
    const userId = user.id;
    const safeUser = { id: user.id, name: user.name, email: user.email };
    <% } -%>

    const payload = { user: { id: userId } };
    const token = signJwt(payload);

    return res.json({ token, user: safeUser });
  } catch (error) {
    console.error(error);
    return res.status(500).json({ message: 'Server Error' });
  }
};