package com.cpop.oam.business.controller.mini;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import com.alibaba.excel.EasyExcel;
import com.cpop.api.tencent.wxWork.handler.WebHookSendHandler;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.R;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.handler.TencentCosHandler;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.file.FileUtils;
import com.cpop.oam.business.bo.SummitApplyBo;
import com.cpop.oam.business.dto.SummitApplyDto;
import com.cpop.oam.business.entity.SummitApply;
import com.cpop.oam.business.entity.SummitApplyUser;
import com.cpop.oam.business.service.SummitApplyService;
import com.cpop.oam.business.service.SummitApplyUserService;
import com.cpop.oam.framework.constant.WebHookKeyConstant;
import com.mybatisflex.core.query.QueryWrapper;
import com.qcloud.cos.model.UploadResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

import static com.cpop.oam.business.entity.table.SummitApplyTableDef.SUMMIT_APPLY;

/**
 * @author DB
 * @version 1.0.0
 * @since 2024-04-10 14:33
 */
@RestController
@Api(tags = "小程序峰会接口")
@RequestMapping("/mini/summit")
@Slf4j
public class MiniSummitController {

    @Autowired
    private SummitApplyService summitApplyService;

    @Autowired
    private SummitApplyUserService summitApplyUserService;

    /**
     * 获取峰会二维码
     * @author DB
     * @since 2023/12/07
     */
    @ApiOperation("获取峰会二维码")
    @GetMapping("/getSummitQrCode")
    @Deprecated
    public R<String> getSummitQrCode() throws WxErrorException, IOException {
        WxMaQrcodeService qrcodeService = SpringUtils.getBean(WxMaService.class).getQrcodeService();
        //"release"
        File qrCode = qrcodeService.createWxaCodeUnlimit("100", "pages/pay/pay", false, "trial", 430,
                true, null, false);
        MultipartFile multipartFile = FileUtils.getInstance().getMultipartFile(qrCode);
        TencentCosHandler tencentCosHandler = SpringUtils.getBean(TencentCosHandler.class);
        UploadResult uploadResult = tencentCosHandler.cdnUpload(multipartFile);
        return R.ok("https://" + uploadResult.getBucketName() + tencentCosHandler.getCdnUrl() + uploadResult.getKey());
    }

    /**
     * 是否已报名
     * @author DB
     * @since 2024/4/10
     * @param openId openId
     * @return R<Boolean>
     */
    @ApiOperation("是否已报名")
    @GetMapping("/haveSummitApply")
    public R<Boolean> haveSummitApply(@RequestParam @ApiParam("openId") String openId) {
        long count = summitApplyService.count(QueryWrapper.create().where(SUMMIT_APPLY.OPEN_ID.eq(openId)));
        return R.ok(count > 0);
    }

    /**
     * 峰会报名
     * @author DB
     * @since 2024/4/10
     * @param bo 请求参数
     * @return R<String>
     */
    @ApiOperation("峰会报名")
    @PostMapping("/summitApply")
    @Transactional(rollbackFor = Exception.class)
    public R<String> summitApply(@RequestBody @Validated SummitApplyBo bo) {
        long count = summitApplyService.count(QueryWrapper.create().where(SUMMIT_APPLY.OPEN_ID.eq(bo.getOpenId())));
        if (count > 0) {
            throw new ServiceException("您已报名，请勿重复提交!");
        }
        SummitApply summitApply = BeanUtils.mapToClass(bo, SummitApply.class);
        summitApplyService.save(summitApply);
        List<SummitApplyUser> summitApplyUsers = BeanUtils.mapToList(bo.getUsers(), SummitApplyUser.class);
        summitApplyUsers.forEach(item->{
            item.setSummitApplyId(summitApply.getId());
        });
        summitApplyUserService.saveBatch(summitApplyUsers);
        // 企微通知值班人员
        List<String> phoneList = new ArrayList<String>();
        try {
            SpringUtils.getBean(WebHookSendHandler.class)
                    .webHookSendText(WebHookKeyConstant.MARKET_BOT,
                            phoneList,
                            "==========2024峰会报名==========\n" +
                                    "机构" + bo.getStoreName() + "报名成功",
                            true);
        } catch (IOException e) {
            throw new ServiceException("发送消息通知失败!");
        }
        return R.ok();
    }

    /**
     * 导出峰会申请
     * @author DB
     * @since 2024/4/10
     * @param response 响应流
     */
    @ApiOperation(value = "导出峰会申请", notes = "export", produces = "application/octet-stream")
    @GetMapping("/exportSummitApply")
    public void exportSummitApply(HttpServletResponse response) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyExcel没有关系
        String fileName = URLEncoder.encode("峰会报名数据", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=" + fileName + ".xlsx");
        //获取峰会数据
        Map<String, SummitApply> summitApplyMap = summitApplyService.list().stream().collect(Collectors.toMap(SummitApply::getId, item -> item));
        List<SummitApplyDto> summitApplyDtos = summitApplyUserService.listAs(QueryWrapper.create(), SummitApplyDto.class);
        Map<String, List<SummitApplyDto>> summitApplyDtoMap = summitApplyDtos.stream().collect(Collectors.groupingBy(SummitApplyDto::getSummitApplyId));
        summitApplyDtoMap.forEach((key, value) -> {
            SummitApply summitApply = summitApplyMap.get(key);
            value.forEach(item -> {
                BeanUtils.copyBeanProp(item, summitApply);
            });
        });
        EasyExcel.write(response.getOutputStream(), SummitApplyDto.class).sheet("报名信息").doWrite(summitApplyDtos);
    }

}
