package com.dayou.utils;

import com.alibaba.fastjson.JSON;
import com.dayou.dto.ItemData;
import com.dayou.entity.PersonalExample;
import com.dayou.exception.ErrorCode;
import com.dayou.vo.CompareExampleItemVO;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
import org.springframework.core.io.Resource;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 类说明：个贷工具
 *
 * @author: wucl
 * @since: 2024/3/7
 * created with IntelliJ IDEA.
 */
public class PersonalUtils {

    /**
     * 可比实例转对象
     * @param targetId
     * @param calculateId
     * @param originData
     * @return
     */
    public static List<PersonalExample> example2Entity(Long targetId, Long calculateId, List<CompareExampleItemVO> originData){
        PersonalExample exampleA= new PersonalExample(targetId,calculateId,true);
        PersonalExample exampleB= new PersonalExample(targetId,calculateId,true);
        PersonalExample exampleC= new PersonalExample(targetId,calculateId,true);
        PersonalExample target = new PersonalExample(targetId,calculateId,false);
        originData.stream().forEach(x->{
            String index = x.getIndex();
            switch (index){
                case "坐落":
                    exampleA.setLocation(JSON.toJSONString(x.getCompareA()));
                    exampleB.setLocation(JSON.toJSONString(x.getCompareB()));
                    exampleC.setLocation(JSON.toJSONString(x.getCompareC()));
                    target.setLocation(JSON.toJSONString(x.getTarget()));
                    break;
                case "总价(元)":
                    exampleA.setAmount(JSON.toJSONString(x.getCompareA()));
                    exampleB.setAmount(JSON.toJSONString(x.getCompareB()));
                    exampleC.setAmount(JSON.toJSONString(x.getCompareC()));
                    target.setAmount(JSON.toJSONString(x.getTarget()));
                    break;
                case "单价(元)":
                    exampleA.setPrice(JSON.toJSONString(x.getCompareA()));
                    exampleB.setPrice(JSON.toJSONString(x.getCompareB()));
                    exampleC.setPrice(JSON.toJSONString(x.getCompareC()));
                    target.setPrice(JSON.toJSONString(x.getTarget()));
                    break;
                case "市场状况":
                    exampleA.setMarketInfo(JSON.toJSONString(x.getCompareA()));
                    exampleB.setMarketInfo(JSON.toJSONString(x.getCompareB()));
                    exampleC.setMarketInfo(JSON.toJSONString(x.getCompareC()));
                    target.setMarketInfo(JSON.toJSONString(x.getTarget()));
                    break;
                case "所在楼栋":
                    exampleA.setOrientation(JSON.toJSONString(x.getCompareA()));
                    exampleB.setOrientation(JSON.toJSONString(x.getCompareB()));
                    exampleC.setOrientation(JSON.toJSONString(x.getCompareC()));
                    target.setOrientation(JSON.toJSONString(x.getTarget()));
                    break;
                case "建筑面积(平)":
                    exampleA.setAcreage(JSON.toJSONString(x.getCompareA()));
                    exampleB.setAcreage(JSON.toJSONString(x.getCompareB()));
                    exampleC.setAcreage(JSON.toJSONString(x.getCompareC()));
                    target.setAcreage(JSON.toJSONString(x.getTarget()));
                    break;
                case "楼层/总楼层":
                    exampleA.setAtFloor(JSON.toJSONString(x.getCompareA()));
                    exampleB.setAtFloor(JSON.toJSONString(x.getCompareB()));
                    exampleC.setAtFloor(JSON.toJSONString(x.getCompareC()));
                    target.setAtFloor(JSON.toJSONString(x.getTarget()));
                    break;
                case "户型":
                    exampleA.setHouseType(JSON.toJSONString(x.getCompareA()));
                    exampleB.setHouseType(JSON.toJSONString(x.getCompareB()));
                    exampleC.setHouseType(JSON.toJSONString(x.getCompareC()));
                    target.setHouseType(JSON.toJSONString(x.getTarget()));
                    break;
                case "室内装饰":
                    exampleA.setDecoration(JSON.toJSONString(x.getCompareA()));
                    exampleB.setDecoration(JSON.toJSONString(x.getCompareB()));
                    exampleC.setDecoration(JSON.toJSONString(x.getCompareC()));
                    target.setDecoration(JSON.toJSONString(x.getTarget()));
                    break;
                case "其他":
                    exampleA.setOtherInfo(JSON.toJSONString(x.getCompareA()));
                    exampleB.setOtherInfo(JSON.toJSONString(x.getCompareB()));
                    exampleC.setOtherInfo(JSON.toJSONString(x.getCompareC()));
                    target.setOtherInfo(JSON.toJSONString(x.getTarget()));
                case "权重":
                    exampleA.setWeight(JSON.toJSONString(x.getCompareA()));
                    exampleB.setWeight(JSON.toJSONString(x.getCompareB()));
                    exampleC.setWeight(JSON.toJSONString(x.getCompareC()));
                case "修正后价格":
                    exampleA.setFixPrice(JSON.toJSONString(x.getCompareA()));
                    exampleB.setFixPrice(JSON.toJSONString(x.getCompareB()));
                    exampleC.setFixPrice(JSON.toJSONString(x.getCompareC()));
                    target.setFixPrice(JSON.toJSONString(x.getTarget()));
                    break;
            }
        });
        List<PersonalExample> entities = new ArrayList<>();
        entities.add(exampleA);
        entities.add(exampleB);
        entities.add(exampleC);
        entities.add(target);
        return entities;
    }

    /**
     * 对象转可比实例
     * @param examples
     * @return
     */
    public static List<CompareExampleItemVO> entity2Example(List<PersonalExample> examples) {
        List<CompareExampleItemVO> vos = new ArrayList<>();
        CompareExampleItemVO location = new CompareExampleItemVO(0,"坐落");
        CompareExampleItemVO amount = new CompareExampleItemVO(1,"总价(元)");
        CompareExampleItemVO price = new CompareExampleItemVO(2,"单价(元)");
        CompareExampleItemVO marketInfo = new CompareExampleItemVO(3,"市场状况");
        CompareExampleItemVO orientation = new CompareExampleItemVO(4,"所在楼栋");
        CompareExampleItemVO acreage = new CompareExampleItemVO(5,"建筑面积(平)");
        CompareExampleItemVO atFloor = new CompareExampleItemVO(6,"楼层/总楼层");
        CompareExampleItemVO houseType = new CompareExampleItemVO(7,"户型");
        CompareExampleItemVO decoration = new CompareExampleItemVO(8,"室内装饰");
        CompareExampleItemVO otherInfo = new CompareExampleItemVO(9,"其他");
        CompareExampleItemVO weight = new CompareExampleItemVO(10,"权重");
        CompareExampleItemVO fixPrice = new CompareExampleItemVO(11,"修正后价格");

        for (int i = 0; i<examples.size() ; i++){
            switch (i){
                case 0:
                    location.setCompareA(JSON.parseObject(examples.get(i).getLocation(), ItemData.class));
                    amount.setCompareA(JSON.parseObject(examples.get(i).getAmount(), ItemData.class));
                    price.setCompareA(JSON.parseObject(examples.get(i).getPrice(), ItemData.class));
                    marketInfo.setCompareA(JSON.parseObject(examples.get(i).getMarketInfo(), ItemData.class));
                    orientation.setCompareA(JSON.parseObject(examples.get(i).getOrientation(), ItemData.class));
                    acreage.setCompareA(JSON.parseObject(examples.get(i).getAcreage(), ItemData.class));
                    atFloor.setCompareA(JSON.parseObject(examples.get(i).getAtFloor(), ItemData.class));
                    houseType.setCompareA(JSON.parseObject(examples.get(i).getHouseType(), ItemData.class));
                    decoration.setCompareA(JSON.parseObject(examples.get(i).getDecoration(), ItemData.class));
                    otherInfo.setCompareA(JSON.parseObject(examples.get(i).getOtherInfo(), ItemData.class));
                    weight.setCompareA(JSON.parseObject(examples.get(i).getWeight(), ItemData.class));
                    fixPrice.setCompareA(JSON.parseObject(examples.get(i).getFixPrice(), ItemData.class));
                    break;
                case 1:
                    location.setCompareB(JSON.parseObject(examples.get(i).getLocation(), ItemData.class));
                    amount.setCompareB(JSON.parseObject(examples.get(i).getAmount(), ItemData.class));
                    price.setCompareB(JSON.parseObject(examples.get(i).getPrice(), ItemData.class));
                    marketInfo.setCompareB(JSON.parseObject(examples.get(i).getMarketInfo(), ItemData.class));
                    orientation.setCompareB(JSON.parseObject(examples.get(i).getOrientation(), ItemData.class));
                    acreage.setCompareB(JSON.parseObject(examples.get(i).getAcreage(), ItemData.class));
                    atFloor.setCompareB(JSON.parseObject(examples.get(i).getAtFloor(), ItemData.class));
                    houseType.setCompareB(JSON.parseObject(examples.get(i).getHouseType(), ItemData.class));
                    decoration.setCompareB(JSON.parseObject(examples.get(i).getDecoration(), ItemData.class));
                    otherInfo.setCompareB(JSON.parseObject(examples.get(i).getOtherInfo(), ItemData.class));
                    weight.setCompareB(JSON.parseObject(examples.get(i).getWeight(), ItemData.class));
                    fixPrice.setCompareB(JSON.parseObject(examples.get(i).getFixPrice(), ItemData.class));
                case 2:
                    location.setCompareC(JSON.parseObject(examples.get(i).getLocation(), ItemData.class));
                    amount.setCompareC(JSON.parseObject(examples.get(i).getAmount(), ItemData.class));
                    price.setCompareC(JSON.parseObject(examples.get(i).getPrice(), ItemData.class));
                    marketInfo.setCompareC(JSON.parseObject(examples.get(i).getMarketInfo(), ItemData.class));
                    orientation.setCompareC(JSON.parseObject(examples.get(i).getOrientation(), ItemData.class));
                    acreage.setCompareC(JSON.parseObject(examples.get(i).getAcreage(), ItemData.class));
                    atFloor.setCompareC(JSON.parseObject(examples.get(i).getAtFloor(), ItemData.class));
                    houseType.setCompareC(JSON.parseObject(examples.get(i).getHouseType(), ItemData.class));
                    decoration.setCompareC(JSON.parseObject(examples.get(i).getDecoration(), ItemData.class));
                    otherInfo.setCompareC(JSON.parseObject(examples.get(i).getOtherInfo(), ItemData.class));
                    weight.setCompareC(JSON.parseObject(examples.get(i).getWeight(), ItemData.class));
                    fixPrice.setCompareC(JSON.parseObject(examples.get(i).getFixPrice(), ItemData.class));
                case 3:
                    location.setTarget(JSON.parseObject(examples.get(i).getLocation(), ItemData.class));
                    amount.setTarget(JSON.parseObject(examples.get(i).getAmount(), ItemData.class));
                    price.setTarget(JSON.parseObject(examples.get(i).getPrice(), ItemData.class));
                    marketInfo.setTarget(JSON.parseObject(examples.get(i).getMarketInfo(), ItemData.class));
                    orientation.setTarget(JSON.parseObject(examples.get(i).getOrientation(), ItemData.class));
                    acreage.setTarget(JSON.parseObject(examples.get(i).getAcreage(), ItemData.class));
                    atFloor.setTarget(JSON.parseObject(examples.get(i).getAtFloor(), ItemData.class));
                    houseType.setTarget(JSON.parseObject(examples.get(i).getHouseType(), ItemData.class));
                    decoration.setTarget(JSON.parseObject(examples.get(i).getDecoration(), ItemData.class));
                    otherInfo.setTarget(JSON.parseObject(examples.get(i).getOtherInfo(), ItemData.class));
                    weight.setTarget(JSON.parseObject(examples.get(i).getWeight(), ItemData.class));
                    fixPrice.setTarget(JSON.parseObject(examples.get(i).getFixPrice(), ItemData.class));
                    break;
            }
        }
        vos.add(location);vos.add(amount);vos.add(price);vos.add(marketInfo);vos.add(orientation);vos.add(acreage);vos.add(atFloor);vos.add(houseType);vos.add(decoration);vos.add(otherInfo);vos.add(weight);vos.add(fixPrice);
        return vos;
    }


    /**
     * 添加公章
     * @param inputStream 需要盖章的文件流
     * @param resource   公章图片资源
     * @param originFilePath 原文件路经
     */
    public static void addPublicStamp(InputStream inputStream,Resource resource,String originFilePath){
        try {
            XWPFDocument document = new XWPFDocument(inputStream);
            XWPFRun targetRun = stampingPoint(document,1);
            if (targetRun == null){
                targetRun = stampingPoint(document,13);
                if(targetRun == null){
                    return;
                }
            }
            targetRun.addPicture(resource.getInputStream(), XWPFDocument.PICTURE_TYPE_PNG, "stamp.png", Units.toEMU(150), Units.toEMU(150));
            CTDrawing drawing = targetRun.getCTR().getDrawingArray(0);
            CTGraphicalObject graphic = drawing.getInlineArray(0).getGraphic();
            //拿到新插入的图片替换添加CTAnchor 设置浮动属性 删除inline属性
            CTAnchor anchor = getAnchorWithGraphic(graphic, "stamp",
                    Units.toEMU(150), Units.toEMU(150),//图片大小
                    Units.toEMU(260), Units.toEMU(-90), true);//相对当前段落位置 需要计算段落已有内容的左偏移
            drawing.setAnchorArray(new CTAnchor[]{anchor});//添加浮动属性
            drawing.removeInline(0);//删除行内属性

            File absoluteFile = new File(originFilePath);
            FileOutputStream out = new FileOutputStream(absoluteFile);
            document.write(out);
            out.close();
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InvalidFormatException e) {
            throw new RuntimeException(e);
        }
    }

    private static XWPFRun stampingPoint( XWPFDocument document,int point) throws IOException {
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        XWPFParagraph paragraph = paragraphs.get(paragraphs.size() - point);
        List<XWPFRun> runs = paragraph.getRuns();
        XWPFRun targetRun = null;
        if (runs.size()>0){
            targetRun = runs.get(runs.size() - 1);
            if (targetRun.getEmbeddedPictures().size()==0){
                if (DateUtils.checkIsDate(targetRun.toString())){
                    return targetRun;
                }
            }else {
                ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"文件已加盖公章.");
            }
        }
        return null;
    }

    /**
     * @param ctGraphicalObject 图片数据
     * @param deskFileName      图片描述
     * @param width             宽
     * @param height            高
     * @param leftOffset        水平偏移 left
     * @param topOffset         垂直偏移 top
     * @param behind            文字上方，文字下方
     * @return
     * @throws Exception
     */
    private static CTAnchor getAnchorWithGraphic(CTGraphicalObject ctGraphicalObject,
                                                String deskFileName, int width, int height,
                                                int leftOffset, int topOffset, boolean behind) {
        System.out.println(">>width>>"+width+"; >>height>>>>"+height);
        String anchorXML =
                "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
                        + "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"" + ((behind) ? 1 : 0) + "\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
                        + "<wp:simplePos x=\"0\" y=\"0\"/>"
                        + "<wp:positionH relativeFrom=\"column\">"
                        + "<wp:posOffset>" + leftOffset + "</wp:posOffset>"
                        + "</wp:positionH>"
                        + "<wp:positionV relativeFrom=\"paragraph\">"
                        + "<wp:posOffset>" + topOffset + "</wp:posOffset>" +
                        "</wp:positionV>"
                        + "<wp:extent cx=\"" + width + "\" cy=\"" + height + "\"/>"
                        + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
                        + "<wp:wrapNone/>"
                        + "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\"" + deskFileName + "\"/><wp:cNvGraphicFramePr/>"
                        + "</wp:anchor>";

        CTDrawing drawing = null;
        try {
            drawing = CTDrawing.Factory.parse(anchorXML);
        } catch (XmlException e) {
            e.printStackTrace();
        }
        CTAnchor anchor = drawing.getAnchorArray(0);
        anchor.setGraphic(ctGraphicalObject);
        return anchor;
    }

}
