// src/client/entities/inventory.ts
// Inventory entity - types and store for inventory management with approval workflow

import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import {
  inventoryRepository,
  type InventoryResponse,
  type InventoryPendingEntryResponse,
  type CreateInventoryRequest,
  type UpdateInventoryRequest,
  type InventoryCategory,
} from '../shared/api/repositories/InventoryRepository';
import { calculateUnifiedList } from './inventory/model/unifiedList';
import type { InventoryUnifiedEntry } from '@shared/contracts/inventory';

// Re-export types for backward compatibility
export type Inventory = InventoryResponse;
export type CreateInventoryInput = CreateInventoryRequest;
export type UpdateInventoryInput = UpdateInventoryRequest;

export const useInventoryStore = defineStore('inventory', () => {
  // State
  const items = ref<Inventory[]>([]);
  const pendingItems = ref<InventoryPendingEntryResponse[]>([]);
  const loading = ref(false);
  const error = ref<string | null>(null);

  // Computed
  const activeItems = computed(() => items.value);
  const unifiedList = computed(() => calculateUnifiedList(items.value, pendingItems.value));
  const pendingCount = computed(() => pendingItems.value.length);

  // Actions
  async function fetchAll() {
    loading.value = true;
    error.value = null;
    try {
      const data = await inventoryRepository.getAll();
      // HARD REPLACE: Direct assignment, not smart merge
      items.value = data;
    } catch (err: any) {
      error.value = err.message || 'Не удалось загрузить инвентарь';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  async function fetchPending() {
    loading.value = true;
    error.value = null;
    try {
      const data = await inventoryRepository.getPending();
      // HARD REPLACE: Direct assignment, not smart merge
      pendingItems.value = data;
    } catch (err: any) {
      error.value = err.message || 'Не удалось загрузить черновики';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  async function approveEntry(id: string) {
    loading.value = true;
    error.value = null;
    try {
      await inventoryRepository.approve(id);
      // Optimistic UI: Remove from pendingItems immediately
      pendingItems.value = pendingItems.value.filter(i => i.id !== id && i.targetId !== id);
      // Refresh both lists after approval
      await Promise.all([fetchAll(), fetchPending()]);
    } catch (err: any) {
      error.value = err.message || 'Не удалось одобрить запись';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  async function rejectEntry(id: string, reason: string) {
    loading.value = true;
    error.value = null;
    try {
      await inventoryRepository.reject(id, reason);
      // Optimistic UI: Remove from pendingItems immediately
      pendingItems.value = pendingItems.value.filter(i => i.id !== id && i.targetId !== id);
      // Refresh both lists after rejection
      await Promise.all([fetchAll(), fetchPending()]);
    } catch (err: any) {
      error.value = err.message || 'Не удалось отклонить запись';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  async function fetchByCategory(category: InventoryCategory) {
    loading.value = true;
    error.value = null;
    try {
      const data = await inventoryRepository.getByCategory(category);
      // HARD REPLACE: Direct assignment, not smart merge
      items.value = data;
    } catch (err: any) {
      error.value = err.message || 'Не удалось загрузить инвентарь';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  async function fetchById(id: string) {
    loading.value = true;
    error.value = null;
    try {
      const data = await inventoryRepository.getById(id);
      // Update or add item to list
      const index = items.value.findIndex((item: Inventory) => item.id === id);
      if (index >= 0) {
        items.value[index] = data;
      } else {
        items.value.push(data);
      }
      return data;
    } catch (err: any) {
      error.value = err.message || 'Не удалось загрузить запись';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  async function create(input: CreateInventoryInput) {
    loading.value = true;
    error.value = null;
    try {
      const data = await inventoryRepository.create(input);
      // Check status to determine which list to add to
      if (data.status === 'pending' || data.targetId) {
        // Manager created a draft - add to pendingItems
        pendingItems.value.push(data as InventoryPendingEntryResponse);
      } else {
        // Admin created directly - add to items
        items.value.push(data);
      }
      return data;
    } catch (err: any) {
      error.value = err.message || 'Не удалось создать запись';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  async function update(id: string, input: UpdateInventoryInput) {
    loading.value = true;
    error.value = null;
    try {
      const data = await inventoryRepository.update(id, input);
      // Check status to determine which list to update
      if (data.status === 'pending' || data.targetId) {
        // Manager updated a draft - update in pendingItems
        const index = pendingItems.value.findIndex((item: InventoryPendingEntryResponse) => item.id === id);
        if (index >= 0) {
          pendingItems.value[index] = data as InventoryPendingEntryResponse;
        } else {
          pendingItems.value.push(data as InventoryPendingEntryResponse);
        }
      } else {
        // Admin updated directly - update in items
        const index = items.value.findIndex((item: Inventory) => item.id === id);
        if (index >= 0) {
          items.value[index] = data;
        }
      }
      return data;
    } catch (err: any) {
      error.value = err.message || 'Не удалось обновить запись';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  async function archive(id: string) {
    loading.value = true;
    error.value = null;
    try {
      await inventoryRepository.archive(id);
      const index = items.value.findIndex((item: Inventory) => item.id === id);
      if (index >= 0) {
        items.value.splice(index, 1);
      }
    } catch (err: any) {
      error.value = err.message || 'Не удалось архивировать запись';
      throw err;
    } finally {
      loading.value = false;
    }
  }

  function clearError() {
    error.value = null;
  }

  return {
    // State
    items,
    pendingItems,
    loading,
    error,
    // Computed
    activeItems,
    unifiedList,
    pendingCount,
    // Actions
    fetchAll,
    fetchPending,
    approveEntry,
    rejectEntry,
    fetchByCategory,
    fetchById,
    create,
    update,
    archive,
    clearError,
  };
});
