package com.yeejoin.amos.boot.module.elevator.biz.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.controller.BaseController;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.module.common.api.excel.ExcelUtil;
import com.yeejoin.amos.boot.module.elevator.api.common.BizCommonConstant;
import com.yeejoin.amos.boot.module.elevator.api.common.StringUtil;
import com.yeejoin.amos.boot.module.elevator.api.dto.ElevatorDto;
import com.yeejoin.amos.boot.module.elevator.api.dto.ExportDto;
import com.yeejoin.amos.boot.module.elevator.api.dto.TemplateExportDto;
import com.yeejoin.amos.boot.module.elevator.api.dto.VoiceRecordFileDto;
import com.yeejoin.amos.boot.module.elevator.api.entity.TemplateExport;
import com.yeejoin.amos.boot.module.elevator.api.service.IMaintenanceUnitService;
import com.yeejoin.amos.boot.module.elevator.api.service.IRescueStationService;
import com.yeejoin.amos.boot.module.elevator.api.service.IUseUnitService;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.ElevatorServiceImpl;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.TemplateExportServiceImpl;
import com.yeejoin.amos.boot.module.elevator.biz.service.impl.VoiceRecordFileServiceImpl;
import com.yeejoin.amos.boot.module.elevator.biz.utils.RedisUtil;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * 模板表
 *
 * @author system_generator
 * @date 2021-10-25
 */
@Slf4j
@RestController
@Api(tags = "导出Api")
@RequestMapping(value = "/template-export")
public class TemplateExportController extends BaseController {

    @Autowired
    TemplateExportServiceImpl templateExportServiceImpl;

	@Autowired
	IMaintenanceUnitService iMaintenanceUnitService;

	@Autowired
	IUseUnitService iUseUnitService;

	@Autowired
	ElevatorServiceImpl elevatorServiceImpl;

	@Autowired
	IRescueStationService iRescueStationService;

	@Autowired
	VoiceRecordFileServiceImpl voiceRecordFileServiceImpl;

	@Autowired
	RedisUtil redisUtil;

	@Autowired
	Executor customExecutor;


    /**
     * 新增模板表
     *
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
	@PostMapping(value = "/save")
	@ApiOperation(httpMethod = "POST", value = "新增模板", notes = "新增模板")
	public ResponseModel<TemplateExportDto> save(@RequestBody TemplateExportDto model) {
		if (ValidationUtil.isEmpty(model.getTemplateName())
				|| ValidationUtil.isEmpty(model.getTemplateContent())
				|| ValidationUtil.isEmpty(model.getTemplateType())
		) {
			throw new BadRequest("参数校验失败.");
		}
		// 判断 同一类型模板名称不能重复
		TemplateExport temp = templateExportServiceImpl.getOne(new LambdaQueryWrapper<TemplateExport>().eq(TemplateExport::getIsDelete,0).eq(TemplateExport::getTemplateType,model.getTemplateType()).eq(TemplateExport::getTemplateName,model.getTemplateName()));
		if(temp != null) {
			throw new BadRequest("模板名称已存在.");
		}
		model.setIsStandard(false); // 新增模板表均不为标准模板
	    model = templateExportServiceImpl.createWithModel(model);
	    return ResponseHelper.buildResponse(model);
	}

	/**
     * 根据sequenceNbr更新
     *
     * @param sequenceNbr 主键
     * @return
     */
	@TycloudOperation(ApiLevel = UserType.AGENCY)
	@PutMapping(value = "/{sequenceNbr}")
	@ApiOperation(httpMethod = "PUT", value = "根据sequenceNbr更新模板", notes = "根据sequenceNbr更新模板")
	public ResponseModel<TemplateExportDto> updateBySequenceNbrTemplateExport(@RequestBody TemplateExportDto model,@PathVariable(value = "sequenceNbr") Long sequenceNbr) {
		model.setSequenceNbr(sequenceNbr);
		if (ValidationUtil.isEmpty(model.getTemplateType())
		) {
			throw new BadRequest("模板类型为必填项");
		}
		if(StringUtils.isNotBlank(model.getTemplateName())) {
			TemplateExport temp = templateExportServiceImpl.getOne(new LambdaQueryWrapper<TemplateExport>().eq(TemplateExport::getTemplateType,model.getTemplateType()).
					eq(TemplateExport::getTemplateName,model.getTemplateName()).
					ne(TemplateExport::getSequenceNbr,sequenceNbr).
					eq(TemplateExport::getIsDelete,0));
			if(temp != null) {
				throw new BadRequest("模板名称已存在.");
			}
		}
		model.setIsStandard(false); // 更新模板表均不为标准模板
	    return ResponseHelper.buildResponse(templateExportServiceImpl.updateWithModel(model));
	}

	/**
     * 根据sequenceNbr删除
     *
     * @param sequenceNbr 主键
     * @return
     */
    @TycloudOperation(ApiLevel = UserType.AGENCY)
    @DeleteMapping(value = "/{sequenceNbr}")
    @ApiOperation(httpMethod = "DELETE", value = "根据sequenceNbr删除模板", notes = "根据sequenceNbr删除模板")
    public ResponseModel<Boolean> deleteBySequenceNbr(HttpServletRequest request, @PathVariable(value = "sequenceNbr") Long sequenceNbr){
    	// 不可删除标准模板
		TemplateExport temp = templateExportServiceImpl.getOne(new LambdaQueryWrapper<TemplateExport>().
				eq(TemplateExport::getSequenceNbr,sequenceNbr));
		if(temp.getIsStandard() == true) {
			throw new BadRequest("不可删除标准模板.");
		}


        return ResponseHelper.buildResponse(templateExportServiceImpl.update(new LambdaUpdateWrapper<TemplateExport>().set(TemplateExport::getIsDelete,true).eq(TemplateExport::getSequenceNbr,sequenceNbr)));
    }


	/**
	 * 列表全部数据查询
     *
	 * @return
	 */
	@TycloudOperation(ApiLevel = UserType.AGENCY)
	@ApiOperation(httpMethod = "GET",value = "模板表列表全部数据查询",   notes = "模板表列表全部数据查询")
	@GetMapping(value = "/list/{type}")
	public ResponseModel<Map<String, Object>> selectForList(@PathVariable String type) {
		Map<String, Object> result = new HashMap<>();
		List<TemplateExport> list = templateExportServiceImpl.list(new LambdaQueryWrapper<TemplateExport>().eq(TemplateExport::getIsDelete,0).eq(TemplateExport::getTemplateType,type).orderByDesc(TemplateExport::getIsStandard));
		result.put("list",list);
		String fileName = null;
		if("ELEVATOR".equals(type)) { // 查询电梯数据
			fileName = "电梯信息";
		} else if("MAINTENANCE_COMPANY".equals(type)) { // 查询维保单位数据
			fileName = "维保单位";
		} else if("USE_UNIT".equals(type)) { // 查询使用单位数据
			fileName = "使用单位";
		} else if("RESCUE_STATION".equals(type)) { // 查询救援站数据
			fileName = "救援站";
		} else if("VOICE_RECORD".equals(type)) { // 查询通话录音数据
			fileName = "通话录音";
		}
		fileName += DateUtils.getDateNowShortNumber();
		result.put("fileName",fileName);
	    return ResponseHelper.buildResponse(result);
	}


	@TycloudOperation(ApiLevel = UserType.AGENCY)
	@ApiOperation(httpMethod = "POST", value = "根据字段类型导出", notes = "根据字段类型导出")
	@PostMapping("/exportByTypeParams")
	public void exportByTypeParams(@RequestBody ExportDto exportDto, HttpServletResponse response) throws Exception {
		if (ValidationUtil.isEmpty(exportDto.getExportArray())
				|| ValidationUtil.isEmpty(exportDto.getDataType())
				|| ValidationUtil.isEmpty(exportDto.getFileName())
				|| ValidationUtil.isEmpty(exportDto.getExportType())
				|| ValidationUtil.isEmpty(exportDto.getFileType())
		) {
			throw new BadRequest("参数校验失败.");
		}
		// 导出模块 电梯  维保单位  救援机构
		if("1042".equals(exportDto.getDataType())) { // 选择列导出
			if(ValidationUtil.isEmpty(exportDto.getExportId())) {
				throw new BadRequest("未选择需要导出的数据.");
			}
		} else {
			exportDto.setExportId("");
		}
		JSONArray jsonArray = JSONArray.parseArray(exportDto.getExportArray());
		List<List<String>> heads = Lists.newArrayList();
		List<String> headstr = Lists.newArrayList();
		List list = null;
		String sheetName = null;
		for(int i = 0; i < jsonArray.size() ; i ++) {
			JSONObject temp = jsonArray.getJSONObject(i);
			headstr.add(temp.getString("key"));
			List<String> tempList = Lists.newArrayList(temp.getString("value"));
			heads.add(tempList);
		}
		String fileName = exportDto.getFileName();
        // 查询电梯数据
		if("ELEVATOR".equals(exportDto.getExportType())) {
			if(StringUtil.isNotEmpty(exportDto.getExportId())){
				// 选择指定的行-导出逻辑
				list = elevatorServiceImpl.selectExportData(exportDto.getExportId());
			} else {
				// 全部导出-导出逻辑，由于电梯为老存量数据，只是查看，故全部放到redis,解决全部导出时性能问题
				if(redisUtil.hasKey(BizCommonConstant.OLD_ELEVATOR_REDIS_KEY)){
					list = JSONObject.parseArray(redisUtil.get(BizCommonConstant.OLD_ELEVATOR_REDIS_KEY).toString(),ElevatorDto.class);
				} else {
					list = elevatorServiceImpl.selectExportData(exportDto.getExportId());
					redisUtil.set(BizCommonConstant.OLD_ELEVATOR_REDIS_KEY,JSONObject.toJSONString(list));
				}
			}
			ExcelUtil.exportWithMplThread2(response,fileName,list,heads,exportDto.getFileType(),customExecutor,10000);
			return;
		} else if("MAINTENANCE_COMPANY".equals(exportDto.getExportType())) { // 查询维保单位数据
			list = iMaintenanceUnitService.selectExportData(exportDto.getExportId());
			sheetName = "维保单位";
		} else if("USE_UNIT".equals(exportDto.getExportType())) { // 查询使用单位数据
			sheetName = "使用单位";
			list = iUseUnitService.selectExportData(exportDto.getExportId());
		} else if("RESCUE_STATION".equals(exportDto.getExportType())) { // 查询救援站数据
			sheetName = "救援站";
			list = iRescueStationService.selectExportData(exportDto.getExportId());
		} else if("VOICE_RECORD".equals(exportDto.getExportType())) { // 查询救援站数据
			sheetName = "通话录音";
			AgencyUserModel userModel = this.getSelectedOrgInfo().getUserModel();
			if (!ObjectUtils.isEmpty(userModel)) {
				List<VoiceRecordFileDto> voiceRecordFileDtos = voiceRecordFileServiceImpl.selectExportData(exportDto.getExportId(), userModel);
				byte[] excelBytes = ExcelUtil.generateExcelBytes(sheetName, voiceRecordFileDtos, heads, headstr, exportDto.getFileType());
				// 录音文件获取
				List<JSONObject> recordFiles = voiceRecordFileDtos.stream()
						.filter(s -> ObjectUtils.isNotEmpty(s.getFilePath()) && ObjectUtils.isNotEmpty(s.getWorkNum()))
						.map(s -> templateExportServiceImpl.downloadRecordFile(s))
						.filter(Objects::nonNull)
						.collect(Collectors.toList());

				// 打包zip返回
				templateExportServiceImpl.packZip(response, fileName, excelBytes, exportDto.getFileType(), recordFiles);
				return;
			}
		}
		ExcelUtil.createTemplateWithHeaders(response, fileName, sheetName, list,heads,headstr,exportDto.getFileType());
	}
}
