/**
 * Equipment Model
 *
 * equipments + equipment_photos CRUD (MariaDB)
 */

const { getPool } = require('./userModel');

// ==================== 기본 CRUD ====================

async function getAll(filters = {}) {
  const db = getPool();
  let sql = `SELECT e.*, w.workplace_name, c.category_name
     FROM equipments e
     LEFT JOIN workplaces w ON e.workplace_id = w.workplace_id
     LEFT JOIN workplace_categories c ON w.category_id = c.category_id`;
  const conditions = [];
  const values = [];

  if (filters.workplace_id) { conditions.push('e.workplace_id = ?'); values.push(filters.workplace_id); }
  if (filters.equipment_type) { conditions.push('e.equipment_type = ?'); values.push(filters.equipment_type); }
  if (filters.status) { conditions.push('e.status = ?'); values.push(filters.status); }
  if (filters.search) {
    conditions.push('(e.equipment_name LIKE ? OR e.equipment_code LIKE ?)');
    const term = `%${filters.search}%`;
    values.push(term, term);
  }

  if (conditions.length) sql += ' WHERE ' + conditions.join(' AND ');
  sql += ' ORDER BY e.equipment_code ASC';

  const [rows] = await db.query(sql, values);
  return rows;
}

async function getById(id) {
  const db = getPool();
  const [rows] = await db.query(
    `SELECT e.*, w.workplace_name, c.category_name
     FROM equipments e
     LEFT JOIN workplaces w ON e.workplace_id = w.workplace_id
     LEFT JOIN workplace_categories c ON w.category_id = c.category_id
     WHERE e.equipment_id = ?`,
    [id]
  );
  return rows[0] || null;
}

async function getByWorkplace(workplaceId) {
  const db = getPool();
  const [rows] = await db.query(
    `SELECT e.*, w.workplace_name
     FROM equipments e
     LEFT JOIN workplaces w ON e.workplace_id = w.workplace_id
     WHERE e.workplace_id = ?
     ORDER BY e.equipment_code ASC`,
    [workplaceId]
  );
  return rows;
}

async function create(data) {
  const db = getPool();
  const [result] = await db.query(
    `INSERT INTO equipments (equipment_code, equipment_name, equipment_type, model_name, manufacturer, supplier, purchase_price, installation_date, serial_number, specifications, status, notes, workplace_id, map_x_percent, map_y_percent, map_width_percent, map_height_percent)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
    [
      data.equipment_code, data.equipment_name,
      data.equipment_type || null, data.model_name || null,
      data.manufacturer || null, data.supplier || null,
      data.purchase_price || null, data.installation_date || null,
      data.serial_number || null, data.specifications || null,
      data.status || 'active', data.notes || null,
      data.workplace_id || null,
      data.map_x_percent || null, data.map_y_percent || null,
      data.map_width_percent || null, data.map_height_percent || null
    ]
  );
  return getById(result.insertId);
}

async function update(id, data) {
  const db = getPool();
  const fields = [];
  const values = [];

  if (data.equipment_code !== undefined) { fields.push('equipment_code = ?'); values.push(data.equipment_code); }
  if (data.equipment_name !== undefined) { fields.push('equipment_name = ?'); values.push(data.equipment_name); }
  if (data.equipment_type !== undefined) { fields.push('equipment_type = ?'); values.push(data.equipment_type || null); }
  if (data.model_name !== undefined) { fields.push('model_name = ?'); values.push(data.model_name || null); }
  if (data.manufacturer !== undefined) { fields.push('manufacturer = ?'); values.push(data.manufacturer || null); }
  if (data.supplier !== undefined) { fields.push('supplier = ?'); values.push(data.supplier || null); }
  if (data.purchase_price !== undefined) { fields.push('purchase_price = ?'); values.push(data.purchase_price || null); }
  if (data.installation_date !== undefined) { fields.push('installation_date = ?'); values.push(data.installation_date || null); }
  if (data.serial_number !== undefined) { fields.push('serial_number = ?'); values.push(data.serial_number || null); }
  if (data.specifications !== undefined) { fields.push('specifications = ?'); values.push(data.specifications || null); }
  if (data.status !== undefined) { fields.push('status = ?'); values.push(data.status); }
  if (data.notes !== undefined) { fields.push('notes = ?'); values.push(data.notes || null); }
  if (data.workplace_id !== undefined) { fields.push('workplace_id = ?'); values.push(data.workplace_id || null); }
  if (data.map_x_percent !== undefined) { fields.push('map_x_percent = ?'); values.push(data.map_x_percent); }
  if (data.map_y_percent !== undefined) { fields.push('map_y_percent = ?'); values.push(data.map_y_percent); }
  if (data.map_width_percent !== undefined) { fields.push('map_width_percent = ?'); values.push(data.map_width_percent); }
  if (data.map_height_percent !== undefined) { fields.push('map_height_percent = ?'); values.push(data.map_height_percent); }

  if (fields.length === 0) return getById(id);

  values.push(id);
  await db.query(`UPDATE equipments SET ${fields.join(', ')} WHERE equipment_id = ?`, values);
  return getById(id);
}

async function remove(id) {
  const db = getPool();
  await db.query('DELETE FROM equipments WHERE equipment_id = ?', [id]);
}

async function getEquipmentTypes() {
  const db = getPool();
  const [rows] = await db.query(
    'SELECT DISTINCT equipment_type FROM equipments WHERE equipment_type IS NOT NULL AND equipment_type != "" ORDER BY equipment_type ASC'
  );
  return rows.map(r => r.equipment_type);
}

async function getNextCode(prefix = 'TKP') {
  const db = getPool();
  const [rows] = await db.query(
    'SELECT equipment_code FROM equipments WHERE equipment_code LIKE ? ORDER BY equipment_code DESC LIMIT 1',
    [`${prefix}-%`]
  );
  if (!rows.length) return `${prefix}-001`;
  const lastNum = parseInt(rows[0].equipment_code.replace(`${prefix}-`, ''), 10) || 0;
  return `${prefix}-${String(lastNum + 1).padStart(3, '0')}`;
}

async function checkDuplicateCode(code, excludeId) {
  const db = getPool();
  let sql = 'SELECT equipment_id FROM equipments WHERE equipment_code = ?';
  const values = [code];
  if (excludeId) { sql += ' AND equipment_id != ?'; values.push(excludeId); }
  const [rows] = await db.query(sql, values);
  return rows.length > 0;
}

// ==================== 지도 위치 ====================

async function updateMapPosition(id, positionData) {
  const db = getPool();
  const fields = ['map_x_percent = ?', 'map_y_percent = ?', 'map_width_percent = ?', 'map_height_percent = ?'];
  const values = [positionData.map_x_percent, positionData.map_y_percent, positionData.map_width_percent, positionData.map_height_percent];
  if (positionData.workplace_id !== undefined) {
    fields.push('workplace_id = ?');
    values.push(positionData.workplace_id);
  }
  values.push(id);
  await db.query(`UPDATE equipments SET ${fields.join(', ')} WHERE equipment_id = ?`, values);
  return getById(id);
}

// ==================== 사진 ====================

async function addPhoto(equipmentId, photoData) {
  const db = getPool();
  const [result] = await db.query(
    `INSERT INTO equipment_photos (equipment_id, photo_path, description, display_order, uploaded_by) VALUES (?, ?, ?, ?, ?)`,
    [equipmentId, photoData.photo_path, photoData.description || null, photoData.display_order || 0, photoData.uploaded_by || null]
  );
  return { photo_id: result.insertId, equipment_id: equipmentId, ...photoData };
}

async function getPhotos(equipmentId) {
  const db = getPool();
  const [rows] = await db.query(
    'SELECT * FROM equipment_photos WHERE equipment_id = ? ORDER BY display_order ASC, created_at ASC',
    [equipmentId]
  );
  return rows;
}

async function deletePhoto(photoId) {
  const db = getPool();
  const [photo] = await db.query('SELECT photo_path FROM equipment_photos WHERE photo_id = ?', [photoId]);
  await db.query('DELETE FROM equipment_photos WHERE photo_id = ?', [photoId]);
  return { photo_id: photoId, photo_path: photo[0]?.photo_path };
}

module.exports = {
  getAll, getById, getByWorkplace, create, update, remove,
  getEquipmentTypes, getNextCode, checkDuplicateCode,
  updateMapPosition,
  addPhoto, getPhotos, deletePhoto
};
