package com.izouma.wenlvju.web.performance;

import cn.hutool.core.convert.Convert;
import com.izouma.wenlvju.domain.performance.Performance;
import com.izouma.wenlvju.domain.performance.Programme;
import com.izouma.wenlvju.dto.*;
import com.izouma.wenlvju.enums.ProgrammeStatus;
import com.izouma.wenlvju.enums.SignedIn;
import com.izouma.wenlvju.exception.BusinessException;
import com.izouma.wenlvju.repo.performance.ParticipantRepo;
import com.izouma.wenlvju.repo.performance.PerformanceRepo;
import com.izouma.wenlvju.repo.performance.ProgrammeRepo;
import com.izouma.wenlvju.service.UserService;
import com.izouma.wenlvju.service.performance.ProgrammeService;
import com.izouma.wenlvju.utils.SecurityUtils;
import com.izouma.wenlvju.utils.excel.ExcelUtils;
import com.izouma.wenlvju.web.BaseController;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/programme")
@AllArgsConstructor
public class ProgrammeController extends BaseController {
    private ProgrammeService programmeService;
    private ProgrammeRepo    programmeRepo;
    private UserService      userService;
    private PerformanceRepo  performanceRepo;
    private ParticipantRepo  participantRepo;

    //@PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/save")
    public Programme save(@RequestBody Programme record) {
        return programmeService.save(record, SecurityUtils.getAuthenticatedUser().getId());
    }

    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/saveScore")
    public Programme saveScore(@RequestParam Long id, @RequestParam Double score) {
        Programme programme = programmeRepo.findById(id).orElseThrow(new BusinessException("无节目"));
        Performance performance = performanceRepo.findById(programme.getPerformanceId())
                .orElseThrow(new BusinessException("无活动"));
        if (performance.getAuditTimes() > 1) {
            programme.setReviewScore(score);
            return programmeRepo.save(programme);
        }
        programme.setScore(score);
        return programmeRepo.save(programme);
    }

    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/saveAward")
    public Programme saveAward(@RequestParam Long id, Long awardId) {
        Programme programme = programmeRepo.findById(id).orElseThrow(new BusinessException("无节目"));
        programme.setAwardId(awardId);
        return programmeRepo.save(programme);
    }

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

    @PostMapping("/backAll")
    public Page<ProgrammeDTO> backAll(@RequestBody PageQuery pageQuery) {
        return programmeService.backAll(pageQuery);
    }

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

    @GetMapping("/getByAdmin/{id}")
    public ProgrammeDTO getByAdmin(@PathVariable Long id) {
        return programmeService.getByAdmin(id);
    }

    @PostMapping("/del/{id}")
    public void del(@PathVariable Long id) {
        programmeRepo.softDelete(id);
        // 删除参演人员
        participantRepo.softDeleteProgrammeId(id);
    }

    @GetMapping("/excel")
    @ResponseBody
    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
        List<ProgrammeDTO> data = programmeService.toDTOList(programmeService.all2(pageQuery).getContent());
        ExcelUtils.export(response, data);
    }

    @GetMapping("/excelProgramme")
    @ResponseBody
    public void excelProgramme(HttpServletResponse response, PageQuery pageQuery) throws IOException {
        List<ProgrammeDTO> data = programmeService.backAll(pageQuery).getContent();
        ExcelUtils.export(response, data);
    }


    @GetMapping("/excelGO")
    @ResponseBody
    public void excelGO(HttpServletResponse response, PageQuery pageQuery) throws IOException {
        List<ProgrammeShowDTO> data = this.showAll(pageQuery).getContent();
        ExcelUtils.export(response, data);
    }

    @GetMapping(value = "/excelTemp", produces = "application/vnd.ms-excel;charset=utf-8")
    public void excelTemp(HttpServletResponse response) throws IOException {
//        ExcelUtils.export1(response, ProgrammeDTO.class);
        programmeService.excelTemp(response);
    }

    @PostMapping("/upload")
    public void uploadFile(@RequestParam("file") MultipartFile file) throws Exception {
        programmeService.upload(file, SecurityUtils.getAuthenticatedUser().getId());
//        try {
//            programmeService.upload(file, SecurityUtils.getAuthenticatedUser().getId());
//        } catch (Exception e) {
//            log.error("上传失败", e);
////            throw new BusinessException("上传失败", e.getMessage());
//            throw e;
//        }
    }

    @ApiOperation("移出分组")
    @PostMapping("/removeGroup/{id}")
    public void removeGroup(@PathVariable Long id, @RequestParam Long arrangeId) {
        programmeService.removeArrange(id, arrangeId);
    }

    @ApiOperation("加入分组")
    @PostMapping("/intoGroup")
    public void intoGroup(@RequestParam Long id, @RequestParam Long arrangeId) {
        programmeService.add(id, arrangeId);
    }

    @ApiOperation("未分组")
    @PostMapping("/unGrouped")
    public List<ProgrammeShowDTO> unGrouped(@RequestParam Long performanceId) {
        return programmeService.ungrouped(performanceId);
    }

    @ApiOperation("签到列表")
    @PostMapping("/byArrange")
    public Page<ArrangeProgrammeDTO> byArrange(@RequestBody PageQuery pageQuery) {
        return programmeService.byArrange(pageQuery);
    }

    @ApiOperation("签到")
    @PostMapping("/signIn")
    public void signIn(@RequestParam Long id, @RequestParam SignedIn signedIn, String description) {
        programmeService.signIn(id, signedIn, description, SecurityUtils.getAuthenticatedUser().getId());
    }

    @PostMapping("/byExpert")
    @ApiOperation("专家手机端查看")
    public Page<ProgrammeScoreDTO> byExpert(@RequestBody PageQuery pageQuery) {
        pageQuery.setSort("showBegin,asc;");
        Long arrangeId = Convert.convert(Long.class, pageQuery.getQuery().get("arrangeId"));
        return programmeService.toDTOPage(this.all(pageQuery), Collections.singletonList(arrangeId), SecurityUtils.getAuthenticatedUser()
                .getId());
    }

    @PostMapping("/byScore")
    @ApiOperation("专家电脑端查看")
    public Page<ProgrammeScoreDTO> byScore(@RequestBody PageQuery pageQuery) {
        return programmeService.byScore(pageQuery);
    }

    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/byScoreAdmin")
    @ApiOperation("查看分数")
    public Page<ProgScoreAdminDTO> byScoreAdmin(@RequestBody PageQuery pageQuery) {
        Page<Programme> all = programmeService.all2(pageQuery);
        return programmeService.toDTOPage(all);
    }

    @GetMapping("/excelScore")
    @ResponseBody
    public void excelScore(HttpServletResponse response, PageQuery pageQuery) throws IOException {
        List<ProgScoreAdminDTO> data = this.byScoreAdmin(pageQuery).getContent();
        ExcelUtils.export(response, data);
    }

    @PostMapping("/getDTO/{id}")
    @ApiOperation("专家手机端查看详情")
    public ProgrammeScoreDTO getDTO(@PathVariable Long id) {
        return programmeService.getDTO(id, SecurityUtils.getAuthenticatedUser().getId());
    }

    @PostMapping("/firstAudit")
    @ApiOperation("考级机构初审")
    public void firstAudit(@RequestParam Long id, @RequestParam ProgrammeStatus status, String remark) {
        programmeService.firstAudit(id, status, remark, SecurityUtils.getAuthenticatedUser().getId());
    }

    @GetMapping("/getShow/{id}")
    @ApiOperation("考级机构查看节目信息")
    public ProgrammeShowDTO getShow(@PathVariable Long id) {
        Programme programme = programmeRepo.findById(id).orElseThrow(new BusinessException("无节目"));
        return programmeService.toShowDTO(programme);
    }

    @PostMapping("/showAll")
    @ApiOperation("考级机构查看节目信息")
    public Page<ProgrammeShowDTO> showAll(@RequestBody PageQuery pageQuery) {
        Page<Programme> all = programmeService.all2(pageQuery);
        return new PageImpl<>(programmeService.toShowDTOList(all.getContent()), all.getPageable()
                , all.getTotalElements());
    }

    @ApiOperation("获取手机号/token")
    @PostMapping("/getAuth")
    public Map<String, String> getAuth(@RequestParam Long id, @RequestParam String phone) {
        Programme apply = programmeRepo.findById(id).orElseThrow(new BusinessException("无记录"));
        return userService.getAuth(id, phone, apply.getPhone());
    }

    @ApiOperation("查分数信息")
    @GetMapping("/getScore/{id}")
    public ProgrammeShowDTO getScore(@PathVariable Long id, String phone) {
        return programmeService.get(id, phone);
    }

    @ApiOperation("设置进入复审名单")
    @PostMapping("/review")
    public void review(@RequestParam Long performanceId, int pass) {
        programmeService.review(performanceId, pass, SecurityUtils.getAuthenticatedUser().getId());
    }

    @PostMapping("/result")
    public Page<ProgrammeResultDTO> result(@RequestBody PageQuery pageQuery) {
        return programmeService.result(pageQuery);
    }

    @GetMapping("/excelResult")
    @ResponseBody
    public void excelResult(HttpServletResponse response, PageQuery pageQuery) throws IOException {
        List<ProgrammeResultDTO> data = this.result(pageQuery).getContent();
        ExcelUtils.export(response, data);
    }
}

