package cn.com.ty.lift.business.common;

import cn.com.ty.lift.business.annualinspection.service.AnnualInspectionService;
import cn.com.ty.lift.business.capital.service.CapitalRepairLiftRelevanceService;
import cn.com.ty.lift.business.emergency.service.EmergencyRepairService;
import cn.com.ty.lift.business.framework.conf.SystemConfiguration;
import cn.com.ty.lift.business.framework.util.MessageUtils;
import cn.com.ty.lift.business.library.dao.entity.LiftBrand;
import cn.com.ty.lift.business.maintenance.service.MaintenancePlanService;
import cn.com.ty.lift.business.project.dao.entity.model.AreaCodeDTO;
import cn.com.ty.lift.business.project.dao.mapper.AreaCodeMapper;
import cn.com.ty.lift.common.constants.RedisConstants;
import cn.com.ty.lift.common.utils.ValuePool;
import cn.com.ty.lift.common.verify.Val;
import cn.com.ty.lift.common.verify.Validate;
import cn.com.ty.lift.common.verify.Validation;
import cn.com.xwy.boot.web.dto.RestResponse;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author bieao
 * @date 2019/12/19
 * @description 公共初始化数据
 */
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("common")
public class CommonController {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd");

    private RedisTemplate<String, Object> redisTemplate;
    private SystemConfiguration           systemConfiguration;
    private AnnualInspectionService       annualInspectionService;
    private EmergencyRepairService        emergencyRepairService;
    private CapitalRepairLiftRelevanceService capitalRepairLiftRelevanceService;
    private MaintenancePlanService maintenancePlanService;
    private AreaCodeMapper codeMapper;

    /**
     * @return RestResponse 省、市、区树形结构列表
     * @description 查询省、市、区树形结构列表
     * @date 2019/12/4 10:23 AM
     */
    @PostMapping("area/list")
    @Validation(fields = {"code"})
    public RestResponse areaList(@Val @RequestBody CommonRequest commonRequest) {
        List<AreaCodeDTO> areaCodeList = codeMapper.queryAreaList(commonRequest.getCode());
        return RestResponse.success(areaCodeList, MessageUtils.get("msg.query.success"));
    }

    /**
     * @return RestResponse 电梯品牌列表
     * @description 查询电梯品牌列表
     * @date 2019/12/10 10:23 AM
     */
    @PostMapping("brand/list")
    @SuppressWarnings(value = "unchecked")
    public RestResponse list() {
        List<LiftBrand> liftBrandList = (List<LiftBrand>) redisTemplate.opsForValue().get(RedisConstants.RK_LIFT_BRAND_LIST);
        if (ObjectUtil.isEmpty(liftBrandList)) {
            return RestResponse.success();
        }
        return RestResponse.success(liftBrandList, MessageUtils.get("msg.query.success"));
    }

    /**
     * 批量上传多个文件
     *
     * @param files 文件列表
     * @return RestResponse
     */
    @PostMapping("uploads")
    public RestResponse uploads(@RequestParam("files") MultipartFile[] files) {
        Validate.notTrue(ArrayUtil.isEmpty(files), ValuePool.UPLOAD_DATA_MISSING);
        Map<String, MultipartFile> fileMap = new LinkedHashMap<>();
        //1 先解析文件格式
        for (MultipartFile file : files) {
            String currentTime = DateUtil.formatDateTime(new Date());
            //上传图片加图片水印
            //ImageUtil.pressImage(null, file, "/home/ying/server/lift-business/tmp/watermark.png", "/home/ying/server/lift-business/tmp/imgBack.png", "right-bottom", null);
            //上传图片加文字水印
            //ImageUtil.pressText("/home/ying/server/lift-business/tmp/imgBack.png", currentTime, "/home/ying/server/lift-business/tmp/imgBack.png", "黑体", Font.BOLD + Font.ITALIC, 30, "left-bottom", Color.GRAY);
            //File downloadFile = new File("/home/ying/server/lift-business/tmp/imgBack.png");
            //FileItem fileItem = ImageUtil.createFileItem(downloadFile, downloadFile.getName());
            //MultipartFile mfile = new CommonsMultipartFile(fileItem);
            String fileName = handleFile(file);
            fileMap.put(fileName, file);
        }
        //2 批量上传
        try {
            List<String> urls = new LinkedList<>();
            for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) {
                String url = systemConfiguration.build().putObject(entry.getKey(), entry.getValue().getBytes());
                log.info("upload file complete, file URL: {}", url);
                Validate.notNull(url, ValuePool.UPLOAD_FAIL);
                urls.add(url);
            }
            return RestResponse.success(urls);
        } catch (Exception e) {
            log.error("upload file occur exception", e);
            return RestResponse.fail(ValuePool.UPLOAD_FAIL);
        }
    }

    /**
     * 上传单个文件
     *
     * @param file 上传的文件
     * @return RestResponse
     */
    @PostMapping("upload")
    public RestResponse upload(@RequestParam("file") MultipartFile file) {
        Validate.notTrue(Objects.isNull(file) || file.isEmpty(), ValuePool.UPLOAD_DATA_MISSING);
        //String currentTime = DateUtil.formatDateTime(new Date());
        //上传图片加图片水印
        //ImageUtil.pressImage(null, file, "/home/ying/server/lift-business/tmp/watermark.png", "/home/ying/server/lift-business/tmp/imgBack.png", "right-bottom", null);
        //上传图片加文字水印
        //ImageUtil.pressText("/home/ying/server/lift-business/tmp/imgBack.png", currentTime, "/home/ying/server/lift-business/tmp/imgBack.png", "黑体", Font.BOLD + Font.ITALIC, 30, "left-bottom", Color.GRAY);
        //File downloadFile = new File("/home/ying/server/lift-business/tmp/imgBack.png");
        //FileItem fileItem = ImageUtil.createFileItem(downloadFile, downloadFile.getName());
        //MultipartFile mfile = new CommonsMultipartFile(fileItem);
        String fileName = handleFile(file);
        try {
            String url = systemConfiguration.build().putObject(fileName, file.getBytes());
            log.info("upload file complete, file URL: {}", url);
            return RestResponse.success(url);
        } catch (Exception e) {
            log.error("upload file occur exception", e);
            return RestResponse.fail(ValuePool.UPLOAD_FAIL);
        }
    }

    /**
     * 校验文件大小，文件格式，生成新文件名
     *
     * @param file the {@link MultipartFile} to upload
     * @return the name string of the file.
     */
    private String handleFile(MultipartFile file) {
        Validate.notTrue(Objects.isNull(file) || file.isEmpty(), ValuePool.UPLOAD_DATA_MISSING);
        // 获取文件名，带后缀
        String originalFilename = file.getOriginalFilename();
        log.info("the original file name：{}", originalFilename);
        // 获取文件的后缀格式
        Validate.notNull(originalFilename, ValuePool.UPLOAD_ORIGINAL_NAME_MISSING);
        int lastDotIndex = originalFilename.lastIndexOf(ValuePool.DOT);
        Validate.notTrue(-1 == lastDotIndex, ValuePool.UPLOAD_FORMAT_MISSING);
        String fileSuffix = originalFilename.substring(lastDotIndex).toLowerCase();
        Validate.notNull(fileSuffix, ValuePool.UPLOAD_FORMAT_ILLEGAL);
        long fileSize = file.getSize();
        log.info("the size of file: {}", fileSize);
        if (StrUtil.equalsAny(fileSuffix, ValuePool.UPLOAD_TYPE_PICS)) {
            Validate.notTrue(fileSize > ValuePool.UPLOAD_MAX_SIZE_PIC, ValuePool.UPLOAD_MAX_SIZE_PIC_DESC);
        } else if (StrUtil.equalsAny(fileSuffix, ValuePool.UPLOAD_TYPE_FILES)) {
            Validate.notTrue(fileSize > ValuePool.UPLOAD_MAX_SIZE_FILE, ValuePool.UPLOAD_MAX_SIZE_FILE_DESC);
        } else if (StrUtil.equalsAny(fileSuffix, ValuePool.UPLOAD_TYPE_VIDEOS)) {
            Validate.notTrue(fileSize > ValuePool.UPLOAD_MAX_SIZE_VIDEO, ValuePool.UPLOAD_MAX_SIZE_VIDEO_DESC);
        } else {
            throw Validate.validateException(ValuePool.UPLOAD_FORMAT_NOT_SUPPORT);
        }
        String fileName = StrUtil.format("{}/{}{}", DATE_TIME_FORMATTER.format(LocalDate.now()), IdWorker.getIdStr(), fileSuffix);
        log.info("the new file name：{}", fileName);
        return fileName;
    }

    @PostMapping("countDoing")
    @Validation(fields = {"mtCompanyId", "userId"})
    public RestResponse countDoing(@Val @RequestBody CommonRequest request) {
        long inspection = annualInspectionService.countDoingByUser(request);
        long repair = emergencyRepairService.countDoingByUser(request);
        long capital = capitalRepairLiftRelevanceService.countDoingByUser(request);
        long maintain = maintenancePlanService.countWaitingMaintenanceByUser(request);
        CommonResponse common = new CommonResponse();
        common.setInspection(inspection);
        common.setRepair(repair);
        common.setCapital(capital);
        common.setMaintain(maintain);
        return RestResponse.success(common);
    }
}
