package cn.sagacloud.server.algorithm.controllers.modelFile

import cn.sagacloud.server.algorithm.models.modelFile.FloorModelView
import cn.sagacloud.server.algorithm.models.modelFile.ModelFileFolder
import cn.sagacloud.server.algorithm.models.responses.DataCheckListResponse
import cn.sagacloud.server.algorithm.services.BaseDataService
import cn.sagacloud.server.algorithm.services.comparator.FloorComparator
import cn.sagacloud.server.algorithm.services.endpoint.ReportService
import cn.sagacloud.server.algorithm.services.excel.ExcelService
import cn.sagacloud.server.algorithm.services.modelCheck.TaskService
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.serializer.SerializeConfig
import com.sybotan.database.SFilter
import com.sybotan.mybatis.SMybatisDao
import com.sybotan.service.SBaseService
import com.sybotan.service.SPageContext
import com.sybotan.service.models.enums.SResponseType
import com.sybotan.service.models.responses.SBaseResponse
import com.sybotan.service.models.responses.SQueryResponse
import com.sybotan.service.utils.SSpringContextUtil
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import java.net.URLEncoder
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.*
import javax.servlet.http.HttpServletResponse
import kotlin.collections.ArrayList

/**
 *
 *
 * @author jxing
 */
@Api(tags = ["报告接口"])
@RestController
@RequestMapping("/report")
class ReportController {

    val dataService = BaseDataService

    @Autowired
    lateinit var floorComparator: FloorComparator

    @Autowired
    lateinit var taskService: TaskService

    @Autowired
    lateinit var reportService : ReportService

    /**
     * 根据模型id获取模型所属楼层名, 所属文件夹名
     */
    @ApiOperation(value = "非阻塞性报告列表", notes = "填文件夹Id和项目id")
    @PostMapping(value = ["/list/non-blocking"])
    fun getNonBlockingReportList(@RequestBody(required = true) request: ModelFileFolder) : SBaseResponse{
        val errorResponse = SBaseResponse(SResponseType.failure)
        val sQueryResponse = SQueryResponse<DataCheckListResponse>()
        try {
            if(request.id.isNullOrBlank() || request.projectId.isNullOrBlank()){
                errorResponse.message = "Id或ProjectId不能为空"
                return errorResponse
            }
//            val list = floorMapper.getFinishedFloor(request.projectId!!, request.id!!)
            val service = SBaseService(SMybatisDao(FloorModelView::class.java))
            val select = service.select(SFilter.eq("folderId", request.id!!), SFilter.Companion.eq("projectId", request.projectId!!), SFilter.Companion.eq("status", 4))
            select.tableName = "revit.model_floor_file_func('${SPageContext.getHeader("ProjectId")}')"
            var list = select.exec()
            if(list.isEmpty()){
                //errorResponse.message = "暂时没有可用楼层"
                return sQueryResponse
            }
            list = ArrayList(list.sortedWith(floorComparator))
            val reportMap = taskService.getAllDataCheckResult(list)
            val content = ArrayList<DataCheckListResponse>()
            sQueryResponse.content = content
            reportMap.forEach {
                val dataCheckListResponse = DataCheckListResponse()
                dataCheckListResponse.floorName = it.key
                reportService.doNonBlockingStatistics(it.value, dataCheckListResponse)
                content.add(dataCheckListResponse)
            }
            return sQueryResponse
        }catch (e : Exception){
            e.printStackTrace()
            return errorResponse
        }
    }

    /**
     * 根据模型id获取模型所属楼层名, 所属文件夹名
     */
    @ApiOperation(value = "下载非阻塞性报告", notes = "填文件夹Id和项目id")
    @PostMapping(value = ["/non-blocking"])
    fun getNonBlockingReport(response : HttpServletResponse, @RequestBody(required = true) request: ModelFileFolder){
        val errorResponse = SBaseResponse(SResponseType.failure)
        try {
            if(request.id.isNullOrBlank() || request.projectId.isNullOrBlank()){
                errorResponse.message = "Id或ProjectId不能为空"
                response.contentType = "application/json;charset=utf-8"
                response.flushBuffer()
                response.outputStream.write(JSON.toJSONString(errorResponse, SSpringContextUtil.getBean("jsonMessageConverterConfig") as SerializeConfig).toByteArray())
                return
            }
//            val list = floorMapper.getFinishedFloor(request.projectId!!, request.id!!)
            val service = SBaseService(SMybatisDao(FloorModelView::class.java))
            val select = service.select(SFilter.eq("folderId", request.id!!), SFilter.Companion.eq("projectId", request.projectId!!), SFilter.Companion.eq("status", 4))
            select.tableName = "revit.model_floor_file_func('${SPageContext.getHeader("ProjectId")}')"
            var list = select.exec()
            if(list.isEmpty()){
                errorResponse.message = "没有可以下载的报告"
                response.contentType = "application/json;charset=utf-8"
                response.flushBuffer()
                response.outputStream.write(JSON.toJSONString(errorResponse, SSpringContextUtil.getBean("jsonMessageConverterConfig") as SerializeConfig).toByteArray())
                return
            }
            val folder = dataService.folderService.select(SFilter.Companion.eq("id", request.id!!)).entity()
            list = ArrayList(list.sortedWith(floorComparator))
            val reportMap = taskService.getAllDataCheckResult(list)
            val excelService = SSpringContextUtil.getBean(ExcelService::class.java) as ExcelService
            excelService.readNonBlockingExcel2007()
            reportService.writeNonBlockingReportToExcel(list, reportMap, excelService)
            response.contentType = "application/vnd.ms-excel;charset=utf-8"
            val desiredFormat = SimpleDateFormat("yyyyMMdd").format(Date())
            var str = ("${folder?.name}-模型检查报告-${desiredFormat}.xlsx")
            response.setHeader("Content-disposition",
                    "attachment;filename=${URLEncoder.encode(str, "UTF-8")}")
            excelService.workBook!!.write(response.outputStream)
            excelService.workBook!!.close()
            response.flushBuffer()
        }catch (e : Exception){
            errorResponse.message = "异常: ${e.message}"
            response.contentType = "application/json;charset=utf-8"
            response.flushBuffer()
            response.outputStream.write(JSON.toJSONString(errorResponse, SSpringContextUtil.getBean("jsonMessageConverterConfig") as SerializeConfig).toByteArray())
            e.printStackTrace()
        }finally {
            response.outputStream.flush()
            response.outputStream.close()
        }
    }
}