import pool from '../config/db.js';

// Helper to ensure status, suspension_reason, and last_login_at columns exist
let cachedUserColumns = null;
async function getUserColumns() {
  if (!cachedUserColumns) {
    try {
      const [cols] = await pool.query('SHOW COLUMNS FROM users');
      cachedUserColumns = new Set(cols.map(c => c.Field));
      if (!cachedUserColumns.has('status')) {
        await pool.query("ALTER TABLE users ADD COLUMN status VARCHAR(20) DEFAULT 'Active'").catch(() => {});
        cachedUserColumns.add('status');
      }
      if (!cachedUserColumns.has('suspension_reason')) {
        await pool.query("ALTER TABLE users ADD COLUMN suspension_reason TEXT NULL").catch(() => {});
        cachedUserColumns.add('suspension_reason');
      }
      if (!cachedUserColumns.has('avatar_url')) {
        await pool.query("ALTER TABLE users ADD COLUMN avatar_url VARCHAR(255) NULL").catch(() => {});
        cachedUserColumns.add('avatar_url');
      }
      if (!cachedUserColumns.has('is_verified')) {
        await pool.query("ALTER TABLE users ADD COLUMN is_verified TINYINT(1) DEFAULT 0").catch(() => {});
        cachedUserColumns.add('is_verified');
      }
    } catch (err) {
      cachedUserColumns = new Set();
    }
  }
  return cachedUserColumns;
}

let viewerTablesChecked = false;
async function ensureViewerTables() {
  if (viewerTablesChecked) return;
  try {
    await pool.query(`
      CREATE TABLE IF NOT EXISTS user_saved_listings (
        id INT AUTO_INCREMENT PRIMARY KEY,
        user_id INT NOT NULL,
        listing_id INT NOT NULL,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        UNIQUE KEY uniq_user_saved (user_id, listing_id),
        INDEX idx_usl_user (user_id)
      ) ENGINE=InnoDB;
    `);

    await pool.query(`
      CREATE TABLE IF NOT EXISTS user_view_history (
        id INT AUTO_INCREMENT PRIMARY KEY,
        user_id INT NOT NULL,
        listing_id INT NOT NULL,
        viewed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        UNIQUE KEY uniq_user_viewed (user_id, listing_id),
        INDEX idx_uvh_user (user_id)
      ) ENGINE=InnoDB;
    `);
    viewerTablesChecked = true;
  } catch (e) {
    console.error("ensureViewerTables error:", e.message);
  }
}

// Helper to log audit events into audit_logs table
async function logAuditEvent(adminUserId, eventType, description, severity = 'Info', ipAddress = null) {
  try {
    await pool.query(`
      CREATE TABLE IF NOT EXISTS audit_logs (
        id INT AUTO_INCREMENT PRIMARY KEY,
        admin_user_id INT,
        event_type VARCHAR(100) NOT NULL,
        description TEXT,
        severity VARCHAR(20) DEFAULT 'Info',
        ip_address VARCHAR(45),
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (admin_user_id) REFERENCES users(id) ON DELETE SET NULL
      ) ENGINE=InnoDB
    `).catch(() => {});

    await pool.query(
      'INSERT INTO audit_logs (admin_user_id, event_type, description, severity, ip_address) VALUES (?, ?, ?, ?, ?)',
      [adminUserId || null, eventType, description, severity, ipAddress || null]
    );
  } catch (err) {
    console.error("Audit log error:", err);
  }
}

// 1. Get All Users with Server-Side Search, Role, Status, Timeframe & Pagination
export async function getUsers(req, res) {
  try {
    await getUserColumns();
    const userRole = req.user.role;
    if (userRole !== 'super_admin' && userRole !== 'moderator') {
      return res.status(403).json({ error: "Access denied. Insufficient privileges to inspect user accounts." });
    }

    const { page, limit, search, role, status, timeframe } = req.query;

    const whereClauses = ['1=1'];
    const queryParams = [];

    // Search query matching Name, Email, Phone, Business Name, or ID
    if (search && search.trim()) {
      const term = `%${search.trim()}%`;
      whereClauses.push('(u.first_name LIKE ? OR u.last_name LIKE ? OR CONCAT(u.first_name, " ", u.last_name) LIKE ? OR u.email LIKE ? OR u.phone LIKE ? OR u.business_name LIKE ? OR CAST(u.id AS CHAR) LIKE ?)');
      queryParams.push(term, term, term, term, term, term, term);
    }

    // Role filter
    if (role && role.trim() && role !== 'All Roles' && role !== 'all') {
      let mappedRole = role.trim().toLowerCase().replace(/\s+/g, '_');
      if (mappedRole === 'member') mappedRole = 'user';
      whereClauses.push('r.name = ?');
      queryParams.push(mappedRole);
    }

    // Status filter (Active / Suspended)
    if (status && status.trim() && status !== 'All Statuses' && status !== 'all') {
      whereClauses.push('u.status = ?');
      queryParams.push(status.trim());
    }

    // Timeframe filter
    if (timeframe && timeframe !== 'All Time' && timeframe !== 'all') {
      if (timeframe === 'Last 30 Days' || timeframe === '30days') {
        whereClauses.push('u.created_at >= NOW() - INTERVAL 30 DAY');
      } else if (timeframe === 'Last 7 Days' || timeframe === '7days') {
        whereClauses.push('u.created_at >= NOW() - INTERVAL 7 DAY');
      } else if (timeframe === 'This Year' || timeframe === 'this_year') {
        whereClauses.push('YEAR(u.created_at) = YEAR(NOW())');
      }
    }

    const whereSql = whereClauses.join(' AND ');

    // Total Count
    const countQuery = `
      SELECT COUNT(*) as total 
      FROM users u
      LEFT JOIN roles r ON u.role_id = r.id
      WHERE ${whereSql}
    `;
    const [countResult] = await pool.query(countQuery, queryParams);
    const total = countResult[0]?.total || 0;

    const pageNum = Math.max(1, parseInt(page) || 1);
    const limitNum = Math.max(1, parseInt(limit) || 10);
    const offset = (pageNum - 1) * limitNum;

    const listQuery = `
      SELECT u.id, u.first_name, u.last_name, 
             CONCAT(u.first_name, ' ', u.last_name) as name, 
             u.email, u.phone, u.business_name, 
             u.status, u.suspension_reason, u.last_login_at, u.created_at,
             r.name as role 
      FROM users u
      LEFT JOIN roles r ON u.role_id = r.id
      WHERE ${whereSql}
      ORDER BY u.created_at DESC
      LIMIT ? OFFSET ?
    `;

    const [rows] = await pool.query(listQuery, [...queryParams, limitNum, offset]);

    const formattedUsers = rows.map(u => ({
      ...u,
      status: u.status || 'Active'
    }));

    return res.json({
      users: formattedUsers,
      pagination: {
        total,
        page: pageNum,
        limit: limitNum,
        totalPages: Math.ceil(total / limitNum) || 1
      }
    });
  } catch (err) {
    console.error("getUsers controller error:", err);
    return res.status(500).json({ error: "Internal server error fetching user database catalog." });
  }
}

// 2. Get User Stats (KPI Cards)
export async function getUserStats(req, res) {
  try {
    await getUserColumns();
    const userRole = req.user.role;
    if (userRole !== 'super_admin' && userRole !== 'moderator') {
      return res.status(403).json({ error: "Access denied." });
    }

    // Role breakdown
    const [roleStats] = await pool.query(`
      SELECT r.name as role, COUNT(u.id) as count
      FROM users u
      LEFT JOIN roles r ON u.role_id = r.id
      GROUP BY r.name
    `);

    // Aggregates: Total, Active, Suspended, Growth
    const [counts] = await pool.query(`
      SELECT 
        COUNT(*) as total_users,
        SUM(CASE WHEN status = 'Active' OR status IS NULL THEN 1 ELSE 0 END) as active_users,
        SUM(CASE WHEN status = 'Suspended' THEN 1 ELSE 0 END) as suspended_users,
        SUM(CASE WHEN created_at >= NOW() - INTERVAL 30 DAY THEN 1 ELSE 0 END) as new_this_month,
        SUM(CASE WHEN last_login_at >= NOW() - INTERVAL 24 HOUR THEN 1 ELSE 0 END) as active_now
      FROM users
    `);

    const stats = counts[0] || { total_users: 0, active_users: 0, suspended_users: 0, new_this_month: 0, active_now: 0 };

    return res.json({
      total: stats.total_users || 0,
      active: stats.active_users || 0,
      suspended: stats.suspended_users || 0,
      active_now: stats.active_now || 0,
      growth_month: stats.new_this_month || 0,
      by_role: roleStats
    });
  } catch (err) {
    console.error("getUserStats error:", err);
    return res.status(500).json({ error: "Internal server error fetching user stats." });
  }
}

// 3. Batch or Individual User Status Update (Activate / Suspend with Optional Reason)
export async function updateUserStatus(req, res) {
  try {
    await getUserColumns();
    const userRole = req.user.role;
    if (userRole !== 'super_admin' && userRole !== 'moderator') {
      return res.status(403).json({ error: "Access denied. Insufficient privileges to update account status." });
    }

    const { userIds, userId, status, reason } = req.body;
    const targetIds = Array.isArray(userIds) ? userIds : (userId ? [userId] : []);

    if (targetIds.length === 0) {
      return res.status(400).json({ error: "Missing target user IDs." });
    }

    if (!['Active', 'Suspended'].includes(status)) {
      return res.status(400).json({ error: "Invalid status value. Must be 'Active' or 'Suspended'." });
    }

    // Filter out current admin user to prevent self-suspension
    const currentAdminId = req.user.id;
    const filteredIds = targetIds.filter(id => parseInt(id) !== currentAdminId);

    if (filteredIds.length === 0) {
      return res.status(400).json({ error: "Cannot alter the suspension status of your own account." });
    }

    const suspensionReason = status === 'Suspended' ? (reason || null) : null;

    // Fetch target users to include names and emails in audit log
    const placeholders = filteredIds.map(() => '?').join(', ');
    const [targetUsers] = await pool.query(
      `SELECT id, first_name, last_name, email, status FROM users WHERE id IN (${placeholders})`,
      filteredIds
    );

    const query = `
      UPDATE users 
      SET status = ?, suspension_reason = ? 
      WHERE id IN (${placeholders})
    `;
    const params = [status, suspensionReason, ...filteredIds];
    const [result] = await pool.query(query, params);

    // Audit Log Entry
    const adminName = [req.user.first_name, req.user.last_name].filter(Boolean).join(' ') || req.user.email || 'Administrator';
    const reasonDetail = suspensionReason ? ` Reason: "${suspensionReason}"` : '';

    if (targetUsers.length === 1) {
      const u = targetUsers[0];
      const eventTitle = status === 'Suspended' ? 'User Suspended' : 'User Activated';
      const desc = status === 'Suspended'
        ? `Admin ${adminName} suspended user ${u.first_name} ${u.last_name} (${u.email}) [ID: #${u.id}].${reasonDetail}`
        : `Admin ${adminName} activated user account for ${u.first_name} ${u.last_name} (${u.email}) [ID: #${u.id}].`;
      await logAuditEvent(
        req.user.id,
        eventTitle,
        desc,
        status === 'Suspended' ? 'Warning' : 'Info',
        req.ip
      );
    } else {
      const namesList = targetUsers.map(u => `${u.first_name} ${u.last_name} (#${u.id})`).join(', ');
      const eventTitle = status === 'Suspended' ? 'Users Suspended' : 'Users Activated';
      const desc = status === 'Suspended'
        ? `Admin ${adminName} batch-suspended ${targetUsers.length} users: [${namesList}].${reasonDetail}`
        : `Admin ${adminName} batch-activated ${targetUsers.length} user accounts: [${namesList}].`;
      await logAuditEvent(
        req.user.id,
        eventTitle,
        desc,
        status === 'Suspended' ? 'Warning' : 'Info',
        req.ip
      );
    }

    return res.json({ 
      message: `Successfully ${status.toLowerCase()}ed ${result.affectedRows} account(s).`,
      affectedCount: result.affectedRows
    });
  } catch (err) {
    console.error("updateUserStatus error:", err);
    return res.status(500).json({ error: "Internal server error modifying user status." });
  }
}

// 4. Update User Profile & Role (Admin Edit)
export async function updateUserProfileAdmin(req, res) {
  try {
    await getUserColumns();
    const userRole = req.user.role;
    if (userRole !== 'super_admin' && userRole !== 'moderator') {
      return res.status(403).json({ error: "Access denied. Insufficient privileges to edit user profiles." });
    }

    const userId = req.params.id;
    const { first_name, last_name, email, phone, business_name, role_name } = req.body;

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

    // Fetch existing user state to audit log exact changes
    const [existingRows] = await pool.query(
      'SELECT u.*, r.name as role_name FROM users u LEFT JOIN roles r ON u.role_id = r.id WHERE u.id = ?',
      [userId]
    );
    if (existingRows.length === 0) {
      return res.status(404).json({ error: "User account not found." });
    }
    const existing = existingRows[0];

    let roleId = null;
    if (role_name) {
      let mapped = role_name.toLowerCase().replace(/\s+/g, '_');
      if (mapped === 'member') mapped = 'user';
      const [roleRows] = await pool.query('SELECT id FROM roles WHERE name = ?', [mapped]);
      if (roleRows.length > 0) {
        roleId = roleRows[0].id;
      }
    }

    const updateQuery = roleId
      ? `UPDATE users SET first_name = ?, last_name = ?, email = ?, phone = ?, business_name = ?, role_id = ? WHERE id = ?`
      : `UPDATE users SET first_name = ?, last_name = ?, email = ?, phone = ?, business_name = ? WHERE id = ?`;
    
    const updateParams = roleId
      ? [first_name, last_name, email, phone || null, business_name || null, roleId, userId]
      : [first_name, last_name, email, phone || null, business_name || null, userId];

    const [result] = await pool.query(updateQuery, updateParams);
    if (result.affectedRows === 0) {
      return res.status(404).json({ error: "User account not found." });
    }

    // Determine field modifications for descriptive audit log
    const changes = [];
    if (existing.first_name !== first_name || existing.last_name !== last_name) {
      changes.push(`Name: "${existing.first_name} ${existing.last_name}" -> "${first_name} ${last_name}"`);
    }
    if (existing.email !== email) {
      changes.push(`Email: "${existing.email}" -> "${email}"`);
    }
    if ((existing.phone || "") !== (phone || "")) {
      changes.push(`Phone: "${existing.phone || 'None'}" -> "${phone || 'None'}"`);
    }
    if ((existing.business_name || "") !== (business_name || "")) {
      changes.push(`Business: "${existing.business_name || 'None'}" -> "${business_name || 'None'}"`);
    }
    if (role_name) {
      let currentDisplayRole = existing.role_name === 'user' ? 'Member' : (existing.role_name === 'super_admin' ? 'Super Admin' : (existing.role_name === 'business_owner' ? 'Business Owner' : (existing.role_name || 'Member')));
      if (currentDisplayRole !== role_name) {
        changes.push(`Role: "${currentDisplayRole}" -> "${role_name}"`);
      }
    }

    const changesText = changes.length > 0 ? changes.join('; ') : 'Profile details updated';
    const adminName = [req.user.first_name, req.user.last_name].filter(Boolean).join(' ') || req.user.email || 'Administrator';
    await logAuditEvent(
      req.user.id,
      'User Profile Edited',
      `Admin ${adminName} edited user #${userId} (${existing.email}): ${changesText}.`,
      'Info',
      req.ip
    );

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

// 5. Update User Role (Legacy standalone endpoint)
export async function updateUserRole(req, res) {
  const { userId, roleName } = req.body;

  if (!userId || !roleName) {
    return res.status(400).json({ error: "Missing required update parameters." });
  }

  try {
    const [existingRows] = await pool.query(
      'SELECT u.*, r.name as role_name FROM users u LEFT JOIN roles r ON u.role_id = r.id WHERE u.id = ?',
      [userId]
    );
    const existing = existingRows[0] || {};

    let mapped = roleName.toLowerCase().replace(/\s+/g, '_');
    if (mapped === 'member') mapped = 'user';

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

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

    const adminName = [req.user.first_name, req.user.last_name].filter(Boolean).join(' ') || req.user.email || 'Administrator';
    await logAuditEvent(
      req.user.id,
      'User Role Changed',
      `Admin ${adminName} updated user #${userId} (${existing.email || ''}) role to "${roleName}".`,
      'Info',
      req.ip
    );

    return res.json({ message: "User account role updated successfully." });
  } catch (err) {
    console.error("updateUserRole controller error:", err);
    return res.status(500).json({ error: "Internal server error updating user account role." });
  }
}

// 6. Get Single User Details (Profile Dialog View)
export async function getUserProfile(req, res) {
  try {
    await getUserColumns();
    const userId = req.params.id;

    const query = `
      SELECT u.id, u.first_name, u.last_name, 
             CONCAT(u.first_name, ' ', u.last_name) as name, 
             u.email, u.phone, u.business_name, 
             u.status, u.suspension_reason, u.last_login_at, u.created_at,
             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];

    // Also get business listing count for this user
    const [listingsResult] = await pool.query('SELECT COUNT(*) as count FROM listings WHERE owner_id = ?', [userId]);
    // Also get review count
    const [reviewsResult] = await pool.query('SELECT COUNT(*) as count FROM reviews WHERE user_id = ?', [userId]);

    return res.json({
      user: {
        ...user,
        status: user.status || 'Active',
        listingsCount: listingsResult[0]?.count || 0,
        reviewsCount: reviewsResult[0]?.count || 0
      }
    });
  } catch (err) {
    console.error("getUserProfile error:", err);
    return res.status(500).json({ error: "Internal server error fetching user profile." });
  }
}

// =========================================================================
// VIEWER / GENERAL USER DASHBOARD CONTROLLERS
// =========================================================================

// 7. Get My Personal Profile (Self)
export async function getMyViewerProfile(req, res) {
  try {
    await getUserColumns();
    await ensureViewerTables();
    const userId = req.user.id;

    const query = `
      SELECT u.id, u.first_name, u.last_name, u.email, u.phone, u.avatar_url, u.is_verified, u.created_at, 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 not found." });

    const user = rows[0];
    return res.json({
      success: true,
      user: {
        ...user,
        is_verified: user.is_verified === 1 || user.is_verified === true
      }
    });
  } catch (err) {
    console.error("getMyViewerProfile error:", err);
    return res.status(500).json({ error: "Failed to fetch profile." });
  }
}

// 8. Update My Personal Profile (Self)
export async function updateMyViewerProfile(req, res) {
  try {
    await getUserColumns();
    const userId = req.user.id;
    const { first_name, last_name, phone, avatar_url } = req.body;

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

    await pool.query(
      `UPDATE users 
       SET first_name = ?, last_name = ?, phone = ?, avatar_url = COALESCE(?, avatar_url)
       WHERE id = ?`,
      [first_name.trim(), last_name.trim(), (phone || '').trim() || null, avatar_url || null, userId]
    );

    const [rows] = await pool.query(
      `SELECT u.id, u.first_name, u.last_name, u.email, u.phone, 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 = ?`,
      [userId]
    );

    return res.json({
      success: true,
      message: "Profile updated successfully.",
      user: {
        ...rows[0],
        is_verified: rows[0].is_verified === 1 || rows[0].is_verified === true
      }
    });
  } catch (err) {
    console.error("updateMyViewerProfile error:", err);
    return res.status(500).json({ error: "Failed to update profile." });
  }
}

// 9. Verify OTP (Hardcoded "123123")
export async function verifyOtp(req, res) {
  try {
    await getUserColumns();
    const userId = req.user.id;
    const { otp } = req.body;

    if (!otp) {
      return res.status(400).json({ error: "Please enter the 6-digit verification code." });
    }

    if (String(otp).trim() !== "123123") {
      return res.status(400).json({ error: "Invalid verification code. Please enter '123123'." });
    }

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

    return res.json({
      success: true,
      message: "Account verified successfully! You can now write reviews."
    });
  } catch (err) {
    console.error("verifyOtp error:", err);
    return res.status(500).json({ error: "Failed to verify account code." });
  }
}

// 10. View History Management
export async function getViewHistory(req, res) {
  try {
    await ensureViewerTables();
    const userId = req.user.id;

    const query = `
      SELECT v.listing_id, v.viewed_at, l.name, l.category, l.price, l.rating, l.reviews_count, l.location, l.address, l.image
      FROM user_view_history v
      JOIN listings l ON v.listing_id = l.id
      WHERE v.user_id = ?
      ORDER BY v.viewed_at DESC
      LIMIT 50
    `;
    const [rows] = await pool.query(query, [userId]);
    return res.json({ success: true, history: rows });
  } catch (err) {
    console.error("getViewHistory error:", err);
    return res.status(500).json({ error: "Failed to retrieve view history." });
  }
}

export async function recordViewHistory(req, res) {
  try {
    await ensureViewerTables();
    const userId = req.user.id;
    const listingId = parseInt(req.params.listingId, 10);

    if (!listingId) return res.status(400).json({ error: "Invalid listing ID." });

    await pool.query(
      `INSERT INTO user_view_history (user_id, listing_id, viewed_at)
       VALUES (?, ?, CURRENT_TIMESTAMP)
       ON DUPLICATE KEY UPDATE viewed_at = CURRENT_TIMESTAMP`,
      [userId, listingId]
    );

    return res.json({ success: true });
  } catch (err) {
    console.error("recordViewHistory error:", err);
    return res.status(500).json({ error: "Failed to record view history." });
  }
}

export async function deleteViewHistoryItem(req, res) {
  try {
    await ensureViewerTables();
    const userId = req.user.id;
    const listingId = parseInt(req.params.listingId, 10);

    await pool.query(
      'DELETE FROM user_view_history WHERE user_id = ? AND listing_id = ?',
      [userId, listingId]
    );

    return res.json({ success: true, message: "Item removed from history." });
  } catch (err) {
    console.error("deleteViewHistoryItem error:", err);
    return res.status(500).json({ error: "Failed to delete history item." });
  }
}

export async function clearAllViewHistory(req, res) {
  try {
    await ensureViewerTables();
    const userId = req.user.id;

    await pool.query('DELETE FROM user_view_history WHERE user_id = ?', [userId]);
    return res.json({ success: true, message: "View history cleared." });
  } catch (err) {
    console.error("clearAllViewHistory error:", err);
    return res.status(500).json({ error: "Failed to clear history." });
  }
}

// 11. Saved Listings Management (Bookmarks / Favorites)
export async function getSavedListings(req, res) {
  try {
    await ensureViewerTables();
    const userId = req.user.id;

    const query = `
      SELECT s.listing_id, s.created_at as saved_at, l.name, l.category, l.price, l.rating, l.reviews_count, l.location, l.address, l.image
      FROM user_saved_listings s
      JOIN listings l ON s.listing_id = l.id
      WHERE s.user_id = ?
      ORDER BY s.created_at DESC
    `;
    const [rows] = await pool.query(query, [userId]);
    return res.json({ success: true, saved: rows });
  } catch (err) {
    console.error("getSavedListings error:", err);
    return res.status(500).json({ error: "Failed to retrieve saved listings." });
  }
}

export async function saveListing(req, res) {
  try {
    await ensureViewerTables();
    const userId = req.user.id;
    const listingId = parseInt(req.params.listingId, 10);

    if (!listingId) return res.status(400).json({ error: "Invalid listing ID." });

    await pool.query(
      'INSERT IGNORE INTO user_saved_listings (user_id, listing_id) VALUES (?, ?)',
      [userId, listingId]
    );

    return res.json({ success: true, message: "Listing saved to favorites." });
  } catch (err) {
    console.error("saveListing error:", err);
    return res.status(500).json({ error: "Failed to save listing." });
  }
}

export async function removeSavedListing(req, res) {
  try {
    await ensureViewerTables();
    const userId = req.user.id;
    const listingId = parseInt(req.params.listingId, 10);

    await pool.query(
      'DELETE FROM user_saved_listings WHERE user_id = ? AND listing_id = ?',
      [userId, listingId]
    );

    return res.json({ success: true, message: "Listing removed from favorites." });
  } catch (err) {
    console.error("removeSavedListing error:", err);
    return res.status(500).json({ error: "Failed to remove saved listing." });
  }
}

// 12. User Review History
export async function getMyReviews(req, res) {
  try {
    const userId = req.user.id;
    const query = `
      SELECT r.id, r.listing_id, r.rating, r.comment, r.images, r.created_at,
             l.name as listing_name, l.category as listing_category, l.location as listing_location, l.image as listing_image
      FROM reviews r
      JOIN listings l ON r.listing_id = l.id
      WHERE r.user_id = ?
      ORDER BY r.created_at DESC
    `;
    const [rows] = await pool.query(query, [userId]);

    const formatted = rows.map(r => {
      let parsedImages = [];
      if (r.images) {
        try {
          parsedImages = typeof r.images === 'string' ? JSON.parse(r.images) : r.images;
        } catch (e) {
          parsedImages = [];
        }
      }
      return {
        ...r,
        images: Array.isArray(parsedImages) ? parsedImages : []
      };
    });

    return res.json({ success: true, reviews: formatted });
  } catch (err) {
    console.error("getMyReviews error:", err);
    return res.status(500).json({ error: "Failed to retrieve user reviews." });
  }
}
