// controllers/authController.js
import bcrypt              from 'bcryptjs';
import jwt                 from 'jsonwebtoken';
import crypto              from 'crypto';
import db                  from '../config/database.js';
import { v4 as uuidv4 }   from 'uuid';
import { sendResetEmail, sendWelcomeEmail } from '../utils/emailService.js';

// ─────────────────────────────────────────────────────────────
// Config — hardcoded (no .env)
// ─────────────────────────────────────────────────────────────
const JWT_SECRET = process.env.JWT_SECRET;
const FRONTEND_URL = "https://hireloomglobal.com";

// ─────────────────────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────────────────────
const generateToken = () => crypto.randomBytes(32).toString('hex');
const tokenExpiry   = (minutes = 60) => {
  const d = new Date();
  d.setMinutes(d.getMinutes() + minutes);
  return d;
};

// ─────────────────────────────────────────────────────────────
// register
// ─────────────────────────────────────────────────────────────
export const register = async (req, res) => {
  try {
    const { full_name, email, contact_number, designation, password, role } = req.body;

    const [existingUser] = await db.query('SELECT * FROM profiles WHERE email = ?', [email]);
    if (existingUser.length > 0) {
      return res.status(400).json({ error: 'User already exists' });
    }

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

    await db.query(
      'INSERT INTO profiles (id, role, full_name, contact_number, email, password, designation) VALUES (?, ?, ?, ?, ?, ?, ?)',
      [userId, role || 'salesman', full_name, contact_number, email, hashedPassword, designation]
    );

    const [newUser] = await db.query(
      'SELECT id, role, full_name, contact_number, email, designation, photo_url, created_at FROM profiles WHERE id = ?',
      [userId]
    );

    // Send welcome + credentials email in background (non-blocking)
    sendWelcomeEmail({
      toEmail    : email,
      name       : full_name,
      password,
      designation: designation || '',
    }).catch(err => console.error('Welcome email failed (non-blocking):', err.message));

    res.status(201).json({ message: 'User created successfully', user: newUser[0] });
  } catch (error) {
    console.error('Register error:', error);
    res.status(500).json({ error: 'Server error' });
  }
};

// ─────────────────────────────────────────────────────────────
// login
// ─────────────────────────────────────────────────────────────
export const login = async (req, res) => {
  try {
    const { email, password } = req.body;

    const [users] = await db.query('SELECT * FROM profiles WHERE email = ?', [email]);
    if (users.length === 0) {
      return res.status(400).json({ error: 'Invalid credentials' });
    }

    const user = users[0];
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) {
      return res.status(400).json({ error: 'Invalid credentials' });
    }

    const token = jwt.sign(
      { id: user.id, email: user.email, role: user.role },
      JWT_SECRET,
      { expiresIn: '7d' }
    );

    const { password: _, ...userWithoutPassword } = user;
    res.json({ token, user: userWithoutPassword });
  } catch (error) {
    console.error('Login error:', error);
    res.status(500).json({ error: 'Server error' });
  }
};

// ─────────────────────────────────────────────────────────────
// getProfile
// ─────────────────────────────────────────────────────────────
export const getProfile = async (req, res) => {
  try {
    const [users] = await db.query(
      'SELECT id, role, full_name, contact_number, email, designation, photo_url, created_at FROM profiles WHERE id = ?',
      [req.user.id]
    );
    if (users.length === 0) {
      return res.status(404).json({ error: 'User not found' });
    }
    res.json(users[0]);
  } catch (error) {
    console.error('Get profile error:', error);
    res.status(500).json({ error: 'Server error' });
  }
};

// ─────────────────────────────────────────────────────────────
// getAllUsers
// ─────────────────────────────────────────────────────────────
export const getAllUsers = async (req, res) => {
  try {
    const { role } = req.query;
    let query = 'SELECT id, role, full_name, contact_number, email, designation, photo_url, created_at FROM profiles';
    const params = [];
    if (role) { query += ' WHERE role = ?'; params.push(role); }
    query += ' ORDER BY created_at DESC';
    const [users] = await db.query(query, params);
    res.json({ users });
  } catch (error) {
    console.error('Get all users error:', error);
    res.status(500).json({ error: 'Server error' });
  }
};

// ─────────────────────────────────────────────────────────────
// forgotPassword
// POST /auth/forgot-password   body: { email }
// ─────────────────────────────────────────────────────────────
export const forgotPassword = async (req, res) => {
  try {
    const { email } = req.body;

    if (!email) {
      return res.status(400).json({ error: 'Email is required' });
    }

    const [users] = await db.query(
      'SELECT id, full_name, email FROM profiles WHERE email = ?',
      [email]
    );

    // Same response whether user exists or not (prevents email enumeration)
    if (users.length === 0) {
      return res.json({ message: 'If this email is registered, a reset link has been sent.' });
    }

    const user       = users[0];
    const resetToken = generateToken();
    const expiry     = tokenExpiry(60);

    await db.query(
      'UPDATE profiles SET reset_token = ?, reset_token_expires = ? WHERE id = ?',
      [resetToken, expiry, user.id]
    );

    const resetURL = `${FRONTEND_URL}/reset-password?token=${resetToken}`;

    await sendResetEmail({
      toEmail      : user.email,
      name         : user.full_name,
      resetURL,
      expiryMinutes: 60,
    });

    res.json({ message: 'Password reset link has been sent to your email.' });

  } catch (error) {
    console.error('Forgot password error:', error);
    res.status(500).json({ error: 'Failed to send reset email. Please try again.' });
  }
};

// ─────────────────────────────────────────────────────────────
// resetPassword
// POST /auth/reset-password   body: { token, newPassword }
// ─────────────────────────────────────────────────────────────
export const resetPassword = async (req, res) => {
  try {
    const { token, newPassword } = req.body;

    if (!token || !newPassword) {
      return res.status(400).json({ error: 'Token and new password are required' });
    }

    if (newPassword.length < 6) {
      return res.status(400).json({ error: 'Password must be at least 6 characters' });
    }

    const [users] = await db.query(
      'SELECT id, email FROM profiles WHERE reset_token = ? AND reset_token_expires > NOW()',
      [token]
    );

    if (users.length === 0) {
      return res.status(400).json({ error: 'Reset link is invalid or has expired. Please request a new one.' });
    }

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

    await db.query(
      'UPDATE profiles SET password = ?, reset_token = NULL, reset_token_expires = NULL WHERE id = ?',
      [hashedPassword, users[0].id]
    );

    res.json({ message: 'Password has been reset successfully. You can now sign in.' });

  } catch (error) {
    console.error('Reset password error:', error);
    res.status(500).json({ error: 'Server error' });
  }
};

// ─────────────────────────────────────────────────────────────
// changePassword
// POST /auth/change-password   body: { currentPassword, newPassword }
// ─────────────────────────────────────────────────────────────
export const changePassword = async (req, res) => {
  try {
    const { currentPassword, newPassword } = req.body;

    if (!currentPassword || !newPassword) {
      return res.status(400).json({ error: 'Current password and new password are required' });
    }

    if (newPassword.length < 6) {
      return res.status(400).json({ error: 'New password must be at least 6 characters' });
    }

    if (currentPassword === newPassword) {
      return res.status(400).json({ error: 'New password must be different from the current password' });
    }

    const [users] = await db.query(
      'SELECT id, password FROM profiles WHERE id = ?',
      [req.user.id]
    );
    if (users.length === 0) {
      return res.status(404).json({ error: 'User not found' });
    }

    const isMatch = await bcrypt.compare(currentPassword, users[0].password);
    if (!isMatch) {
      return res.status(400).json({ error: 'Current password is incorrect' });
    }

    const hashedPassword = await bcrypt.hash(newPassword, 10);
    await db.query('UPDATE profiles SET password = ? WHERE id = ?', [hashedPassword, req.user.id]);

    res.json({ message: 'Password updated successfully' });

  } catch (error) {
    console.error('Change password error:', error);
    res.status(500).json({ error: 'Server error' });
  }
};