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

import com.ffii.fpsms.modules.master.entity.Shop
import com.ffii.fpsms.modules.master.entity.ShopRepository
import com.ffii.fpsms.modules.master.entity.projections.ShopAndTruck
import com.ffii.fpsms.modules.master.entity.projections.ShopCombo
import com.ffii.fpsms.modules.master.enums.ShopType
import com.ffii.fpsms.modules.master.web.models.SaveShopRequest
import com.ffii.fpsms.modules.master.web.models.SaveShopResponse
import org.springframework.stereotype.Service
import kotlin.jvm.optionals.getOrDefault

@Service
open class ShopService(
    val shopRepository: ShopRepository
) {
    open fun findAll(): List<Shop> {
        return shopRepository.findAllByDeletedIsFalse()
    }

    open fun findById(id: Long): Shop? {
        return shopRepository.findByIdAndDeletedIsFalse(id)
    }

    open fun findVendorByM18Id(m18Id: Long): Shop? {
        return shopRepository.findByM18IdAndTypeAndDeletedIsFalse(m18Id, ShopType.SUPPLIER)
    }

    open fun findShopByM18Id(m18Id: Long): Shop? {
        return shopRepository.findByM18IdAndTypeAndDeletedIsFalse(m18Id, ShopType.SHOP)
    }

    open fun findM18VendorIdsByCodeRegexp(code: List<String>): List<Long>? {
        val codeRegexp = code.joinToString("|")
        return shopRepository.findM18IdsByCodeRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value)
    }

    open fun findM18VendorIdsByCodeNotRegexp(code: List<String>): List<Long>? {
        val codeRegexp = code.joinToString("|")
        return shopRepository.findM18IdsByCodeNotRegexpAndTypeAndDeletedIsFalse(codeRegexp, type = ShopType.SUPPLIER.value)
    }

    open fun findSupplierCombo(): List<ShopCombo> {
        return shopRepository.findShopComboByTypeAndDeletedIsFalse(ShopType.SUPPLIER)
    }

    open fun findShopCombo(): List<ShopCombo> {
        return shopRepository.findShopComboByTypeAndDeletedIsFalse(ShopType.SHOP)
    }

    open fun findAllByTypeAndDeletedIsFalse(): List<ShopAndTruck>?{
        return shopRepository.findAllByTypeAndDeletedIsFalse()
    }
    open fun saveShop(request: SaveShopRequest): SaveShopResponse {
        val shop = if (request.m18Id != null) {
            when (request.type){
                "supplier" -> findVendorByM18Id(request.m18Id) ?: Shop()
                "shop" -> findShopByM18Id(request.m18Id) ?: Shop()
                else -> Shop();
            }
        } else {
            request.id?.let { shopRepository.findById(it).getOrDefault(Shop()) } ?: Shop()
        }
        // TODO: May need later
//        if (shop?.m18LastModifyDate == request.m18LastModifyDate) {
//            return shop.let {
//                SaveShopResponse(
//                    id = it?.id,
//                    code = it?.code,
//                    name = it?.name,
//                )
//            }
//        }

        val type = request.type?.let { type -> ShopType.entries.find { it.value == type } }

        shop?.apply {
            code = request.code
            name = request.name
            brNo = request.brNo
            contactNo = request.contactNo
            contactEmail = request.contactEmail
            contactName = request.contactName
            addr1 = request.addr1
            addr2 = request.addr2
            addr3 = request.addr3
            addr4 = request.addr4
            district = request.district
            this.type = type
            m18Id = request.m18Id ?: this.m18Id
            m18LastModifyDate = request.m18LastModifyDate ?: this.m18LastModifyDate
        }

        val response = shopRepository.saveAndFlush(shop).let {
            SaveShopResponse(
                id = it?.id,
                code = it?.code,
                name = it?.name,
            )
        }

        return response
    }
}