package com.yccrc.kede.controller.ent;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mchange.io.FileUtils;
import com.yccrc.common.annotation.Log;
import com.yccrc.common.config.YccrcConfig;
import com.yccrc.common.core.controller.BaseController;
import com.yccrc.common.core.domain.entity.SysUser;
import com.yccrc.common.enums.BusinessType;
import com.yccrc.common.exception.ServiceException;
import com.yccrc.common.utils.SecurityUtils;
import com.yccrc.common.utils.StringUtils;
import com.yccrc.common.vo.Result;
import com.yccrc.kede.domain.Attach;
import com.yccrc.kede.domain.Enterprise;
import com.yccrc.kede.domain.EnterpriseProject;
import com.yccrc.kede.domain.EnterpriseYearInfo;
import com.yccrc.kede.enums.AttachTypeEnum;
import com.yccrc.kede.service.*;
import com.yccrc.kede.vo.ProjectHeadAddVO;
import com.yccrc.kede.vo.ProjectQueryVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author zhiqiang.peng
 * @date 2023/7/26
 */
@Api(tags = "企业项目管理")
@RestController
@RequestMapping("/ent/data")
public class EntProjectController extends BaseController {

    ;;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private IEnterpriseYearInfoService enterpriseYearInfoService;
    @Autowired
    private IEnterpriseProjectService enterpriseProjectService;
    @Autowired
    private INotifyService notifyService;
    @Autowired
    private IAttachService attachService;

    @ApiOperation(value = "年度列表")
    @GetMapping("/year-list")
    public Result<Page<EnterpriseYearInfo>> yearList(ProjectQueryVO project) {
        return new Result<Page<EnterpriseYearInfo>>().ok(enterpriseYearInfoService.selectList(project));
    }

    @ApiOperation(value = "项目管理列表")
    @GetMapping("/list")
    public Result<Page<EnterpriseProject>> list(ProjectQueryVO project) {
        return new Result<Page<EnterpriseProject>>().ok(enterpriseProjectService.selectList(project));
    }

    @ApiOperation(value = "新增年度基本信息")
    @Log(title = "新增年度基本信息", businessType = BusinessType.INSERT)
    @PostMapping("/year-project")
    public Result<Boolean> add(@RequestBody EnterpriseYearInfo yearInfo) {
        Boolean aBoolean = enterpriseYearInfoService.saveYearProject(yearInfo);
        if (aBoolean) {
            return new Result<Boolean>().ok(true);
        } else {
            return new Result<Boolean>().ok(enterpriseYearInfoService.updateById(yearInfo));
        }
    }

    @ApiOperation(value = "修改年度基本信息")
    @Log(title = "修改年度基本信息", businessType = BusinessType.UPDATE)
    @PutMapping("/year-project")
    public Result<Boolean> edit(@RequestBody EnterpriseYearInfo yearInfo) {
        return new Result<Boolean>().ok(enterpriseYearInfoService.updateById(yearInfo));
    }

    @ApiOperation(value = "获取企业年度基本信息")
    @GetMapping(value = "/year-project/{projectYear}/{entId}")
    public Result<EnterpriseYearInfo> getInfoEntId(@PathVariable("projectYear") Integer projectYear, @PathVariable("entId") Integer entId) {
        EnterpriseYearInfo one = enterpriseYearInfoService.getOne(new LambdaQueryWrapper<EnterpriseYearInfo>()
                .eq(EnterpriseYearInfo::getProjectYear, projectYear)
                .eq(EnterpriseYearInfo::getEntId, entId)
        );
        return new Result<EnterpriseYearInfo>().ok(one);
    }

    @ApiOperation(value = "获取企业年度基本信息")
    @GetMapping(value = "/year-project/{projectYear}")
    public Result<EnterpriseYearInfo> getInfo(@PathVariable("projectYear") Integer projectYear) {
        SysUser user = SecurityUtils.getLoginUser().getUser();

        EnterpriseYearInfo one = enterpriseYearInfoService.getOne(new LambdaQueryWrapper<EnterpriseYearInfo>()
                .eq(EnterpriseYearInfo::getProjectYear, projectYear)
                .eq(EnterpriseYearInfo::getEntId, user.getScopeId())
        );
        return new Result<EnterpriseYearInfo>().ok(one);
    }

    @ApiOperation(value = "获取企业项目信息")
    @GetMapping(value = "/project/{projectId}")
    public Result<EnterpriseProject> getProjectInfo(@PathVariable("projectId") Integer projectId) {
        EnterpriseProject one = enterpriseProjectService.getOne(new LambdaQueryWrapper<EnterpriseProject>()
                .eq(EnterpriseProject::getId, projectId));
        if (StringUtils.isNotEmpty(one.getProjectJson())) {
            one.setHeadAddVOList(JSON.parseArray(one.getProjectJson(), ProjectHeadAddVO.class));
        }
        return new Result<EnterpriseProject>().ok(one);
    }

    @ApiOperation(value = "新增企业项目")
    @Log(title = "新增企业项目", businessType = BusinessType.INSERT)
    @PostMapping("/project")
    public Result<Boolean> addProject(@RequestBody EnterpriseProject project) {
        return new Result<Boolean>().ok(enterpriseProjectService.saveProject(project));
    }

    @ApiOperation(value = "修改企业项目")
    @Log(title = "修改企业项目", businessType = BusinessType.UPDATE)
    @PutMapping("/project")
    public Result<Boolean> edit(@RequestBody EnterpriseProject project) {
        // 判断是否是追溯项目
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy");
        String nowYear = currentDate.format(formatter);
        project.setProjectJson(JSON.toJSONString(project.getHeadAddVOList()));
        project.setOverYearFlag(!nowYear.equals(project.getProjectYear()));

        // 判断有没有当前年度企业基本信息
        Enterprise enterprise = enterpriseService.getById(project.getEntId());
        long count = enterpriseYearInfoService.count(new LambdaQueryWrapper<EnterpriseYearInfo>()
                .eq(EnterpriseYearInfo::getEntId, project.getEntId())
                .eq(EnterpriseYearInfo::getProjectYear, project.getProjectYear())
        );
        if (count < 1) {
            // 初始化一条年度企业基本信息数据
            enterpriseYearInfoService.save(new EnterpriseYearInfo(enterprise.getId(), enterprise.getEntName(),
                    project.getProjectYear(), enterprise.getAddress(), enterprise.getLinkName(), enterprise.getLinkPhone(), enterprise.getLinkMobile()));
        }
        return new Result<Boolean>().ok(enterpriseProjectService.updateById(project));
    }

    @ApiOperation(value = "删除企业项目")
    @Log(title = "删除企业项目", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public Result<Boolean> remove(@PathVariable Long[] ids) {
        return new Result<Boolean>().ok(enterpriseProjectService.removeByIds(Arrays.asList(ids)));
    }

    @ApiOperation(value = "修改状态:申报状态 1:待补充 2:待申报 3:待审核 4:已申报")
    @Log(title = "项目提交", businessType = BusinessType.UPDATE)
    @PutMapping("/auth/{projectId}/{reportState}")
    public Result<Boolean> auth(@PathVariable Integer projectId, @PathVariable Integer reportState) {
        if (reportState == 3) {
            notifyService.authProjectMsg(projectId);
        } else if (reportState == 4) {
            notifyService.authProjectFinishMsg(projectId);
        } else if (reportState == 1) {
            notifyService.authProjectFinishMsg(projectId);
        } else {
            throw new ServiceException("reportState[" + reportState + "]有误");
        }
        return new Result<Boolean>().ok(enterpriseProjectService.lambdaUpdate().set(EnterpriseProject::getReportState, reportState)
                .eq(EnterpriseProject::getId, projectId).update());
    }

    @ApiOperation(value = "打包下载指定项目附件")
    @GetMapping("/download/{projectId}")
    public void download(HttpServletResponse response, @PathVariable Integer projectId) throws IOException {
        String downloadFileName = "";
        if (projectId == null || projectId == 0) throw new ServiceException("项目ID不能为空");

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);

        EnterpriseProject pro = enterpriseProjectService.getById(projectId);
        if (pro != null) {
            downloadFileName += pro.getProjectName() + "_";
            // 企业项目申报上传文件
            List<Attach> attachEntList = attachService.lambdaQuery()
                    .eq(Attach::getAttachType, AttachTypeEnum.FINACIAL)
                    .eq(Attach::getDataId, pro.getId())
                    .in(Attach::getFileType, "file1", "file2", "file3", "file4", "file5",
                            "file6", "file7", "file8", "file9", "file10")
                    .list();

            if (!CollectionUtil.isEmpty(attachEntList)) {
                logger.info("打包企业资料");
                ArrayList<String> fileList = new ArrayList<>();
                for (Attach attach : attachEntList) {
                    File file = new File(YccrcConfig.getUploadPath() + attach.getFileKey());
                    if (file.exists()) {
                        logger.info(file.getName());
                        try {
                            String fileName = attach.getFileName();
                            if (fileList.contains(fileName)) {
                                fileName = FileUtil.getPrefix(fileName) + "_" + RandomUtil.randomString(3) + "." + FileUtil.getSuffix(fileName);
                            }
                            fileList.add(fileName);

                            ZipEntry e = new ZipEntry(pro.getProjectName() + "/企业/" + fileName);
                            logger.info(e.getName());
                            zip.putNextEntry(e);
                            IOUtils.write(FileUtils.getBytes(file), zip);
                            zip.flush();
                            zip.closeEntry();
                        } catch (IOException e) {
                            logger.error("文件写入压缩包失败：" + attach.getFileName(), e);
                        }

                    }
                }
            }
        }

        downloadFileName += DateUtil.format(new Date(), "HHmmss") + ".zip";

        IOUtils.closeQuietly(zip);
        byte[] data = outputStream.toByteArray();
        logger.info("data.lenght:{}", data.length);
        response.reset();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + java.net.URLEncoder.encode(downloadFileName, "utf-8").replaceAll("\\+", "%20") + "\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");
        IOUtils.write(data, response.getOutputStream());
    }

}
