package com.ffii.fpsms.modules.master.service

import com.ffii.core.support.AbstractBaseEntityService
import com.ffii.core.support.JdbcDao
import com.ffii.core.utils.ExcelUtils
import com.ffii.core.utils.JwtTokenUtil
import com.ffii.fpsms.modules.master.entity.ItemsRepository
import com.ffii.fpsms.modules.master.entity.Warehouse
import com.ffii.fpsms.modules.master.entity.WarehouseRepository
import com.ffii.fpsms.modules.master.entity.projections.WarehouseCombo
import com.ffii.fpsms.modules.master.web.models.SaveWarehouseRequest
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderLineRepository
import com.ffii.fpsms.modules.stock.entity.InventoryLotRepository
import com.ffii.fpsms.modules.stock.entity.StockInLine
import com.ffii.fpsms.modules.stock.entity.StockInLineRepository
import com.ffii.fpsms.modules.stock.entity.StockInRepository
import com.ffii.fpsms.modules.stock.service.InventoryLotService
import com.ffii.fpsms.modules.stock.service.StockInService
import org.apache.poi.ss.usermodel.Sheet
import org.apache.poi.ss.usermodel.Workbook
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
import java.math.BigDecimal
import kotlin.jvm.optionals.getOrNull

@Service
open class WarehouseService(
    private val jdbcDao: JdbcDao,
    private val warehouseRepository: WarehouseRepository,
) : AbstractBaseEntityService<Warehouse, Long, WarehouseRepository>(jdbcDao, warehouseRepository) {
    open fun getWarehouses(): List<Warehouse> {
        return warehouseRepository.findAll().filter { it.deleted == false }
    }

    open fun findCombo(): List<WarehouseCombo> {
        return warehouseRepository.findWarehouseComboByDeletedFalse();
    }

    open fun findById(id: Long): Warehouse? {
        return warehouseRepository.findByIdAndDeletedIsFalse(id);
    }

    open fun findByCode(code: String): Warehouse? {
        return warehouseRepository.findByCodeAndDeletedIsFalse(code);
    }

    open fun saveWarehouse(request: SaveWarehouseRequest): Warehouse {
        val warehouse = request.id?.let { warehouseRepository.findById(it).getOrNull() } ?: Warehouse();

        warehouse.apply {
            code = request.code
            name = request.name
            description = request.description
            capacity = request.capacity
        };

        return warehouseRepository.save(warehouse);
    }

    open fun importExcel(workbook: Workbook?): String {
        logger.info("--------- Start - Import Warehouse Excel -------");

        if (workbook == null) {
            logger.error("No Excel Import");
            return "Import Excel failure";
        }
        val sheet: Sheet = workbook.getSheetAt(0);

        // Columns
        val COLUMN_WAREHOSE_INDEX = 1;
        val COLUMN_ZONE_INDEX = 2;
        val COLUMN_SLOT_INDEX = 3;
        val COLUMN_FLOOR_INDEX = 4;
        val COLUMN_PLACE_INDEX = 5;

        val START_ROW_INDEX = 1;

        // Start Import
        for (i in START_ROW_INDEX..<sheet.lastRowNum) {
            val row = sheet.getRow(i)

            try {
                val floor = ExcelUtils.getStringValue(row.getCell(COLUMN_FLOOR_INDEX)).trim()
                val place = ExcelUtils.getStringValue(row.getCell(COLUMN_PLACE_INDEX)).trim()
                val code = ExcelUtils.getStringValue(row.getCell(COLUMN_WAREHOSE_INDEX)).trim()
                val zone = ExcelUtils.getStringValue(row.getCell(COLUMN_ZONE_INDEX)).trim()
                val slot = ExcelUtils.getStringValue(row.getCell(COLUMN_SLOT_INDEX)).trim()
//                logger.info("Warehouse code - zone - slot: ${row.getCell(COLUMN_WAREHOSE_INDEX).cellType} - ${row.getCell(COLUMN_ZONE_INDEX).cellType} - ${row.getCell(COLUMN_SLOT_INDEX).cellType}")

                val defaultCapacity = BigDecimal(10000)
                val warehouseCode = "$code-$zone-$slot"
                val warehouseName = "$floor-$place"
                val existingWarehouse = findByCode(warehouseCode)

                if (existingWarehouse == null) {
                    val warehouseRequest = SaveWarehouseRequest(
                        code = warehouseCode,
                        name = warehouseName,
                        description = warehouseName,
                        capacity = defaultCapacity
                    )
                    saveWarehouse(warehouseRequest)
                }
            } catch (e: Exception) {
                logger.error("Import Error (Warehouse Error): ${e.message}")
            }
        }
        logger.info("--------- End - Import Warehouse Excel -------")
        return "Import Excel success";
    }
}