package com.ffii.fpsms.m18.web

import com.ffii.core.utils.JwtTokenUtil
import com.ffii.fpsms.m18.M18Config
import com.ffii.fpsms.m18.model.SyncResult
import com.ffii.fpsms.m18.service.*
import com.ffii.fpsms.m18.model.M18BomShopSyncTriggerResult
import com.ffii.fpsms.m18.web.models.M18CommonRequest
import com.ffii.fpsms.modules.master.service.BomService
import com.ffii.fpsms.modules.common.scheduler.service.SchedulerService
import com.ffii.fpsms.modules.master.entity.ItemUom
import com.ffii.fpsms.modules.master.entity.Items
import com.ffii.fpsms.modules.master.entity.ShopRepository
import com.ffii.fpsms.modules.master.enums.ShopType
import com.ffii.fpsms.modules.master.service.ItemUomService
import com.ffii.fpsms.modules.master.service.ItemsService
import com.ffii.fpsms.modules.master.service.ShopService
import com.ffii.fpsms.modules.settings.service.SettingsService
import jakarta.validation.Valid
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*


@RestController
@RequestMapping("/m18")
class M18TestController (
    private val shopRepository: ShopRepository,
    private val shopService: ShopService,
    private val itemsService: ItemsService,
    private val m18MasterDataService: M18MasterDataService,
    private val m18PurchaseOrderService: M18PurchaseOrderService,
    private val m18Config: M18Config,
    private val itemUomService: ItemUomService,
    private val m18PurchaseQuotationService: M18PurchaseQuotationService,
    private val m18DeliveryOrderService: M18DeliveryOrderService,
    val schedulerService: SchedulerService,
    private val settingsService: SettingsService,
    private val bomService: BomService,
) {
    var logger: Logger = LoggerFactory.getLogger(JwtTokenUtil::class.java)

    @GetMapping("/test1")
    fun test1(@RequestParam name: String, @RequestParam m18UomId: Long): Items? {
        val temp = itemsService.findByNameAndM18UomId(name, m18UomId)
        println(name)
        println(m18UomId)
        println(temp?.id)
        return temp
    }

    @GetMapping("/test2")
    fun test2(): List<Long>? {
        return shopRepository.findM18IdsByCodeRegexpAndTypeAndDeletedIsFalse("P06|P07", ShopType.SUPPLIER.value)
    }

    @GetMapping("/test3")
    fun test3(@RequestParam m18ItemId: Long): ItemUom? {
        val response = itemUomService.findPurchaseUnitByM18ItemId(m18ItemId)
        println(response?.item?.id)
        println(response?.uom?.id)
        return response
    }

    @GetMapping("/test4")
    fun test4(): Any {
        return schedulerService.getM18Pos();
    }

    @PostMapping("/test/bom-shop-sync/{bomId}")
    fun testBomShopSync(
        @PathVariable bomId: Long,
        @RequestParam(required = false) m18HeaderId: Long?,
    ): M18BomShopSyncTriggerResult {
        return bomService.pushBomToM18ShopIfAllowed(bomId, m18HeaderId)
    }

    @GetMapping("/test/po-by-code")
    fun testSyncPoByCode(@RequestParam code: String): SyncResult {
        return m18PurchaseOrderService.savePurchaseOrderByCode(code)
    }

    @GetMapping("/test/do-by-code")
    fun testSyncDoByCode(@RequestParam code: String): SyncResult {
        return m18DeliveryOrderService.saveDeliveryOrderByCode(code, isExtraSync = false)
    }

    /** DO（加單）：手動按 code 同步，並寫入本地 [DeliveryOrder.isExtra]=true（不做 M18 端加單條件過濾） */
    @GetMapping("/test/do-by-code-extra")
    fun testSyncDoByCodeExtra(@RequestParam code: String): SyncResult {
        // 加單 tab: only sync when it's a NEW order (not existing in local system)
        return m18DeliveryOrderService.saveDeliveryOrderByCode(code, isExtraSync = true, newOnly = true)
    }

    @GetMapping("/test/product-by-code")
    fun testSyncProductByCode(@RequestParam code: String): SyncResult {
        return m18MasterDataService.saveProductByCode(code)
    }
    // --------------------------------------------- Scheduler --------------------------------------------- ///
//    @GetMapping("/schedule/po")
//    fun schedulePo(@RequestParam @Valid newCron: String) {
//        settingsService.update(SettingNames.SCHEDULE_M18_PO, newCron);
//        schedulerService.scheduleM18PoTask()
//    }

    // --------------------------------------------- Master Data --------------------------------------------- ///
    @GetMapping("/all")
    fun m18All() {
        val mdRequest = M18CommonRequest()
        // Master Data
        m18MasterDataService.saveUnits(mdRequest)
        m18MasterDataService.saveProducts(mdRequest)
        m18MasterDataService.resyncProblemItemUomsFromM18()
        m18MasterDataService.saveVendors(mdRequest)
        m18MasterDataService.saveBusinessUnits(mdRequest)
        m18MasterDataService.saveCurrencies(mdRequest)
        m18MasterDataService.saveBoms(mdRequest)

        val pqRequest = M18CommonRequest()
        m18PurchaseQuotationService.savePurchaseQuotations(pqRequest)
    }

    // --------------------------------------------- Master Data --------------------------------------------- ///
    @PostMapping("/master-data")
    fun m18MasterData(@Valid @RequestBody request: M18CommonRequest) {
        // Master Data
        m18MasterDataService.ensureCunitSeededForAllIfEmpty()
        m18MasterDataService.saveUnits(request)
        m18MasterDataService.saveProducts(request)
        m18MasterDataService.resyncProblemItemUomsFromM18()
        m18MasterDataService.saveVendors(request)
        m18MasterDataService.saveBusinessUnits(request)
        m18MasterDataService.saveCurrencies(request)
//        m18MasterDataService.saveBoms(request)
    }

    @PostMapping("/product")
    fun m18Products(@Valid @RequestBody request: M18CommonRequest) {
        logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18MasterDataService.saveProducts(request)
    }

    @GetMapping("/product/{id}")
    fun m18Product(@PathVariable id: Long) {
        //logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18MasterDataService.saveProduct(id)
    }

    @PostMapping("/vendor")
    fun m18Vendor(@Valid @RequestBody request: M18CommonRequest) {
        //logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18MasterDataService.saveVendors(request)
    }

    @PostMapping("/unit")
    fun m18Unit(@Valid @RequestBody request: M18CommonRequest) {
        //logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18MasterDataService.saveUnits(request)
    }

    @PostMapping("/currency")
    fun m18Currency(@Valid @RequestBody request: M18CommonRequest) {
        //logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18MasterDataService.saveCurrencies(request)
    }

    @PostMapping("/bom")
    fun m18Bom(@Valid @RequestBody request: M18CommonRequest) {
        //logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18MasterDataService.saveBoms(request)
    }

    @PostMapping("/businessUnit")
    fun m18BusinessUnit(@Valid @RequestBody request: M18CommonRequest) {
        //logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18MasterDataService.saveBusinessUnits(request)
    }

    // --------------------------------------------- Purchase Order --------------------------------------------- ///
    @PostMapping("/po")
    fun m18PO(@Valid @RequestBody request: M18CommonRequest) {
        //logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18PurchaseOrderService.savePurchaseOrders(request)
    }

    // --------------------------------------------- Delivery Order --------------------------------------------- ///
    @PostMapping("/do")
    fun m18DO(@Valid @RequestBody request: M18CommonRequest) {
        //logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18DeliveryOrderService.saveDeliveryOrders(request)
    }

    // --------------------------------------------- Purchase Quotation --------------------------------------------- ///
    @PostMapping("/pq")
    fun m18PQ(@Valid @RequestBody request: M18CommonRequest) {
        logger.info("Access token: ${m18Config.ACCESS_TOKEN}")
        m18PurchaseQuotationService.savePurchaseQuotations(request)
    }
}