// src/server/features/reference_books/lib/inventory.drafts.ts
// Drafting logic for manager approval workflow

import { db } from '../../../shared/db/client';
import { inventoryTable, inventoryPendingTable } from '../db/inventory.table';
import { eq } from 'drizzle-orm';
import { randomUUID } from 'node:crypto';
import { logger } from '../../../shared/lib/logger';
import type { InventoryPendingInsert } from '../db/inventory.table';

// Type for inventory pending entry
type InventoryPendingEntry = typeof inventoryPendingTable.$inferSelect;

/**
 * Create draft inventory entry (Manager only)
 */
export async function createDraftInventory(data: any, userId: string): Promise<InventoryPendingEntry> {
  const insertData: InventoryPendingInsert = {
    ...data,
    status: 'pending',
    createdBy: userId,
    createdAt: new Date(),
    updatedAt: new Date(),
  };

  const result = await db.insert(inventoryPendingTable).values(insertData).$returningId();
  if (!result || !result[0]) {
    throw new Error('Failed to create draft inventory entry');
  }

  const finalEntry = await db.select()
    .from(inventoryPendingTable)
    .where(eq(inventoryPendingTable.id, result[0].id))
    .limit(1);

  if (!finalEntry[0]) {
    throw new Error('Failed to retrieve created draft inventory entry');
  }

  logger.info(`[Inventory] Draft created by Manager: ${finalEntry[0].name}`);

  return finalEntry[0];
}

/**
 * Update draft inventory entry (Manager only)
 * Creates a new pending entry with targetId pointing to the original
 */
export async function updateDraftInventory(request: any, existing: any): Promise<InventoryPendingEntry> {
  const { id, name, category, quantity, unit, location, comment, weightPerUnit, manufacturer, model, serialNumber, orderingLink, articleNumber, updatedBy } = request;

  // Валидация полей
  if (name !== undefined && name.trim().length === 0) {
    throw new Error('Название обязательно');
  }
  if (category !== undefined && category.trim().length === 0) {
    throw new Error('Категория обязательна');
  }
  if (quantity !== undefined && quantity.trim().length === 0) {
    throw new Error('Количество обязательно');
  }
  if (location !== undefined && location.trim().length === 0) {
    throw new Error('Локация обязательна');
  }

  const updates = {
    name: name || existing.name,
    category: category || existing.category,
    quantity: quantity || existing.quantity,
    unit: unit !== undefined ? unit : existing.unit,
    location: location || existing.location,
    comment: comment !== undefined ? (comment?.trim() || null) : existing.comment,
    weightPerUnit: weightPerUnit !== undefined ? weightPerUnit : existing.weightPerUnit,
    manufacturer: manufacturer !== undefined ? (manufacturer?.trim() || null) : existing.manufacturer,
    model: model !== undefined ? (model?.trim() || null) : existing.model,
    serialNumber: serialNumber !== undefined ? (serialNumber?.trim() || null) : existing.serialNumber,
    orderingLink: orderingLink !== undefined ? (orderingLink?.trim() || null) : existing.orderingLink,
    articleNumber: articleNumber !== undefined ? (articleNumber?.trim() || null) : existing.articleNumber,
  };

  const result = await db.insert(inventoryPendingTable)
    .values({
      id: randomUUID(),
      name: updates.name.trim(),
      category: updates.category.trim(),
      quantity: updates.quantity,
      unit: updates.unit,
      location: updates.location.trim(),
      comment: updates.comment,
      weightPerUnit: updates.weightPerUnit,
      manufacturer: updates.manufacturer,
      model: updates.model,
      serialNumber: updates.serialNumber,
      orderingLink: updates.orderingLink,
      articleNumber: updates.articleNumber,
      status: 'pending',
      targetId: id, // Ссылка на оригинальную запись
      createdBy: updatedBy,
      createdAt: new Date(),
      updatedAt: new Date(),
    })
    .$returningId();

  const pendingEntry = await db.select()
    .from(inventoryPendingTable)
    .where(eq(inventoryPendingTable.id, result[0].id))
    .limit(1);

  if (!pendingEntry[0]) {
    throw new Error('Ошибка при создании черновика на согласование');
  }

  logger.info(`[Inventory] Pending update created by Manager for entry: ${id}`);

  return pendingEntry[0];
}

/**
 * Delete draft inventory entry (Manager only)
 */
export async function deleteDraftInventory(id: string): Promise<void> {
  await db.delete(inventoryPendingTable).where(eq(inventoryPendingTable.id, id));
  logger.info(`[Inventory] Draft deleted by Manager: ${id}`);
}

/**
 * Create a delete request for an inventory item (Manager only)
 * Copies the item to pending table with 'to_delete' status
 */
export async function createDeleteRequestInventory(originalItem: any, userId: string) {
  const insertData = {
    ...originalItem, // Copy all fields (name, category, etc.)
    id: randomUUID(), // New ID for the draft
    targetId: originalItem.id, // Link to original
    status: 'to_delete',
    createdBy: userId,
    createdAt: new Date(),
    updatedAt: new Date(),
    // Ensure we don't copy system fields that shouldn't be there
    archivedAt: null,
  };

  await db.insert(inventoryPendingTable).values(insertData);
  logger.info(`[Inventory] Delete request created for: ${originalItem.name}`);
}
