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.Warehouse
import com.ffii.fpsms.modules.master.entity.WarehouseRepository
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.math.BigDecimal

@Component
open class WarehouseSetup {

    @Autowired
    private lateinit var warehouseRepository: WarehouseRepository

    data class WarehouseData(
        val store_id: String,
        val warehouse: String,
        val area: String,
        val slot: String,
        val order: String?,
        val stockTakeSection: String?,
        val stockTakeSectionDescription: 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 warehouseDataList = mutableListOf<WarehouseData>()

                // Column indices
                val COLUMN_STORE_ID_INDEX = 1        // Column B
                val COLUMN_WAREHOUSE_INDEX = 2        // Column C
                val COLUMN_AREA_INDEX = 3            // Column D
                val COLUMN_SLOT_INDEX = 4            // Column E
                val COLUMN_ORDER_INDEX = 5           // Column F
                val COLUMN_STOCK_TAKE_SECTION_INDEX = 6 // Column G
                val COLUMN_STOCK_TAKE_SECTION_DESCRIPTION_INDEX = 7 // Column H

                val START_ROW_INDEX = 8  // Start from Excel row 9 (0-based: index 8)

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

                    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() ?: ""

                    // Skip if required fields are empty
                    if (store_id.isEmpty() || warehouse.isEmpty() || area.isEmpty() || slot.isEmpty()) {
                        println("SKIP row ${rowIndex + 1} - Missing required fields (store_id, warehouse, area, or slot)")
                        continue
                    }

                    val order = ExcelUtils.getStringValue(row.getCell(COLUMN_ORDER_INDEX))?.trim()

                    val stockTakeSection = ExcelUtils.getStringValue(row.getCell(COLUMN_STOCK_TAKE_SECTION_INDEX))?.trim()
                    val stockTakeSectionDescription = ExcelUtils.getStringValue(row.getCell(COLUMN_STOCK_TAKE_SECTION_DESCRIPTION_INDEX))?.trim()

                    println("=== Processing row ${rowIndex + 1} (store_id: $store_id, warehouse: $warehouse, area: $area, slot: $slot) ===")

                    warehouseDataList.add(
                        WarehouseData(
                            store_id = store_id,
                            warehouse = warehouse,
                            area = area,
                            slot = slot,
                            order = order,
                            stockTakeSection = stockTakeSection,
                            stockTakeSectionDescription = stockTakeSectionDescription
                        )
                    )
                }

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

                // ────────────────────────────────────────────────
                // Create warehouses
                // ────────────────────────────────────────────────
                var createdCount = 0
                var updatedCount = 0

                for (data in warehouseDataList) {
                    try {
                        // Generate code: store_id-warehouse-area-slot
                        val code = "${data.store_id}-${data.warehouse}-${data.area}-${data.slot}"

                        // Generate name and description (using store_id-warehouse)
                        val name = "${data.store_id}-${data.warehouse}"
                        val description = name

                        // Capacity is always 10000.00
                        val capacity = BigDecimal("10000.00")

                        // Check if warehouse exists by code
                        val existingWarehouse = warehouseRepository.findByCodeAndDeletedIsFalse(code)

                        if (existingWarehouse != null) {
                            // Update existing warehouse
                            existingWarehouse.apply {
                                this.code = code
                                this.name = name
                                this.description = description
                                this.store_id = data.store_id
                                this.warehouse = data.warehouse
                                this.area = data.area
                                this.slot = data.slot
                                this.capacity = capacity
                                this.order = data.order
                                if (data.stockTakeSection != null) {
                                    this.stockTakeSection = data.stockTakeSection
                                }
                                if (data.stockTakeSectionDescription != null) {
                                    this.stockTakeSectionDescription = data.stockTakeSectionDescription
                                }
                            }
                            warehouseRepository.save(existingWarehouse)
                            updatedCount++
                            println("UPDATED warehouse: $code (order: ${data.order ?: "not set"})")
                        } else {
                            // Create new warehouse
                            val newWarehouse = Warehouse().apply {
                                this.code = code
                                this.name = name
                                this.description = description
                                this.capacity = capacity
                                this.store_id = data.store_id
                                this.warehouse = data.warehouse
                                this.area = data.area
                                this.slot = data.slot
                                this.order = data.order ?: ""
                                if (data.stockTakeSection != null) {
                                    this.stockTakeSection = data.stockTakeSection
                                }
                                if (data.stockTakeSectionDescription != null) {
                                    this.stockTakeSectionDescription = data.stockTakeSectionDescription
                                }
                            }
                            warehouseRepository.save(newWarehouse)
                            createdCount++
                            println("CREATED warehouse: $code (order: ${data.order ?: ""})")
                        }
                    } catch (e: Exception) {
                        println("Error processing warehouse row: ${e.message}")
                        continue
                    }
                }

                println("Import finished. Created $createdCount new warehouses, Updated $updatedCount warehouses.")
                return createdCount

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