package com.ffii.fpsms.modules.report.web

import net.sf.jasperreports.engine.*
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
import org.springframework.http.*
import org.springframework.web.bind.annotation.*
import java.io.InputStream
import java.time.LocalDate
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import com.ffii.fpsms.modules.report.service.ReportService

@RestController
@RequestMapping("/report")
class ReportController(
     private val reportService: ReportService,
) {

    @GetMapping("/print-report1")
    fun generateReport1(
        @RequestParam fromDate: String,
        @RequestParam toDate: String,
        //this is an exampe of optional param
        @RequestParam(required = false) itemType: String?
    ): ResponseEntity<ByteArray> {
        val parameters = mutableMapOf<String, Any>()
        parameters["fromDate"] = fromDate
        parameters["toDate"] = toDate
        // you may put more params to show
        parameters["param1"] = "param1Value"
        parameters["param2"] = "param2Value"

        // Query the DB to get a list of data
        val dbData = reportService.searchReport1(fromDate, toDate, itemType)

        val pdfBytes = reportService.createPdfResponse(
            "/jasper/report1.jrxml", 
            parameters, 
            dbData
        )

        val headers = HttpHeaders().apply {
            contentType = MediaType.APPLICATION_PDF
            setContentDispositionFormData("attachment", "Report1.pdf")
            set("filename", "Report1.pdf") 
        }

        return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
    }

    @GetMapping("/print-report3")
    fun generateReport3(
        //@RequestParam fromDate: String,
       // @RequestParam toDate: String,
        //this is an exampe of optional param
        @RequestParam(required = false) itemType: String?
    ): ResponseEntity<ByteArray> {
        val parameters = mutableMapOf<String, Any>()
        //parameters["lastInDateStart"] = fromDate
        //parameters["lastInDateEnd"] = toDate
        // you may put more params to show
        parameters["lastOutDateStart"] = "param1Value"
        parameters["lastOutDateEnd"] = "param2Value"

        // Query the DB to get a list of data
        val dbData = reportService.searchReport3(itemType)

        val pdfBytes = reportService.createPdfResponse(
            "/jasper/StockBalanceReport.jrxml", 
            parameters, 
            dbData
        )

        val headers = HttpHeaders().apply {
            contentType = MediaType.APPLICATION_PDF
            setContentDispositionFormData("attachment", "Report1.pdf")
            set("filename", "Report1.pdf") 
        }

        return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
    }

    @GetMapping("/print-stock-in-traceability")
    fun generateStockInTraceabilityReport(
        @RequestParam(required = false) stockCategory: String?,
        @RequestParam(required = false) itemCode: String?,
        @RequestParam(required = false) lastInDateStart: String?,
        @RequestParam(required = false) lastInDateEnd: String?
    ): ResponseEntity<ByteArray> {
        val parameters = mutableMapOf<String, Any>()
        
        // Set report header parameters
        parameters["itemNo"] = itemCode ?: "All"
        parameters["reportDate"] = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        parameters["reportTime"] = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))
        parameters["lastInDateStart"] = lastInDateStart ?: ""
        parameters["lastInDateEnd"] = lastInDateEnd ?: ""

        // Query the DB to get a list of data
        val dbData = reportService.searchStockInTraceabilityReport(
            stockCategory,
            itemCode,
            lastInDateStart,
            lastInDateEnd
        )

        val pdfBytes = reportService.createPdfResponse(
            "/jasper/StockInTraceabilityReport.jrxml", 
            parameters, 
            dbData
        )

        val headers = HttpHeaders().apply {
            contentType = MediaType.APPLICATION_PDF
            setContentDispositionFormData("attachment", "StockInTraceabilityReport.pdf")
            set("filename", "StockInTraceabilityReport.pdf") 
        }

        return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
    }
    @GetMapping("/print-fg-delivery-report")
    fun generateFGDeliveryReport(
        @RequestParam(required = false) stockCategory: String?,
        @RequestParam(required = false) stockSubCategory: String?,
        @RequestParam(required = false) itemCode: String?,
        @RequestParam(required = false) year: String?,
        @RequestParam(required = false) lastOutDateStart: String?,
        @RequestParam(required = false) lastOutDateEnd: String?
    ): ResponseEntity<ByteArray> {
        val parameters = mutableMapOf<String, Any>()
        
        // 设置报表头部参数
        parameters["stockCategory"] = stockCategory ?: "All"
        parameters["stockSubCategory"] = stockSubCategory ?: "All"
        parameters["itemNo"] = itemCode ?: "All"
        parameters["year"] = year ?: LocalDate.now().year.toString()
        parameters["reportDate"] = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        parameters["reportTime"] = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))
        parameters["lastOutDateStart"] = lastOutDateStart ?: ""
        parameters["lastOutDateEnd"] = lastOutDateEnd ?: ""
        parameters["deliveryPeriodStart"] = ""
        parameters["deliveryPeriodEnd"] = ""
    
        val dbData = reportService.searchFGDeliveryReport(
            stockCategory, 
            stockSubCategory, 
            itemCode, 
            year, 
            lastOutDateStart, 
            lastOutDateEnd
        )
    
        val pdfBytes = reportService.createPdfResponse(
            "/jasper/FGDeliveryReport.jrxml", 
            parameters, 
            dbData
        )
    
        val headers = HttpHeaders().apply {
            contentType = MediaType.APPLICATION_PDF
            setContentDispositionFormData("attachment", "FGDeliveryReport.pdf")
            set("filename", "FGDeliveryReport.pdf") 
        }
    
        return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
    }
    @GetMapping("/fg-stock-out-traceability-handlers")
    fun getFGStockOutTraceabilityHandlers(): List<String> =
        reportService.getDistinctHandlersForFGStockOutTraceability()

    @GetMapping("/material-stock-out-traceability-handlers")
    fun getMaterialStockOutTraceabilityHandlers(): List<String> =
        reportService.getDistinctHandlersForMaterialStockOutTraceability()

    @GetMapping("/print-fg-stock-out-traceability")
    fun generateFGStockOutTraceabilityReport(
        @RequestParam(required = false) stockCategory: String?,
        @RequestParam(required = false) stockSubCategory: String?,
        @RequestParam(required = false) itemCode: String?,
        @RequestParam(required = false) year: String?,
        @RequestParam(required = false) lastOutDateStart: String?,
        @RequestParam(required = false) lastOutDateEnd: String?,
        @RequestParam(required = false) handler: String?
    ): ResponseEntity<ByteArray> {
        val parameters = mutableMapOf<String, Any>()
        
        // Set report header parameters
        parameters["stockCategory"] = stockCategory ?: "All"
        parameters["stockSubCategory"] = stockSubCategory ?: "All"
        parameters["itemNo"] = itemCode ?: "All"
        parameters["year"] = year ?: LocalDate.now().year.toString()
        parameters["reportDate"] = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        parameters["reportTime"] = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))
        parameters["lastOutDateStart"] = lastOutDateStart ?: ""
        parameters["lastOutDateEnd"] = lastOutDateEnd ?: ""
        parameters["deliveryPeriodStart"] = ""
        parameters["deliveryPeriodEnd"] = ""
    
        val dbData = reportService.searchFGStockOutTraceabilityReport(
            stockCategory, 
            stockSubCategory, 
            itemCode, 
            year, 
            lastOutDateStart, 
            lastOutDateEnd,
            handler
        )
    
        val pdfBytes = reportService.createPdfResponse(
            "/jasper/FGStockOutTraceabilityReport.jrxml", 
            parameters, 
            dbData
        )
    
        val headers = HttpHeaders().apply {
            contentType = MediaType.APPLICATION_PDF
            setContentDispositionFormData("attachment", "FGStockOutTraceabilityReport.pdf")
            set("filename", "FGStockOutTraceabilityReport.pdf") 
        }
    
        return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
    }
    @GetMapping("/print-material-stock-out-traceability")
    fun generateMaterialStockOutTraceabilityReport(
        @RequestParam(required = false) stockCategory: String?,
        @RequestParam(required = false) stockSubCategory: String?,
        @RequestParam(required = false) itemCode: String?,
        @RequestParam(required = false) year: String?,
        @RequestParam(required = false) lastOutDateStart: String?,
        @RequestParam(required = false) lastOutDateEnd: String?,
        @RequestParam(required = false) handler: String?
    ): ResponseEntity<ByteArray> {
        val parameters = mutableMapOf<String, Any>()
        
        // Set report header parameters
        parameters["stockCategory"] = stockCategory ?: "All"
        parameters["stockSubCategory"] = stockSubCategory ?: "All"
        parameters["itemNo"] = itemCode ?: "All"
        parameters["year"] = year ?: LocalDate.now().year.toString()
        parameters["reportDate"] = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        parameters["reportTime"] = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))
        parameters["lastOutDateStart"] = lastOutDateStart ?: ""
        parameters["lastOutDateEnd"] = lastOutDateEnd ?: ""
        parameters["deliveryPeriodStart"] = ""
        parameters["deliveryPeriodEnd"] = ""
    
        val dbData = reportService.searchMaterialStockOutTraceabilityReport(
            stockCategory, 
            stockSubCategory, 
            itemCode, 
            year, 
            lastOutDateStart, 
            lastOutDateEnd,
            handler
        )
    
        val pdfBytes = reportService.createPdfResponse(
            "/jasper/MaterialStockOutTraceability.jrxml", 
            parameters, 
            dbData
        )
    
        val headers = HttpHeaders().apply {
            contentType = MediaType.APPLICATION_PDF
            setContentDispositionFormData("attachment", "MaterialStockOutTraceabilityReport.pdf")
            set("filename", "MaterialStockOutTraceabilityReport.pdf") 
        }
    
        return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
    }
    @GetMapping("/print-stock-balance")
    fun generateStockBalanceReport(
        @RequestParam(required = false) stockCategory: String?,
        @RequestParam(required = false) itemCode: String?,
        @RequestParam(required = false) balanceFilterStart: String?,
        @RequestParam(required = false) balanceFilterEnd: String?,
        @RequestParam(required = false) storeLocation: String?,
        @RequestParam(required = false) lastInDateStart: String?,
        @RequestParam(required = false) lastInDateEnd: String?,
        @RequestParam(required = false) lastOutDateStart: String?,
        @RequestParam(required = false) lastOutDateEnd: String?
    ): ResponseEntity<ByteArray> {
        val parameters = mutableMapOf<String, Any>()
        parameters["stockCategory"] = stockCategory ?: "All"
        parameters["itemNo"] = itemCode ?: "All"
        parameters["reportDate"] = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        parameters["reportTime"] = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))
        parameters["storeLocation"] = storeLocation ?: ""
        parameters["balanceFilterStart"] = balanceFilterStart ?: ""
        parameters["balanceFilterEnd"] = balanceFilterEnd ?: ""
        parameters["lastInDateStart"] = lastInDateStart ?: ""
        parameters["lastInDateEnd"] = lastInDateEnd ?: ""
        parameters["lastOutDateStart"] = lastOutDateStart ?: ""
        parameters["lastOutDateEnd"] = lastOutDateEnd ?: ""

        val dbData = reportService.searchStockBalanceReport(
            stockCategory,
            itemCode,
            balanceFilterStart,
            balanceFilterEnd,
            storeLocation,
            lastInDateStart,
            lastInDateEnd,
            lastOutDateStart,
            lastOutDateEnd
        )

        val pdfBytes = reportService.createPdfResponse(
            "/jasper/StockBalanceReport.jrxml",
            parameters,
            dbData
        )

        val headers = HttpHeaders().apply {
            contentType = MediaType.APPLICATION_PDF
            setContentDispositionFormData("attachment", "StockBalanceReport.pdf")
            set("filename", "StockBalanceReport.pdf")
        }

        return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
    }

}