package com.ffii.fpsms.modules.common.internalSetup

import com.ffii.core.utils.ExcelUtils
import org.apache.poi.ss.usermodel.Sheet
import org.apache.poi.ss.usermodel.Workbook
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.springframework.stereotype.Component
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.transaction.annotation.Transactional
import com.ffii.fpsms.modules.master.entity.Items
import com.ffii.fpsms.modules.master.entity.ItemsRepository
import java.io.File
import java.io.FileInputStream
import java.io.IOException

@Component
open class ItemsSetup {

    @Autowired
    private lateinit var itemsRepository: ItemsRepository

    data class ItemsData(
        val code: String,
        val type: String?,
        val store_id: String?,
        val warehouse: String?,
        val area: String?,
        val slot: String?
    )

    @Transactional(rollbackFor = [Exception::class])
    open fun importExcelFromLocal(filePath: String): Int {
        val file = File(filePath)
        if (!file.exists()) {
            throw IOException("File not found: $filePath")
        }

        FileInputStream(file).use { inputStream ->
            val workbook: Workbook = XSSFWorkbook(inputStream)

            try {
                val sheet: Sheet = workbook.getSheetAt(0)
                val itemsDataList = mutableListOf<ItemsData>()

                // Column indices
                val COLUMN_CODE_INDEX = 0        // Column A
                val COLUMN_TYPE_INDEX = 2        // Column C
                val COLUMN_STORE_ID_INDEX = 3    // Column D
                val COLUMN_WAREHOUSE_INDEX = 5   // Column F
                val COLUMN_AREA_INDEX = 6        // Column G
                val COLUMN_SLOT_INDEX = 7        // Column H

                val START_ROW_INDEX = 3  // Start from Excel row 4 (0-based: index 3)

                // ────────────────────────────────────────────────
                // Process data rows (starting from Excel row 4, index 3)
                // ────────────────────────────────────────────────
                for (rowIndex in START_ROW_INDEX..sheet.lastRowNum) {
                    val row = sheet.getRow(rowIndex) ?: continue

                    val code = ExcelUtils.getStringValue(row.getCell(COLUMN_CODE_INDEX))?.trim() ?: ""

                    // Skip if code is empty (required field)
                    if (code.isEmpty()) {
                        println("SKIP row ${rowIndex + 1} - Missing code")
                        continue
                    }

                    val type = ExcelUtils.getStringValue(row.getCell(COLUMN_TYPE_INDEX))?.trim()
                    val store_id = ExcelUtils.getStringValue(row.getCell(COLUMN_STORE_ID_INDEX))?.trim()
                    val warehouse = ExcelUtils.getStringValue(row.getCell(COLUMN_WAREHOUSE_INDEX))?.trim()
                    val area = ExcelUtils.getStringValue(row.getCell(COLUMN_AREA_INDEX))?.trim()
                    val slot = ExcelUtils.getStringValue(row.getCell(COLUMN_SLOT_INDEX))?.trim()

                    println("=== Processing row ${rowIndex + 1} (code: $code, type: $type) ===")

                    itemsDataList.add(
                        ItemsData(
                            code = code,
                            type = type,
                            store_id = store_id,
                            warehouse = warehouse,
                            area = area,
                            slot = slot
                        )
                    )
                }

                println("Total valid rows collected: ${itemsDataList.size}")

                // ────────────────────────────────────────────────
                // Update items
                // ────────────────────────────────────────────────
                var updatedCount = 0
                var notFoundCount = 0

                for (data in itemsDataList) {
                    try {
                        // Find item by code
                        val existingItem = itemsRepository.findByCodeAndDeletedFalse(data.code)

                        if (existingItem == null) {
                            println("NOT FOUND - Item with code '${data.code}' does not exist")
                            notFoundCount++
                            continue
                        }

                        // Generate LocationCode: store_id-warehouse-area-slot
                        val locationCode = if (data.store_id != null && data.warehouse != null &&
                            data.area != null && data.slot != null) {
                            "${data.store_id}-${data.warehouse}-${data.area}-${data.slot}"
                        } else {
                            null
                        }

                        // Update existing item
                        existingItem.apply {
                            if (data.type != null) {
                                this.type = data.type
                            }
                            if (data.store_id != null) {
                                this.store_id = data.store_id
                            }
                            if (data.warehouse != null) {
                                this.warehouse = data.warehouse
                            }
                            if (data.area != null) {
                                this.area = data.area
                            }
                            if (data.slot != null) {
                                this.slot = data.slot
                            }
                            if (locationCode != null) {
                                this.LocationCode = locationCode
                            }
                        }

                        itemsRepository.save(existingItem)
                        updatedCount++
                        println("UPDATED item: ${data.code} (LocationCode: $locationCode)")
                    } catch (e: Exception) {
                        println("Error processing item row (code: ${data.code}): ${e.message}")
                        continue
                    }
                }

                println("Import finished. Updated $updatedCount items, Not found: $notFoundCount items.")
                return updatedCount

            } finally {
                workbook.close()
            }
        }
    }
}