// src/shared/contracts/inventory.ts
// Contracts for inventory feature - Zod schemas and types

import { z } from 'zod';

/**
 * Inventory entry type (unified for both approved and pending entries)
 */
export interface InventoryEntry {
  id: string;
  name: string;
  category: string;
  quantity: string;
  unit: string | null;
  location: string;
  comment: string | null;
  weightPerUnit: string | null;
  manufacturer: string | null;
  model: string | null;
  serialNumber: string | null;
  orderingLink: string | null;
  articleNumber: string | null;
  isApproved: boolean;
  status?: 'pending' | 'approved' | 'rejected' | 'to_delete';
  targetId: string | null;
  createdBy: string | null;
  creatorName: string | null;
  reviewedBy: string | null;
  reviewedAt: string | null;
  rejectionReason: string | null;
  createdAt: string;
  updatedAt: string;
  archivedAt: string | null;
}

/**
 * Inventory pending entry type (для записей на согласовании)
 */
export interface InventoryPendingEntry {
  id: string;
  name: string;
  category: string;
  quantity: string;
  unit: string | null;
  location: string;
  comment: string | null;
  weightPerUnit: string | null;
  manufacturer: string | null;
  model: string | null;
  serialNumber: string | null;
  orderingLink: string | null;
  articleNumber: string | null;
  status: 'pending' | 'approved' | 'rejected' | 'to_delete';
  targetId: string | null; // ID оригинальной записи в таблице inventory
  createdBy: string | null;
  creatorName: string | null; // Имя сотрудника, создавшего запись
  reviewedBy: string | null;
  reviewedAt: string | null;
  rejectionReason: string | null;
  createdAt: string;
  updatedAt: string;
  archivedAt: string | null;
  isApproved: boolean;
}

/**
 * Extended type for unified list with diff information
 */
export interface InventoryUnifiedEntry extends Omit<InventoryEntry, 'creatorName'> {
  isModified?: boolean;  // true если это редактирование существующей записи
  isNew?: boolean;       // true если это новая запись (без targetId)
  isPendingDelete?: boolean;  // true если это запрос на удаление
  originalData?: Partial<InventoryEntry>; // оригинальные данные для diff
  creatorName?: string | null; // Имя сотрудника, создавшего запись
}

/**
 * Create inventory entry request
 */
export interface InventoryCreateRequest {
  name: string;
  category: string;
  quantity: string;
  unit: string | null;
  location: string;
  comment: string | null;
  weightPerUnit: string | null;
  manufacturer: string | null;
  model: string | null;
  serialNumber: string | null;
  orderingLink: string | null;
  articleNumber: string | null;
}

/**
 * Update inventory entry request
 */
export interface InventoryUpdateRequest {
  name?: string;
  category?: string;
  quantity?: string;
  unit?: string | null;
  location?: string;
  comment?: string | null;
  weightPerUnit?: string | null;
  manufacturer?: string | null;
  model?: string | null;
  serialNumber?: string | null;
  orderingLink?: string | null;
  articleNumber?: string | null;
}

/**
 * Zod schema for creating inventory entry
 */
export const inventoryCreateSchema = z.object({
  name: z.string().min(1, 'Название обязательно'),
  category: z.string().min(1, 'Категория обязательна'),
  quantity: z.coerce.string().min(0, 'Количество обязательно'),
  unit: z.string().nullable(),
  location: z.string().min(1, 'Локация обязательна'),
  comment: z.string().nullable(),
  weightPerUnit: z.coerce.string().nullable(),
  manufacturer: z.string().nullable(),
  model: z.string().nullable(),
  serialNumber: z.string().nullable(),
  orderingLink: z.string().nullable(),
  articleNumber: z.string().nullable(),
});

/**
 * Zod schema for updating inventory entry
 */
export const inventoryUpdateSchema = z.object({
  name: z.string().min(1).optional(),
  category: z.string().min(1).optional(),
  quantity: z.coerce.string().min(0).optional(),
  unit: z.string().nullable().optional(),
  location: z.string().min(1).optional(),
  comment: z.string().nullable().optional(),
  weightPerUnit: z.coerce.string().nullable().optional(),
  manufacturer: z.string().nullable().optional(),
  model: z.string().nullable().optional(),
  serialNumber: z.string().nullable().optional(),
  orderingLink: z.string().nullable().optional(),
  articleNumber: z.string().nullable().optional(),
});

/**
 * Zod schema for inventory entry response (unified for both approved and pending entries)
 */
export const inventoryEntrySchema = z.object({
  id: z.string(),
  name: z.string(),
  category: z.string(),
  quantity: z.string(),
  unit: z.string().nullable(),
  location: z.string(),
  comment: z.string().nullable(),
  weightPerUnit: z.string().nullable(),
  manufacturer: z.string().nullable(),
  model: z.string().nullable(),
  serialNumber: z.string().nullable(),
  orderingLink: z.string().nullable(),
  articleNumber: z.string().nullable(),
  isApproved: z.boolean(),
  status: z.enum(['pending', 'approved', 'rejected', 'to_delete']).optional(),
  targetId: z.string().nullable(),
  createdBy: z.string().nullable(),
  creatorName: z.string().nullable(),
  reviewedBy: z.string().nullable(),
  reviewedAt: z.string().nullable(),
  rejectionReason: z.string().nullable(),
  createdAt: z.string(),
  updatedAt: z.string(),
  archivedAt: z.string().nullable(),
});

/**
 * Zod schema for inventory entries array response
 */
export const inventoryEntriesSchema = z.array(inventoryEntrySchema);

/**
 * Zod schema for inventory pending entry response
 */
export const inventoryPendingEntrySchema = z.object({
  id: z.string(),
  name: z.string(),
  category: z.string(),
  quantity: z.string(),
  unit: z.string().nullable(),
  location: z.string(),
  comment: z.string().nullable(),
  weightPerUnit: z.string().nullable(),
  manufacturer: z.string().nullable(),
  model: z.string().nullable(),
  serialNumber: z.string().nullable(),
  orderingLink: z.string().nullable(),
  articleNumber: z.string().nullable(),
  status: z.enum(['pending', 'approved', 'rejected', 'to_delete']),
  targetId: z.string().nullable(),
  createdBy: z.string().nullable(),
  creatorName: z.string().nullable(),
  reviewedBy: z.string().nullable(),
  reviewedAt: z.string().nullable(),
  rejectionReason: z.string().nullable(),
  createdAt: z.string(),
  updatedAt: z.string(),
});

/**
 * Zod schema for inventory pending entries array response
 */
export const inventoryPendingEntriesSchema = z.array(inventoryPendingEntrySchema);

/**
 * Zod schema for approve/reject response
 */
export const inventoryActionResponseSchema = z.object({
  success: z.literal(true),
  message: z.string(),
  count: z.number().optional(),
});

/**
 * Zod schema for error response
 */
export const inventoryErrorResponseSchema = z.object({
  success: z.literal(false),
  error: z.object({
    message: z.string(),
    code: z.string(),
  }),
});
