package com.ffii.fpsms.modules.master.web

import com.ffii.fpsms.modules.master.entity.Bom
import com.ffii.fpsms.modules.master.entity.BomRepository
import com.ffii.fpsms.modules.master.enums.BomStatus
import com.ffii.fpsms.modules.master.entity.projections.BomCombo
import com.ffii.fpsms.modules.master.service.BomService
import org.springframework.core.io.ByteArrayResource
import org.springframework.core.io.Resource
import org.springframework.http.HttpHeaders
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import org.springframework.web.multipart.MultipartHttpServletRequest
import org.slf4j.LoggerFactory
import java.time.LocalDate
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.Part
import com.ffii.fpsms.modules.master.web.models.BomFormatCheckResponse
import com.ffii.fpsms.modules.master.web.models.BomUploadResponse
import com.ffii.fpsms.modules.master.web.models.BomFormatCheckRequest
import com.ffii.fpsms.modules.master.web.models.ImportBomRequestPayload
import com.ffii.fpsms.modules.master.web.models.BomDetailResponse
import com.ffii.fpsms.modules.master.web.models.EditBomRequest
import com.ffii.fpsms.modules.master.web.models.BomExcelCheckProgress
import com.ffii.fpsms.modules.master.web.models.BomIdByItemCodeResponse
import com.ffii.fpsms.modules.master.web.models.MasterDataIssueResponse
import com.ffii.fpsms.modules.master.service.MasterDataIssueService
import com.ffii.core.exception.BadRequestException
import java.util.logging.Logger
import java.nio.file.Files
import org.springframework.core.io.FileSystemResource

@RestController
@RequestMapping("/bom")
class BomController (
    val bomService: BomService,
    private val bomRepository: BomRepository,
    private val masterDataIssueService: MasterDataIssueService,
) {
    private val log = LoggerFactory.getLogger(BomController::class.java)

    @PostMapping("/import-bom/upload")
    fun uploadBomFiles(request: HttpServletRequest): BomUploadResponse {

       val multipartRequest = request as? MultipartHttpServletRequest
        if (multipartRequest != null) {
            val files = multipartRequest.getFiles("files").toList().filterNot { it.isEmpty }
            if (files.isNotEmpty()) {
                log.info("import-bom/upload: using getFiles(\"files\"), count={}", files.size)
                return bomService.uploadBomFiles(files)
            }
                    // 先嘗試 Spring 包裝的 MultipartHttpServletRequest（與其他 Controller 一致）
            log.info("import-bom/upload: received files count={}", files.size)
            files.forEachIndexed { i, f ->
                log.info("import-bom/upload: file[{}] originalFilename={}", i, f.originalFilename)
            }
        }
        // 否則用 Servlet getParts()（Postman 等可能不會被包裝成 MultipartHttpServletRequest）
        val allParts = try {
            request.parts
        } catch (e: Exception) {
            log.info("import-bom/upload: request.parts failed, content-type may not be multipart: {}", e.message)
            return BomUploadResponse(batchId = "", fileNames = emptyList())
        }
        val parts = allParts.filter { it.name == "files" }
        if (parts.isEmpty()) {
            log.info("import-bom/upload: no parts with name \"files\". All part names: {}", allParts.map { it.name })
            return BomUploadResponse(batchId = "", fileNames = emptyList())
        }
        log.info("import-bom/upload: using getParts(), count={}", parts.size)
        return bomService.uploadBomFilesFromParts(parts)
    }
    @GetMapping("/import-bom/format-issue-log")
fun downloadBomFormatIssueLog(
    @RequestParam batchId: String,
    @RequestParam issueLogFileId: String
): ResponseEntity<Resource> {
    val path = bomService.loadBomFormatIssueLog(batchId, issueLogFileId)
        ?: return ResponseEntity.notFound().build()

    val resource: Resource = FileSystemResource(path.toFile())
    return ResponseEntity.ok()
        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"bom_format_issue.xlsx\"")
        .body(resource)
}
    @PostMapping("/import-bom/format-check")
    fun checkBomFormat(@RequestBody request: BomFormatCheckRequest): BomFormatCheckResponse {
        return bomService.checkBomExcelFormat(request.batchId)
    }
    /*
    @GetMapping("/import-bom/format-check/progress")
    fun getBomFormatCheckProgress(@RequestParam batchId: String): ResponseEntity<BomExcelCheckProgress> {
        val progress = bomService.getBomExcelCheckProgress(batchId)
            ?: return ResponseEntity.notFound().build()
        return ResponseEntity.ok(progress)
    }
    */
    @GetMapping
    fun getBoms(): List<Bom> {
        return bomService.findAll()
    }

    @GetMapping("/combo")
    fun getCombo(
        @RequestParam(defaultValue = "false") includeInactive: Boolean,
    ): List<BomCombo> {
        return if (includeInactive) {
            bomRepository.findBomComboByDeletedIsFalse()
        } else {
            bomRepository.findBomComboByDeletedIsFalseAndStatus(BomStatus.ACTIVE)
        }
    }

    @GetMapping("/combo/issues")
    fun getComboIssues(): List<MasterDataIssueResponse> {
        return bomService.findComboIssues();
    }

    @GetMapping("/master-data/issues")
    fun getBomMasterDataIssues(): List<MasterDataIssueResponse> {
        return masterDataIssueService.findBomMasterDataIssues();
    }

    @PostMapping("/import-bom")
    fun importBom(@RequestBody payload: ImportBomRequestPayload): ResponseEntity<Resource> {
        val reportResult = bomService.importBOM(payload.batchId, payload.items)
       // val filename = "bom_excel_issue_log_${LocalDate.now()}.xlsx"

        return ResponseEntity.ok()
           // .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"$filename\"")
            //.header(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            .body(ByteArrayResource(reportResult))
    }
//    @PostMapping("/export-problematic-bom")
//    fun exportProblematicBom() {
//        return bomService.importBOM()
//    }

    /** Testing: FPSMS BOM id by finished-good item code (same item as BOM header). */
    @GetMapping("/by-item-code")
    fun getBomByItemCode(@RequestParam code: String): BomIdByItemCodeResponse {
        if (code.isBlank()) {
            throw BadRequestException("query parameter code is required")
        }
        return bomService.findBomSummaryByItemCode(code.trim())
    }

@GetMapping("/{id}/detail")
fun getBomDetail(@PathVariable id: Long): BomDetailResponse {
    return bomService.getBomDetail(id)
}

    /**
     * Edit BOM (basic fields + materials + process lines).
     * baseScore is recalculated on server.
     */
    @PutMapping("/{id}")
    fun editBom(
        @PathVariable id: Long,
        @RequestBody request: EditBomRequest,
    ): BomDetailResponse {
        return bomService.editBom(id, request)
    }
}