package com.philisense.www.api.processor.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.philisense.www.api.generator.impl.WordCombGenerator;
import com.philisense.www.api.processor.AbstractVcodeProcessor;
import com.philisense.www.builder.WordCombBuilder;
import com.philisense.www.consts.ErrorConst;
import com.philisense.www.dto.wordcomb.Point;
import com.philisense.www.dto.wordcomb.WordComb;
import com.philisense.www.enums.VcodeType;
import com.philisense.www.exception.UtilsException;
import com.philisense.www.utils.ImageConvertUtils;
import com.philisense.www.utils.ServletUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.ServletWebRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class WordCombProcessor extends AbstractVcodeProcessor<WordComb> {
    private static final Logger log = LoggerFactory.getLogger(WordCombProcessor.class);

    @Resource
    private ObjectMapper objectMapper;

    public WordCombProcessor(WordCombGenerator vcodeGenerator) {
        super(VcodeType.WORD_COMB, vcodeGenerator);
    }

    @Override
    protected void preValidate(ServletWebRequest request) throws UtilsException {

        String pointsJson = request.getParameter("points");
        if (StringUtils.isBlank(pointsJson)) {
            throw new UtilsException("参数points不能为空", ErrorConst.ERR_CODE);
        }
    }

    @Override
    protected void validate(ServletWebRequest request, Object savedValue) throws UtilsException {

        String pointsJson = request.getParameter("points");
        List<Point> inputPoints = null;
        try {
            inputPoints = objectMapper.readValue(pointsJson, new TypeReference<>() {});
        } catch (JsonProcessingException e) {
            log.error("参数points反序列化失败", e);
            throw new UtilsException("参数points反序列化失败", ErrorConst.ERR_CODE);
        }

        // 现在开始校验文字点选位置和顺序
        List<Point> points = (List)savedValue;
        // 执行比较逻辑
        for (int i = 0; i < points.size(); i++) {
            int x = points.get(i).getX();
            int y = points.get(i).getY();
            int inputX = inputPoints.get(i).getX();
            int inputY = inputPoints.get(i).getY();
            int hanziSize = WordCombBuilder.HAN_ZI_SIZE;
            if (x - hanziSize > inputX
                    || inputX > x + hanziSize
                    || y - hanziSize > inputY
                    || inputY > y + hanziSize) {
                throw new UtilsException("文字点选校验失败", ErrorConst.ERR_CODE);
            }
        }

    }

    @Override
    protected Object extractVcodeValueToBeSaved(WordComb wordComb) {
        return wordComb.getPoints();
    }

    @Override
    protected void send(ServletWebRequest request, WordComb wordComb) throws Exception {
        HttpServletResponse response = request.getResponse();
        Map<String, Object> result = new HashMap<>();
        result.put("success", true);
        result.put("message", "生成成功！");
        Map<String, Object> data = new HashMap<>();
        data.put("image", ImageConvertUtils.toDataUri(wordComb.getImage(), "png"));
        data.put("words", wordComb.getWordList());
        data.put("vcodeKey", wordComb.getKey());
        result.put("data", data);
        log.info("points = {}", wordComb.getPoints());
        ServletUtils.renderString(response, objectMapper.writeValueAsString(result));
    }
}
