package com.ffii.fpsms.modules.deliveryOrder.web

import com.ffii.fpsms.modules.deliveryOrder.service.TruckRoutingSummaryService
import com.ffii.fpsms.modules.master.print.A4PrintDriverRegistry
import com.ffii.fpsms.modules.master.service.PrinterService
import com.ffii.fpsms.modules.report.service.ReportService
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import java.io.File
import java.time.LocalDate
import java.time.format.DateTimeFormatter

@RestController
@RequestMapping("/truck-routing-summary")
class TruckRoutingSummaryController(
    private val truckRoutingSummaryService: TruckRoutingSummaryService,
    private val reportService: ReportService,
    private val printerService: PrinterService,
) {
    @GetMapping("/store-options")
    fun getStoreOptions(): List<Map<String, String>> =
        truckRoutingSummaryService.getStoreOptions()

    @GetMapping("/lane-options")
    fun getLaneOptions(
        @RequestParam(required = false) storeId: String?
    ): List<Map<String, String>> =
        truckRoutingSummaryService.getLaneOptions(storeId)

    @GetMapping("/precheck")
    fun precheck(
        @RequestParam(required = false) storeId: String?,
        @RequestParam(required = false) truckLanceCode: String?,
        @RequestParam(required = false) date: String?
    ): Map<String, Any> {
        val reportDate = if (date.isNullOrBlank()) {
            LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        } else {
            date
        }
        val unpickedCount = truckRoutingSummaryService.getUnpickedOrderCount(storeId, truckLanceCode, reportDate)
        return mapOf(
            "unpickedOrderCount" to unpickedCount,
            "hasUnpickedOrders" to (unpickedCount > 0),
        )
    }

    @GetMapping("/print")
    fun print(
        @RequestParam(required = false) storeId: String?,
        @RequestParam(required = false) truckLanceCode: String?,
        @RequestParam(required = false) date: String?
    ): ResponseEntity<ByteArray> {
        val pdfBytes = buildTruckRoutingSummaryPdf(storeId, truckLanceCode, date)

        val headers = HttpHeaders().apply {
            contentType = MediaType.APPLICATION_PDF
            setContentDispositionFormData("attachment", "TruckRoutingSummary.pdf")
            set("filename", "TruckRoutingSummary.pdf")
        }
        return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
    }

    @GetMapping("/print-direct")
    fun printDirect(
        @RequestParam printerId: Long,
        @RequestParam(required = false) printQty: Int?,
        @RequestParam(required = false) storeId: String?,
        @RequestParam(required = false) truckLanceCode: String?,
        @RequestParam(required = false) date: String?
    ): ResponseEntity<Void> {
        val printer = printerService.findById(printerId)
            ?: throw NoSuchElementException("No such printer")
        val pdfBytes = buildTruckRoutingSummaryPdf(storeId, truckLanceCode, date)
        val tempPdfFile = File.createTempFile("truck_routing_summary_", ".pdf")
        try {
            tempPdfFile.writeBytes(pdfBytes)
            val copies = if (printQty == null || printQty <= 0) 1 else printQty
            printer.ip?.let { ip ->
                val port = printer.port ?: 9100
                val driver = A4PrintDriverRegistry.getDriver(printer.brand)
                driver.print(tempPdfFile, ip, port, copies)
            }
        } finally {
            // keep temp files for now to match current project behavior
            // tempPdfFile.delete()
        }
        return ResponseEntity.ok().build()
    }

    private fun buildTruckRoutingSummaryPdf(
        storeId: String?,
        truckLanceCode: String?,
        date: String?
    ): ByteArray {
        val reportDate = if (date.isNullOrBlank()) {
            LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
        } else {
            date
        }
        val departureLabel = truckRoutingSummaryService.getDepartureTimeLabel(storeId, truckLanceCode)
        val lane = (truckLanceCode ?: "").trim()
        val params = mutableMapOf<String, Any>(
            "FLOOR_LABEL" to truckRoutingSummaryService.formatStoreIdForDisplay(storeId),
            "TRUCK_ROUTE" to lane,
            "DEPARTURE_TIME" to departureLabel,
            "REPORT_DATE" to reportDate,
        )
        val rows = truckRoutingSummaryService.search(storeId, truckLanceCode, reportDate)
        return reportService.createPdfResponse(
            "/DeliveryNote/TruckRoutingSummaryPDF.jrxml",
            params,
            rows
        )
    }
}
