#!/usr/bin/env tsx
/**
 * СКРИПТ СИНХРОНИЗАЦИИ СИСТЕМА B → СИСТЕМА A
 * 
 * Синхронизирует существующие данные из FulfillmentConsumableInventory 
 * в FulfillmentConsumable для обеспечения доступности расходников в каталоге
 */

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

interface SyncStats {
  totalInventoryItems: number
  existingCatalogItems: number
  createdCatalogItems: number
  updatedCatalogItems: number
  errors: string[]
}

const SYNC_LOG_PREFIX = '[INVENTORY→CATALOG SYNC]'

/**
 * Главная функция синхронизации
 */
async function syncInventoryToCatalog(dryRun = true): Promise<SyncStats> {
  const stats: SyncStats = {
    totalInventoryItems: 0,
    existingCatalogItems: 0,
    createdCatalogItems: 0,
    updatedCatalogItems: 0,
    errors: [],
  }

  console.warn(`${SYNC_LOG_PREFIX} Starting sync (DRY RUN: ${dryRun})`)
  console.warn(`${SYNC_LOG_PREFIX} Timestamp: ${new Date().toISOString()}`)

  try {
    // Получаем все записи из Системы B (склад)
    const inventoryItems = await prisma.fulfillmentConsumableInventory.findMany({
      include: {
        product: true,
        fulfillmentCenter: true,
      },
      orderBy: {
        createdAt: 'asc',
      },
    })

    stats.totalInventoryItems = inventoryItems.length
    console.warn(`${SYNC_LOG_PREFIX} Found ${stats.totalInventoryItems} inventory items`)

    if (stats.totalInventoryItems === 0) {
      console.warn(`${SYNC_LOG_PREFIX} No inventory items to sync`)
      return stats
    }

    // Синхронизируем каждую запись
    for (const inventoryItem of inventoryItems) {
      try {
        await syncInventoryItem(inventoryItem, stats, dryRun)

        // Логируем прогресс каждые 5 записей
        if ((stats.createdCatalogItems + stats.updatedCatalogItems) % 5 === 0) {
          console.warn(`${SYNC_LOG_PREFIX} Progress: ${stats.createdCatalogItems + stats.updatedCatalogItems}/${inventoryItems.length}`)
        }

      } catch (error) {
        const errorMsg = `Failed to sync inventory item ${inventoryItem.id}: ${error}`
        stats.errors.push(errorMsg)
        console.error(`${SYNC_LOG_PREFIX} ERROR: ${errorMsg}`)
      }
    }

  } catch (error) {
    const errorMsg = `Sync failed: ${error}`
    stats.errors.push(errorMsg)
    console.error(`${SYNC_LOG_PREFIX} CRITICAL ERROR: ${errorMsg}`)
  }

  // Финальная отчетность
  printSyncReport(stats, dryRun)
  return stats
}

/**
 * Синхронизирует одну запись из склада в каталог
 */
async function syncInventoryItem(inventoryItem: any, stats: SyncStats, dryRun: boolean): Promise<void> {
  const fulfillmentCenterId = inventoryItem.fulfillmentCenterId
  const productName = inventoryItem.product.name

  // Проверяем существует ли запись в каталоге
  const existingCatalogItem = await prisma.fulfillmentConsumable.findFirst({
    where: {
      fulfillmentId: fulfillmentCenterId,
      name: productName,
    },
  })

  if (existingCatalogItem) {
    stats.existingCatalogItems++
    
    if (dryRun) {
      console.warn(`${SYNC_LOG_PREFIX} [DRY RUN] Would update: ${productName} ` +
        `(stock: ${inventoryItem.currentStock})`)
      return
    }

    // Обновляем существующую запись в каталоге
    await prisma.fulfillmentConsumable.update({
      where: { id: existingCatalogItem.id },
      data: {
        currentStock: inventoryItem.currentStock,
        minStock: inventoryItem.minStock,
        isAvailable: inventoryItem.currentStock > 0,
        inventoryId: inventoryItem.id,
        updatedAt: new Date(),
      },
    })

    stats.updatedCatalogItems++
    console.warn(`${SYNC_LOG_PREFIX} ✅ Updated catalog: ${productName}`)
  } else {
    if (dryRun) {
      console.warn(`${SYNC_LOG_PREFIX} [DRY RUN] Would create: ${productName} ` +
        `(stock: ${inventoryItem.currentStock})`)
      return
    }

    // Создаем новую запись в каталоге
    await prisma.fulfillmentConsumable.create({
      data: {
        fulfillmentId: fulfillmentCenterId,
        inventoryId: inventoryItem.id,
        name: inventoryItem.product.name,
        article: inventoryItem.product.article || '',
        pricePerUnit: 0, // Цену фулфилмент устанавливает вручную
        unit: inventoryItem.product.unit || 'шт',
        minStock: inventoryItem.minStock,
        currentStock: inventoryItem.currentStock,
        isAvailable: inventoryItem.currentStock > 0,
        imageUrl: inventoryItem.product.imageUrl,
        sortOrder: 0,
      },
    })

    stats.createdCatalogItems++
    console.warn(`${SYNC_LOG_PREFIX} ✅ Created catalog: ${productName}`)
  }
}

/**
 * Печатает детальный отчет о синхронизации
 */
function printSyncReport(stats: SyncStats, dryRun: boolean): void {
  console.log('\n' + '='.repeat(60))
  console.warn(`${SYNC_LOG_PREFIX} SYNC REPORT`)
  console.log('='.repeat(60))
  console.warn(`Mode: ${dryRun ? 'DRY RUN' : 'PRODUCTION'}`)
  console.warn(`Timestamp: ${new Date().toISOString()}`)
  console.log('')
  console.log('📊 STATISTICS:')
  console.warn(`  Inventory items found: ${stats.totalInventoryItems}`)
  console.warn(`  Existing catalog items: ${stats.existingCatalogItems}`)
  console.warn(`  Created catalog items: ${stats.createdCatalogItems}`)
  console.warn(`  Updated catalog items: ${stats.updatedCatalogItems}`)
  console.warn(`  Errors encountered: ${stats.errors.length}`)
  console.log('')

  if (stats.errors.length > 0) {
    console.log('❌ ERRORS:')
    stats.errors.forEach((error, index) => {
      console.warn(`  ${index + 1}. ${error}`)
    })
    console.log('')
  }

  if (dryRun) {
    console.log('🔄 TO RUN ACTUAL SYNC:')
    console.log('  node scripts/sync-inventory-to-catalog.ts --production')
  } else {
    console.log('✅ SYNC COMPLETED!')
    console.log('🔄 TO VERIFY RESULTS:')
    console.log('  Check FulfillmentConsumable table')
    console.log('  Refresh http://localhost:3000/fulfillment/services/consumables')
  }

  console.log('='.repeat(60))
}

/**
 * CLI интерфейс
 */
async function main() {
  const args = process.argv.slice(2)
  const isProduction = args.includes('--production')
  const dryRun = !isProduction
  
  if (dryRun) {
    console.log('🔍 Running in DRY RUN mode (no actual changes)')
    console.log('📝 Add --production flag to run actual sync')
  } else {
    console.log('⚠️ Running in PRODUCTION mode (will make changes)')
    console.log('Press Ctrl+C to cancel...')
    
    // Ждем 3 секунды в production режиме
    await new Promise(resolve => setTimeout(resolve, 3000))
  }

  try {
    const stats = await syncInventoryToCatalog(dryRun)
    
    if (stats.errors.length > 0) {
      console.error(`${SYNC_LOG_PREFIX} Sync completed with errors`)
      process.exit(1)
    }
    
    console.warn(`${SYNC_LOG_PREFIX} Sync completed successfully`)
    process.exit(0)
    
  } catch (error) {
    console.error(`${SYNC_LOG_PREFIX} Sync failed:`, error)
    process.exit(1)
  } finally {
    await prisma.$disconnect()
  }
}

// Запускаем только если скрипт вызван напрямую
if (import.meta.url === `file://${process.argv[1]}`) {
  main().catch(console.error)
}

export { syncInventoryToCatalog }