import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import pool from '../config/db.js';
import dotenv from 'dotenv';

dotenv.config();

const JWT_SECRET = process.env.JWT_SECRET || 'khujousa_secret_key_2026';

let userColsChecked = false;
export async function ensureAuthUserColumns() {
  if (userColsChecked) return;
  try {
    const [cols] = await pool.query('SHOW COLUMNS FROM users');
    const set = new Set(cols.map(c => c.Field));
    if (!set.has('avatar_url')) {
      await pool.query('ALTER TABLE users ADD COLUMN avatar_url VARCHAR(255) NULL').catch(() => {});
    }
    if (!set.has('is_verified')) {
      await pool.query('ALTER TABLE users ADD COLUMN is_verified TINYINT(1) DEFAULT 0').catch(() => {});
    }
    userColsChecked = true;
  } catch (e) {}
}

// 1. Create Account / Register User
export async function register(req, res) {
  await ensureAuthUserColumns();
  const { first_name, last_name, phone, email, business_name, password, role } = req.body;

  if (!first_name || !last_name || !email || !password) {
    return res.status(400).json({ error: "Missing required registration parameters." });
  }

  try {
    const [existing] = await pool.query('SELECT id FROM users WHERE email = ?', [email]);
    if (existing.length > 0) {
      return res.status(409).json({ error: "An account is already registered with this email address." });
    }

    const targetRole = role || 'user';
    const [roleRow] = await pool.query('SELECT id FROM roles WHERE name = ?', [targetRole]);
    if (roleRow.length === 0) {
      return res.status(400).json({ error: `Invalid role parameter: ${targetRole}` });
    }
    const roleId = roleRow[0].id;

    const salt = await bcrypt.genSalt(10);
    const passwordHash = await bcrypt.hash(password, salt);

    const insertQuery = `
      INSERT INTO users (first_name, last_name, phone, email, business_name, password_hash, role_id)
      VALUES (?, ?, ?, ?, ?, ?, ?)
    `;
    await pool.query(insertQuery, [first_name, last_name, phone, email, business_name, passwordHash, roleId]);

    return res.status(201).json({ message: "User account created successfully." });
  } catch (err) {
    console.error("Registration controller error:", err);
    return res.status(500).json({ error: "Internal server error registering new user account." });
  }
}

// 2. Authentication / Login User
export async function login(req, res) {
  await ensureAuthUserColumns();
  const { email, password } = req.body;

  if (!email || !password) {
    return res.status(400).json({ error: "Missing email or password credentials." });
  }

  try {
    const query = `
      SELECT u.*, r.name as role_name 
      FROM users u
      LEFT JOIN roles r ON u.role_id = r.id
      WHERE u.email = ?
    `;
    const [rows] = await pool.query(query, [email]);
    if (rows.length === 0) {
      return res.status(401).json({ error: "Invalid credentials. Email not found." });
    }

    const user = rows[0];

    const isMatch = await bcrypt.compare(password, user.password_hash);
    if (!isMatch) {
      return res.status(401).json({ error: "Invalid credentials. Password incorrect." });
    }

    if (user.status === 'Suspended') {
      const reasonText = user.suspension_reason ? ` Reason: ${user.suspension_reason}` : '';
      return res.status(403).json({
        error: `Your account has been suspended. Please contact platform administration.${reasonText}`
      });
    }

    // Update last_login_at
    await pool.query('UPDATE users SET last_login_at = NOW() WHERE id = ?', [user.id]).catch(() => {});

    const payload = {
      id: user.id,
      email: user.email,
      role: user.role_name
    };

    const token = jwt.sign(payload, JWT_SECRET, { expiresIn: '8h' });

    return res.json({
      token,
      user: {
        id: user.id,
        first_name: user.first_name,
        last_name: user.last_name,
        email: user.email,
        phone: user.phone,
        business_name: user.business_name,
        role: user.role_name,
        status: user.status || 'Active',
        avatar_url: user.avatar_url || null,
        is_verified: user.is_verified === 1 || user.is_verified === true
      }
    });
  } catch (err) {
    console.error("Login controller error:", err);
    return res.status(500).json({ error: "Internal server error authenticating user credentials." });
  }
}

// 3. Verify Active Session (getMe)
export async function getMe(req, res) {
  try {
    await ensureAuthUserColumns();
    const userId = req.user.id;
    const query = `
      SELECT u.id, u.first_name, u.last_name, u.email, u.phone, u.business_name, u.status, u.suspension_reason, u.last_login_at, u.avatar_url, u.is_verified, r.name as role 
      FROM users u
      LEFT JOIN roles r ON u.role_id = r.id
      WHERE u.id = ?
    `;
    const [rows] = await pool.query(query, [userId]);
    if (rows.length === 0) {
      return res.status(404).json({ error: "User account not found." });
    }

    const user = rows[0];
    if (user.status === 'Suspended') {
      const reasonText = user.suspension_reason ? ` Reason: ${user.suspension_reason}` : '';
      return res.status(403).json({
        error: `Your account has been suspended. Please contact platform administration.${reasonText}`
      });
    }

    return res.json({
      user: {
        ...user,
        is_verified: user.is_verified === 1 || user.is_verified === true
      }
    });
  } catch (err) {
    console.error("getMe error:", err);
    return res.status(500).json({ error: "Internal server error fetching user profile session." });
  }
}

// 4. Change Password (authenticated)
export async function changePassword(req, res) {
  const { currentPassword, newPassword } = req.body;
  const userId = req.user.id;

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

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

  try {
    const [rows] = await pool.query('SELECT password_hash FROM users WHERE id = ?', [userId]);
    if (rows.length === 0) {
      return res.status(404).json({ error: "User not found." });
    }

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

    const salt = await bcrypt.genSalt(10);
    const newHash = await bcrypt.hash(newPassword, salt);

    await pool.query('UPDATE users SET password_hash = ? WHERE id = ?', [newHash, userId]);

    return res.json({ message: "Password changed successfully." });
  } catch (err) {
    console.error("changePassword error:", err);
    return res.status(500).json({ error: "Internal server error changing password." });
  }
}

// 5. Update Profile (authenticated)
export async function updateProfile(req, res) {
  const { first_name, last_name, phone, email } = req.body;
  const userId = req.user.id;

  if (!first_name || !last_name || !email) {
    return res.status(400).json({ error: "Name and email are required." });
  }

  try {
    // Check if email is taken by another user
    const [existing] = await pool.query('SELECT id FROM users WHERE email = ? AND id != ?', [email, userId]);
    if (existing.length > 0) {
      return res.status(409).json({ error: "This email is already in use by another account." });
    }

    await pool.query(
      'UPDATE users SET first_name = ?, last_name = ?, phone = ?, email = ? WHERE id = ?',
      [first_name, last_name, phone || '', email, userId]
    );

    return res.json({ message: "Profile updated successfully." });
  } catch (err) {
    console.error("updateProfile error:", err);
    return res.status(500).json({ error: "Internal server error updating profile." });
  }
}
