package com.izouma.wenlvju.service.performance;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.izouma.wenlvju.domain.performance.Participant;
import com.izouma.wenlvju.domain.performance.Programme;
import com.izouma.wenlvju.dto.PageQuery;
import com.izouma.wenlvju.exception.BusinessException;
import com.izouma.wenlvju.repo.AwardRepo;
import com.izouma.wenlvju.repo.performance.ParticipantRepo;
import com.izouma.wenlvju.repo.performance.ProgrammeRepo;
import com.izouma.wenlvju.service.storage.StorageService;
import com.izouma.wenlvju.utils.JpaUtils;
import com.izouma.wenlvju.utils.ObjUtils;
import lombok.AllArgsConstructor;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

@Service
@AllArgsConstructor
public class ParticipantService {

    private ParticipantRepo participantRepo;
    private ProgrammeRepo   programmeRepo;
    private AwardRepo       awardRepo;
    private StorageService  storageService;

    public Page<Participant> all(PageQuery pageQuery) {
        return participantRepo.findAll(JpaUtils.toSpecification(pageQuery, Participant.class), JpaUtils.toPageRequest(pageQuery));
    }

    public void batchSave(List<Participant> participants) {
        participants.forEach(participant -> {
            if (participant.getId() != null) {
                Participant orig = participantRepo.findById(participant.getId())
                        .orElseThrow(new BusinessException("无记录"));

                if (!participant.isDel() && StrUtil.isNotEmpty(participant.getIdNo())) {
                    List<Participant> byIdNo = participantRepo.findByIdNoAndPerformanceId(participant.getIdNo(), participant.getPerformanceId());
                    if (CollUtil.isNotEmpty(byIdNo)) {
                        if (byIdNo.size() > 1) {
                            throw new BusinessException("一人只能报一个节目");
                        } else {
                            if (!byIdNo.get(0).getId().equals(participant.getId())) {
                                throw new BusinessException("一人只能报一个节目");
                            }
                        }
                    }
                }

                ObjUtils.merge(orig, participant);
                participantRepo.save(orig);
            } else {
                if (StrUtil.isNotEmpty(participant.getIdNo())) {
                    List<Participant> byIdNo = participantRepo.findByIdNoAndPerformanceId(participant.getIdNo(), participant.getPerformanceId());
                    if (CollUtil.isNotEmpty(byIdNo)) {
                        throw new BusinessException("一人只能报一个节目");
                    }
                }

                participantRepo.save(participant);
            }
        });
    }

    public String createAward(Participant participant, String award) throws IOException {
        BufferedImage shareImg = ImageIO.read(this.getClass().getResourceAsStream("/static/certificate.jpeg"));
        BufferedImage result = new BufferedImage(1100, 778, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = result.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.setComposite(AlphaComposite.SrcOver);
        g.drawImage(shareImg, 0, 0, null);

        // 头像
        if (ObjectUtil.isNotNull(participant.getImg())) {
            BufferedImage avatar = ImageIO.read(new URL(participant.getImg()));
//        int size = Math.min(avatar.getWidth(), avatar.getHeight());
//        BufferedImage subImg = avatar
//                .getSubimage((avatar.getWidth() - size) / 2, (avatar.getHeight() - size) / 2, size, size);
            BufferedImage avatarImg = new BufferedImage(68 * 2, 80 * 2, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2 = avatarImg.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2.setComposite(AlphaComposite.SrcOver);
            g2.setBackground(Color.GREEN);
//        g2.setClip(new Ellipse2D.Float(0, 0, 68 * 2, 76 * 2)); //椭圆
            g2.drawImage(avatar, 0, 0, 68 * 2, 160, null);

            g.drawImage(avatarImg, 420 * 2, 50 * 2, 68 * 2, 160, null);
        }


        // 文字
        g.setColor(new Color(0, 0, 0)); //根据图片的背景设置水印颜色
        Font font = new Font("黑体", Font.PLAIN, 30);
        String content = participant.getName();
        // 加水印
        g.setFont(font);              //设置字体
        //设置水印的坐标
        g.drawString(content, 160, 330);  //画出水印

        String content1 = "在2021“宁艺之星”社会艺术水平考级展演(览)中，表现优";
        //设置水印的坐标
        g.drawString(content1, 215, 390);
        String content2 = "秀，被评为“" + award + "”，特发此证，以资鼓励。";
        g.drawString(content2, 160, 450);

        g.dispose();
        ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
        Thumbnails.of(result)
                .scale(1)
                .outputQuality(.9f)
                .outputFormat("jpg")
                .toOutputStream(out);
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());

        return storageService.uploadFromInputStream(in, "award/" + participant.getId() + ".jpg");
    }

    public void awardByProgrammeId(Long programmeId) {
        List<Participant> participants = participantRepo.findAllByProgrammeId(programmeId);
        if (ObjectUtil.isNull(participants)) {
            return;
        }

        Programme programme = programmeRepo.findById(programmeId).orElseThrow(new BusinessException("无节目"));
        String name = awardRepo.findById(programme.getAwardId()).orElseThrow(new BusinessException("无奖项")).getName();
        List<Participant> result = new ArrayList<>();
        participants.forEach(participant -> {
            if (ObjectUtil.isNull(participant.getAwardImg())) {
                try {
                    participant.setAwardImg(this.createAward(participant, name));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                result.add(participant);
            }
        });

        participantRepo.saveAll(result);
    }

    public void awardByAwardId(Long awardId, Long specialtyId, boolean parent) {
        String award = awardRepo.findById(awardId).orElseThrow(new BusinessException("无奖项")).getName();
        List<Long> programmes;
        if (ObjectUtil.isNull(specialtyId)) {
            programmes = programmeRepo.findAllByAwardId(awardId);
        } else if (parent) {
            programmes = programmeRepo.findAllByAwardIdAndParentSpecialtyId(awardId, specialtyId);
        } else {
            programmes = programmeRepo.findAllByAwardIdAndSpecialtyId(awardId, specialtyId);
        }
        List<Participant> participants = participantRepo.findAllByProgrammeIdIn(programmes);
        List<Participant> result = new ArrayList<>();
        participants.forEach(participant -> {
            if (ObjectUtil.isNull(participant.getAwardImg())) {
                try {
                    participant.setAwardImg(this.createAward(participant, award));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                result.add(participant);
            }
        });
        participantRepo.saveAll(result);
    }
}
