package com.izouma.wenlvju.web;

import cn.hutool.core.collection.CollUtil;
import com.github.kevinsawicki.http.HttpRequest;
import com.izouma.wenlvju.annotations.OperLog;
import com.izouma.wenlvju.domain.*;
import com.izouma.wenlvju.dto.PageQuery;
import com.izouma.wenlvju.dto.RateDTO;
import com.izouma.wenlvju.enums.RateStatus;
import com.izouma.wenlvju.exception.BusinessException;
import com.izouma.wenlvju.repo.*;
import com.izouma.wenlvju.service.RateService;
import com.izouma.wenlvju.utils.SecurityUtils;
import com.izouma.wenlvju.utils.excel.ExcelUtils;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/rate")
@AllArgsConstructor
public class RateController extends BaseController {
    private final RateService             rateService;
    private final RateRepo                rateRepo;
    private final OrganizationRepo        organizationRepo;
    private final UserRepo                userRepo;
    private final GradingOrganizationRepo gradingOrganizationRepo;

    //@PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/save")
    @OperLog(value = "等级评定", type = "修改/新增", desc = "对等级评定申请进行操作")
    public Rate save(@RequestBody Rate record) {
        return rateService.save(record);
    }


    //@PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/all")
    public Page<Rate> all(@RequestBody PageQuery pageQuery) {
        return rateService.all(pageQuery);
    }

    @PreAuthorize("hasAnyRole('ADMIN','DISTRICT','DISTRICT_STAFF','EXPERT')")
    @PostMapping("/all2")
    public Page<RateDTO> all2(@RequestBody PageQuery pageQuery) {
//        pageQuery.setSort("createdAt,desc");
        Map<Long, Organization> organizationMap = organizationRepo.findAll()
                .stream()
                .collect(Collectors.toMap(Organization::getId, organization -> organization));
        Map<Long, String> gradeMap = gradingOrganizationRepo.findAll()
                .stream()
                .collect(Collectors.toMap(GradingOrganization::getId, GradingOrganization::getName));

        return rateService.all(pageQuery).map(rate -> {
            Organization organization = organizationMap.get(rate.getOrganizationId());
            String names = organization.getGradingOrganizationId()
                    .stream()
                    .map(gradeMap::get)
                    .collect(Collectors.joining(","));
            return new RateDTO(rate, organization, names);
        });
    }

    @GetMapping("/get/{id}")
    public Rate get(@PathVariable Long id) {
        return rateRepo.findById(id).orElseThrow(new BusinessException("无记录"));
    }

    @GetMapping("/get1/{id}")
    public Rate get1(@PathVariable Long id) {
        Rate rate = rateRepo.findById(id).orElseThrow(new BusinessException("无记录"));
        if (CollUtil.isNotEmpty(rate.getExpertMemberUserId())) {
            rate.setExpertUser(userRepo.findAllById(rate.getExpertMemberUserId())
                    .stream()
                    .collect(Collectors.toMap(User::getPhone, User::getNickname)));
        }

        return rate;
    }

    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/del/{id}")
    public void del(@PathVariable Long id) {
        rateRepo.softDelete(id);
    }

    @PostMapping("/excel")
    @ResponseBody
    @OperLog(value = "导出等级评定表", type = "导出")
    public void excel(HttpServletResponse response, @RequestBody PageQuery pageQuery) throws IOException {
        List<RateDTO> data = all2(pageQuery).getContent();
        if (CollUtil.isEmpty(data)) {
            throw new BusinessException("暂无数据！");
        }
        ExcelUtils.export(response, data);
    }

    @OperLog(value = "等级评定", type = "修改", desc = "对等级评定申请进行操作")
    @PostMapping("/audit")
    public void audit(@RequestParam Long id, @RequestParam RateStatus status, String remark) {
        rateService.audit(id, status, remark, SecurityUtils.getAuthenticatedUser().getId());
    }

    @OperLog(value = "等级评定", type = "退回", desc = "对等级评定申请进行操作")
    @PostMapping("/offline")
    public void offline(@RequestParam Long id, RateStatus status) {
        rateService.offline(id, SecurityUtils.getAuthenticatedUser().getId(), status);
    }


    @GetMapping(value = "/export/{id}", produces = "application/msword;charset=utf-8")
    public String export(@PathVariable Long id) {
        Rate rate = rateRepo.findById(id).orElseThrow(new BusinessException("无记录"));
        return rateService.export(rate);
    }

    @GetMapping(value = "/exportPdf/{id}", produces = "application/pdf;charset=utf-8")
    public void exportPdf(@PathVariable Long id, HttpServletResponse response) {
        try {
            rateService.exportPdf(id, response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OperLog(value = "等级评定", type = "修改", desc = "对等级评定申请进行操作")
    @ApiOperation("设置审查时间")
    @GetMapping("/saveReviewTime")
    public Rate saveReviewTime(Long id, String time) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        return rateService.saveReviewTime(id, LocalDateTime.parse(time, df), SecurityUtils.getAuthenticatedUser()
                .getId());
    }

    @GetMapping(value = "/test", produces = "application/pdf;charset=utf-8")
    @ResponseBody
    public void test(HttpServletResponse response) throws IOException {
        InputStream in = HttpRequest.get("https://ticket-exchange.oss-cn-hangzhou.aliyuncs.com/application/2021-04-09-10-29-31sAAmcakx.pdf")
                .stream();
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=" + "result.pdf");

        OutputStream sos = response.getOutputStream();

        int readBytes;
        while ((readBytes = in.read()) != -1) {
            sos.write(readBytes);
        }

        sos.flush();
        sos.close();
        in.close();
    }

    @GetMapping("/canApply")
    public boolean canApply(@RequestParam Long id) {
        String year = String.valueOf(LocalDate.now().getYear());
        return rateRepo.countAllByOrganizationIdAndYear(id, year) == 0;
    }

    @PostMapping("/paperMaterial")
    public void paperMaterial(@RequestParam Long id, @RequestParam RateStatus status, String remark) {
        rateService.paperMaterial(id, status, remark, SecurityUtils.getAuthenticatedUser().getId());
    }

}

