#!/usr/bin/env tsx
/**
 * СКРИПТ МИГРАЦИИ V1 → V2 INVENTORY SYSTEM
 * 
 * Безопасно переносит данные из старой системы Supply в новую FulfillmentConsumableInventory
 * с возможностью отката и детальной отчетностью
 */

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

interface MigrationStats {
  totalV1Records: number
  fulfillmentSupplies: number
  migratedRecords: number
  skippedRecords: number
  errors: string[]
  warnings: string[]
}

interface V1SupplyRecord {
  id: string
  name: string
  description: string | null
  price: any // Decimal
  quantity: number
  unit: string
  category: string | null
  status: string
  date: Date
  supplier: string
  minStock: number
  currentStock: number
  organizationId: string
  type: string | null
  createdAt: Date
  updatedAt: Date
}

const MIGRATION_LOG_PREFIX = '[V1→V2 MIGRATION]'

/**
 * Главная функция миграции
 */
async function migrateV1ToV2Inventory(dryRun = true): Promise<MigrationStats> {
  const stats: MigrationStats = {
    totalV1Records: 0,
    fulfillmentSupplies: 0,
    migratedRecords: 0,
    skippedRecords: 0,
    errors: [],
    warnings: [],
  }

  console.log(`${MIGRATION_LOG_PREFIX} Starting migration (DRY RUN: ${dryRun})`)
  console.log(`${MIGRATION_LOG_PREFIX} Timestamp: ${new Date().toISOString()}`)

  try {
    // Получаем все записи из старой системы
    const v1Supplies = await prisma.supply.findMany({
      include: {
        organization: true,
      },
      orderBy: {
        createdAt: 'asc',
      },
    })

    stats.totalV1Records = v1Supplies.length
    console.log(`${MIGRATION_LOG_PREFIX} Found ${stats.totalV1Records} V1 Supply records`)

    // Фильтруем только расходники фулфилмента
    const fulfillmentSupplies = v1Supplies.filter(supply => 
      supply.organization?.type === 'FULFILLMENT' && 
      supply.type === 'FULFILLMENT_CONSUMABLES'
    )

    stats.fulfillmentSupplies = fulfillmentSupplies.length
    console.log(`${MIGRATION_LOG_PREFIX} Found ${stats.fulfillmentSupplies} Fulfillment consumables to migrate`)

    if (stats.fulfillmentSupplies === 0) {
      console.log(`${MIGRATION_LOG_PREFIX} No fulfillment supplies to migrate`)
      return stats
    }

    // Создаем соответствующие Product записи для каждого Supply (если еще нет)
    const productMap = new Map<string, string>()
    
    for (const supply of fulfillmentSupplies) {
      try {
        const productId = await ensureProductExists(supply, dryRun)
        productMap.set(supply.id, productId)
      } catch (error) {
        const errorMsg = `Failed to create/find product for supply ${supply.id}: ${error}`
        stats.errors.push(errorMsg)
        console.error(`${MIGRATION_LOG_PREFIX} ERROR: ${errorMsg}`)
      }
    }

    console.log(`${MIGRATION_LOG_PREFIX} Created/verified ${productMap.size} products`)

    // Мигрируем каждую запись Supply → FulfillmentConsumableInventory
    for (const supply of fulfillmentSupplies) {
      try {
        const productId = productMap.get(supply.id)
        if (!productId) {
          stats.skippedRecords++
          continue
        }

        await migrateSupplyRecord(supply, productId, dryRun)
        stats.migratedRecords++

        // Логируем прогресс каждые 10 записей
        if (stats.migratedRecords % 10 === 0) {
          console.log(`${MIGRATION_LOG_PREFIX} Progress: ${stats.migratedRecords}/${fulfillmentSupplies.length}`)
        }

      } catch (error) {
        const errorMsg = `Failed to migrate supply ${supply.id}: ${error}`
        stats.errors.push(errorMsg)
        console.error(`${MIGRATION_LOG_PREFIX} ERROR: ${errorMsg}`)
        stats.skippedRecords++
      }
    }

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

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

  return stats
}

/**
 * Создает Product запись для Supply, если еще не существует
 */
async function ensureProductExists(supply: V1SupplyRecord, dryRun: boolean): Promise<string> {
  // Проверяем есть ли уже Product с таким названием и организацией
  const existingProduct = await prisma.product.findFirst({
    where: {
      organizationId: supply.organizationId,
      name: supply.name,
      type: 'CONSUMABLE',
    },
  })

  if (existingProduct) {
    return existingProduct.id
  }

  if (dryRun) {
    console.log(`${MIGRATION_LOG_PREFIX} [DRY RUN] Would create product: ${supply.name}`)
    return `mock-product-id-${supply.id}`
  }

  // Создаем новый Product на основе Supply данных
  const newProduct = await prisma.product.create({
    data: {
      name: supply.name,
      article: `MIGRATED-${supply.id.slice(-8)}`, // Уникальный артикул
      description: supply.description || `Мигрировано из V1 Supply ${supply.id}`,
      price: supply.price || 0,
      unit: supply.unit || 'шт',
      category: supply.category || 'Расходники',
      type: 'CONSUMABLE',
      organizationId: supply.organizationId,
      quantity: 0, // В Product quantity означает что-то другое
      imageUrl: null,
    },
  })

  console.log(`${MIGRATION_LOG_PREFIX} Created product: ${newProduct.name} (${newProduct.id})`)
  return newProduct.id
}

/**
 * Мигрирует одну запись Supply в FulfillmentConsumableInventory
 */
async function migrateSupplyRecord(supply: V1SupplyRecord, productId: string, dryRun: boolean): Promise<void> {
  if (dryRun) {
    console.log(`${MIGRATION_LOG_PREFIX} [DRY RUN] Would migrate: ${supply.name} (${supply.currentStock} units)`)
    return
  }

  // Проверяем не мигрировали ли уже эту запись
  const existingInventory = await prisma.fulfillmentConsumableInventory.findUnique({
    where: {
      fulfillmentCenterId_productId: {
        fulfillmentCenterId: supply.organizationId,
        productId: productId,
      },
    },
  })

  if (existingInventory) {
    console.log(`${MIGRATION_LOG_PREFIX} WARNING: Inventory already exists for ${supply.name}, skipping`)
    return
  }

  // Создаем запись в новой системе инвентаря
  const inventory = await prisma.fulfillmentConsumableInventory.create({
    data: {
      fulfillmentCenterId: supply.organizationId,
      productId: productId,
      
      // Складские данные из V1
      currentStock: supply.currentStock,
      minStock: supply.minStock,
      maxStock: null, // В V1 не было
      reservedStock: 0, // В V1 не было
      totalReceived: supply.quantity, // Приблизительно
      totalShipped: Math.max(0, supply.quantity - supply.currentStock), // Приблизительно
      
      // Цены
      averageCost: parseFloat(supply.price?.toString() || '0'),
      resalePrice: null, // В V1 не было
      
      // Метаданные
      lastSupplyDate: supply.date,
      lastUsageDate: null, // В V1 не было точной информации
      notes: `Мигрировано из V1 Supply ${supply.id} (${supply.status})`,
      
      // Временные метки сохраняем из V1
      createdAt: supply.createdAt,
      updatedAt: supply.updatedAt,
    },
  })

  console.log(`${MIGRATION_LOG_PREFIX} ✅ Migrated: ${supply.name} → ${inventory.id}`)
}

/**
 * Печатает детальный отчет о миграции
 */
function printMigrationReport(stats: MigrationStats, dryRun: boolean): void {
  console.log('\n' + '='.repeat(60))
  console.log(`${MIGRATION_LOG_PREFIX} MIGRATION REPORT`)
  console.log('='.repeat(60))
  console.log(`Mode: ${dryRun ? 'DRY RUN' : 'PRODUCTION'}`)
  console.log(`Timestamp: ${new Date().toISOString()}`)
  console.log('')
  console.log('📊 STATISTICS:')
  console.log(`  Total V1 records found: ${stats.totalV1Records}`)
  console.log(`  Fulfillment supplies: ${stats.fulfillmentSupplies}`)
  console.log(`  Successfully migrated: ${stats.migratedRecords}`)
  console.log(`  Skipped records: ${stats.skippedRecords}`)
  console.log(`  Errors encountered: ${stats.errors.length}`)
  console.log('')

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

  if (stats.warnings.length > 0) {
    console.log('⚠️ WARNINGS:')
    stats.warnings.forEach((warning, index) => {
      console.log(`  ${index + 1}. ${warning}`)
    })
    console.log('')
  }

  if (dryRun) {
    console.log('🔄 TO RUN ACTUAL MIGRATION:')
    console.log('  npm run migrate:v1-to-v2 --production')
  } else {
    console.log('✅ MIGRATION COMPLETED!')
    console.log('🔄 TO VERIFY RESULTS:')
    console.log('  Check FulfillmentConsumableInventory table')
    console.log('  Verify counts match expectations')
  }

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

/**
 * Функция отката миграции (осторожно!)
 */
async function rollbackMigration(): Promise<void> {
  console.log(`${MIGRATION_LOG_PREFIX} ⚠️ STARTING ROLLBACK`)
  
  // Удаляем все мигрированные записи
  const deleted = await prisma.fulfillmentConsumableInventory.deleteMany({
    where: {
      notes: {
        contains: 'Мигрировано из V1 Supply'
      }
    }
  })

  console.log(`${MIGRATION_LOG_PREFIX} 🗑️ Deleted ${deleted.count} migrated inventory records`)
  
  // Удаляем мигрированные Products (осторожно!)
  const deletedProducts = await prisma.product.deleteMany({
    where: {
      article: {
        startsWith: 'MIGRATED-'
      }
    }
  })

  console.log(`${MIGRATION_LOG_PREFIX} 🗑️ Deleted ${deletedProducts.count} migrated product records`)
  console.log(`${MIGRATION_LOG_PREFIX} ✅ Rollback completed`)
}

/**
 * CLI интерфейс
 */
async function main() {
  const args = process.argv.slice(2)
  const isProduction = args.includes('--production')
  const isRollback = args.includes('--rollback')

  if (isRollback) {
    if (!isProduction) {
      console.log('❌ Rollback requires --production flag for safety')
      process.exit(1)
    }
    
    console.log('⚠️ You are about to rollback the V1→V2 migration!')
    console.log('This will DELETE all migrated data!')
    console.log('Press Ctrl+C to cancel...')
    
    // Ждем 5 секунд
    await new Promise(resolve => setTimeout(resolve, 5000))
    
    await rollbackMigration()
    process.exit(0)
  }

  const dryRun = !isProduction
  
  if (dryRun) {
    console.log('🔍 Running in DRY RUN mode (no actual changes)')
    console.log('📝 Add --production flag to run actual migration')
  } 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 migrateV1ToV2Inventory(dryRun)
    
    if (stats.errors.length > 0) {
      console.error(`${MIGRATION_LOG_PREFIX} Migration completed with errors`)
      process.exit(1)
    }
    
    console.log(`${MIGRATION_LOG_PREFIX} Migration completed successfully`)
    process.exit(0)
    
  } catch (error) {
    console.error(`${MIGRATION_LOG_PREFIX} Migration failed:`, error)
    process.exit(1)
  } finally {
    await prisma.$disconnect()
  }
}

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

export { migrateV1ToV2Inventory, rollbackMigration }