package com.ffii.fpsms.modules.stock.web

import com.ffii.fpsms.modules.master.web.models.MessageResponse
import com.ffii.fpsms.modules.qc.entity.projection.QcResultInfo
import com.ffii.fpsms.modules.stock.entity.StockInLine
import com.ffii.fpsms.modules.stock.entity.projection.StockInLineInfo
import com.ffii.fpsms.modules.stock.service.StockInLineService
import com.ffii.fpsms.modules.stock.web.model.ExportQrCodeRequest
import com.ffii.fpsms.modules.stock.web.model.PurchaseStockInAlertRow
import com.ffii.fpsms.modules.stock.web.model.PrintQrCodeForSilRequest
import com.ffii.fpsms.modules.stock.web.model.SaveStockInLineRequest
import jakarta.servlet.http.HttpServletResponse
import jakarta.validation.Valid
import net.sf.jasperreports.engine.JasperExportManager
import net.sf.jasperreports.engine.JasperPrint
import org.springframework.context.NoSuchMessageException
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.io.OutputStream
import java.io.UnsupportedEncodingException
import java.text.ParseException


@RestController
@RequestMapping("/stockInLine")
class StockInLineController(
    private val stockInLineService: StockInLineService
) {
    /** Count of recent PO stock-in lines in pending / receiving (same filter as [listPurchaseStockInAlerts]). */
    @GetMapping("/alerts/purchase-incomplete-count")
    fun getPurchaseStockInIncompleteCount(
        @RequestParam(name = "days", required = false) days: Int?,
    ): Map<String, Long> {
        val since = stockInLineService.purchaseStockInAlertSinceDays(days)
        return mapOf("count" to stockInLineService.countPurchaseStockInAlertsSince(since))
    }

    /** Actionable list: recent PO stock-in lines in pending / receiving (deep-link to PO edit). */
    @GetMapping("/alerts/purchase-incomplete")
    fun listPurchaseStockInAlerts(
        @RequestParam(name = "days", required = false) days: Int?,
        @RequestParam(name = "limit", defaultValue = "50") limit: Int,
    ): List<PurchaseStockInAlertRow> {
        val since = stockInLineService.purchaseStockInAlertSinceDays(days)
        return stockInLineService.listPurchaseStockInAlerts(since, limit)
    }

    @GetMapping("/{stockInLineId}")
    fun get(@PathVariable stockInLineId: Long): StockInLineInfo {
        return stockInLineService.getStockInLineInfo(stockInLineId)
    }
    @GetMapping("/received/{stockInLineId}")
    fun getReceived(@PathVariable stockInLineId: Long): StockInLineInfo {
        return stockInLineService.getStockInLineInfo(stockInLineId)
    }
    @PostMapping("/create")
    fun create(@Valid @RequestBody newItem: SaveStockInLineRequest): MessageResponse {
        return stockInLineService.create(newItem)
    }

    @PostMapping("/update")
    fun update(@Valid @RequestBody newItem: SaveStockInLineRequest): MessageResponse {
        return stockInLineService.update(newItem)
    }

    @PostMapping("/delete/{stockInLineId}")
    fun delete(@PathVariable stockInLineId: Long): MessageResponse {
        return stockInLineService.softDelete(stockInLineId)
    }

    @PostMapping("/download-label")
    @Throws(UnsupportedEncodingException::class, NoSuchMessageException::class, ParseException::class, Exception::class)
    fun printLabel(@Valid @RequestBody request: ExportQrCodeRequest, response: HttpServletResponse) {
        response.characterEncoding = "utf-8";
        response.contentType = "application/pdf";
        val out: OutputStream = response.outputStream
        val pdf = stockInLineService.exportStockInLineQrcode(request)
        val jasperPrint = pdf["report"] as JasperPrint
        response.addHeader("filename", "${pdf["fileName"]}.pdf")
        out.write(JasperExportManager.exportReportToPdf(jasperPrint));
    }

    @GetMapping("/print-label")
    fun printQrCode(@ModelAttribute request: PrintQrCodeForSilRequest) {
        stockInLineService.printQrCode(request)
    }
}