/**
 * Service: Manajemen Inventaris / Gudang (Warehouse)
 */
const db = require('../config/database');
const { logger } = require('../config/logger');

// ─── CATEGORIES ───────────────────────────────────────────────────────────
function getAllCategories() {
  return db.prepare('SELECT * FROM inventory_categories ORDER BY name ASC').all();
}

function createCategory(data) {
  const { name, description } = data;
  return db.prepare('INSERT INTO inventory_categories (name, description) VALUES (?, ?)').run(name, description);
}

function updateCategory(id, data) {
  const { name, description } = data;
  return db.prepare('UPDATE inventory_categories SET name = ?, description = ? WHERE id = ?').run(name, description, id);
}

function deleteCategory(id) {
  return db.prepare('DELETE FROM inventory_categories WHERE id = ?').run(id);
}

// ─── ITEMS ───────────────────────────────────────────────────────────────
function getAllItems(search = '') {
  let query = `
    SELECT i.*, c.name as category_name, 
           (SELECT SUM(quantity) FROM inventory_stock s WHERE s.item_id = i.id AND s.status = 'available') as stock_available,
           (SELECT SUM(quantity) FROM inventory_stock s WHERE s.item_id = i.id AND s.status = 'assigned') as stock_assigned
    FROM inventory_items i
    LEFT JOIN inventory_categories c ON i.category_id = c.id
  `;
  const params = [];
  if (search) {
    query += ' WHERE i.name LIKE ? OR i.brand LIKE ? OR i.model LIKE ?';
    const s = `%${search}%`;
    params.push(s, s, s);
  }
  query += ' ORDER BY i.name ASC';
  return db.prepare(query).all(...params);
}

function getItemById(id) {
  return db.prepare(`
    SELECT i.*, c.name as category_name
    FROM inventory_items i
    LEFT JOIN inventory_categories c ON i.category_id = c.id
    WHERE i.id = ?
  `).get(id);
}

function createItem(data) {
  const { category_id, name, brand, model, unit, min_stock, description } = data;
  return db.prepare(`
    INSERT INTO inventory_items (category_id, name, brand, model, unit, min_stock, description)
    VALUES (?, ?, ?, ?, ?, ?, ?)
  `).run(category_id, name, brand, model, unit, min_stock, description);
}

function updateItem(id, data) {
  const { category_id, name, brand, model, unit, min_stock, description } = data;
  return db.prepare(`
    UPDATE inventory_items 
    SET category_id = ?, name = ?, brand = ?, model = ?, unit = ?, min_stock = ?, description = ?
    WHERE id = ?
  `).run(category_id, name, brand, model, unit, min_stock, description, id);
}

function deleteItem(id) {
  return db.prepare('DELETE FROM inventory_items WHERE id = ?').run(id);
}

// ─── STOCK ───────────────────────────────────────────────────────────────
function getStockByItem(itemId) {
  return db.prepare(`
    SELECT s.*, cust.name as customer_name
    FROM inventory_stock s
    LEFT JOIN customers cust ON s.assigned_to_customer_id = cust.id
    WHERE s.item_id = ?
    ORDER BY s.created_at DESC
  `).all(itemId);
}

function addStock(data, actor = 'Admin') {
  const { item_id, serial_number, quantity, condition, location, note } = data;
  
  const run = db.transaction(() => {
    const result = db.prepare(`
      INSERT INTO inventory_stock (item_id, serial_number, quantity, condition, location, note)
      VALUES (?, ?, ?, ?, ?, ?)
    `).run(item_id, serial_number || null, quantity, condition || 'new', location || 'Gudang Utama', note || '');

    db.prepare(`
      INSERT INTO inventory_logs (item_id, stock_id, type, quantity, actor, note)
      VALUES (?, ?, 'in', ?, ?, ?)
    `).run(item_id, result.lastInsertRowid, quantity, actor, note || 'Stock Masuk');

    return result;
  });

  return run();
}

function assignStockToCustomer(stockId, customerId, actor = 'Admin', note = '') {
  const stock = db.prepare('SELECT * FROM inventory_stock WHERE id = ?').get(stockId);
  if (!stock) throw new Error('Stock tidak ditemukan');
  if (stock.status === 'assigned') throw new Error('Stock sudah terpasang di pelanggan lain');

  const run = db.transaction(() => {
    db.prepare(`
      UPDATE inventory_stock 
      SET status = 'assigned', assigned_to_customer_id = ?, updated_at = CURRENT_TIMESTAMP
      WHERE id = ?
    `).run(customerId, stockId);

    db.prepare(`
      INSERT INTO inventory_logs (item_id, stock_id, type, quantity, actor, note)
      VALUES (?, ?, 'out', ?, ?, ?)
    `).run(stock.item_id, stockId, stock.quantity, actor, note || `Terpasang ke pelanggan ID: ${customerId}`);
  });

  return run();
}

function adjustStock(stockId, newQuantity, note, actor = 'Admin') {
  const stock = db.prepare('SELECT * FROM inventory_stock WHERE id = ?').get(stockId);
  if (!stock) throw new Error('Stock tidak ditemukan');

  const run = db.transaction(() => {
    const diff = newQuantity - stock.quantity;
    db.prepare('UPDATE inventory_stock SET quantity = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(newQuantity, stockId);

    db.prepare(`
      INSERT INTO inventory_logs (item_id, stock_id, type, quantity, actor, note)
      VALUES (?, ?, 'adjust', ?, ?, ?)
    `).run(stock.item_id, stockId, diff, actor, note || 'Penyesuaian Stock');
  });

  return run();
}

function getInventoryLogs(limit = 100) {
  return db.prepare(`
    SELECT l.*, i.name as item_name, s.serial_number
    FROM inventory_logs l
    LEFT JOIN inventory_items i ON l.item_id = i.id
    LEFT JOIN inventory_stock s ON l.stock_id = s.id
    ORDER BY l.created_at DESC
    LIMIT ?
  `).all(limit);
}

function getLowStockItems() {
  return db.prepare(`
    SELECT i.*, c.name as category_name, SUM(s.quantity) as current_stock
    FROM inventory_items i
    LEFT JOIN inventory_categories c ON i.category_id = c.id
    LEFT JOIN inventory_stock s ON s.item_id = i.id AND s.status = 'available'
    GROUP BY i.id
    HAVING current_stock <= i.min_stock OR current_stock IS NULL
  `).all();
}

module.exports = {
  getAllCategories, createCategory, updateCategory, deleteCategory,
  getAllItems, getItemById, createItem, updateItem, deleteItem,
  getStockByItem, addStock, assignStockToCustomer, adjustStock,
  getInventoryLogs, getLowStockItems
};
