package com.zhongshu.card.server.core.service.quest;

import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.net.ResultContent;
import com.zhongshu.card.client.model.quest.*;
import com.zhongshu.card.client.utils.DateUtils;
import com.zhongshu.card.server.core.dao.quest.QuestInfoDao;
import com.zhongshu.card.server.core.dao.quest.QuestionCleanDao;
import com.zhongshu.card.server.core.domain.quest.QuestInfo;
import com.zhongshu.card.server.core.domain.quest.QuestionClean;
import com.zhongshu.card.server.core.util.BeanUtils;
import com.zhongshu.card.server.core.util.ExcelUtils;
import com.zhongshu.card.server.core.util.excel.CommonExeclParam;
import com.zhongshu.card.server.core.util.excel.CommonExeclTd;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author TRX
 * @date 2024/11/29
 */
@Slf4j
@Service
public class QuestService {

    @Value("${quest.psd}")
    public String psd = "";

    @Autowired
    private QuestInfoDao questInfoDao;

    private volatile Long preTime = 0L;

    public ResultContent saveInfo(QuestInfoParam param) {
        preTime = System.currentTimeMillis();
        if (StringUtils.isNotEmpty(param.getUuid())) {
            QuestInfo temp = questInfoDao.findTopByUuid(param.getUuid());
            if (ObjectUtils.isNotEmpty(temp)) {
                return ResultContent.buildFail("不能重复提交哦");
            }
        }
        QuestInfo entity = new QuestInfo();
        BeanUtils.copyProperties(param, entity);
        try {
            Object data = param.getData();
            if (data != null) {
                int code = data.hashCode();
                entity.setCode(code);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        questInfoDao.save(entity);
        return ResultContent.buildSuccess();
    }

    public ResultContent updateInfo(QuestInfoUpdateParam param) {
        QuestInfo entity = questInfoDao.findTopById(param.getId());
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail("数据不存在");
        }
        if (StringUtils.isEmpty(param.getPsd())) {
            return ResultContent.buildFail("操作密码为空");
        }
        if (!param.getPsd().equals(psd)) {
            return ResultContent.buildFail("密码错误");
        }

        BeanUtils.copyProperties(param, entity);
        questInfoDao.save(entity);
        return ResultContent.buildSuccess();
    }

    public ResultContent<Page<QuestInfoModel>> page(QuestInfoSearch param, Pageable pageable) {
        if (StringUtils.isEmpty(param.getPsd())) {
            return ResultContent.buildFail("操作密码为空");
        }
        if (!param.getPsd().equals(psd)) {
            return ResultContent.buildFail("密码错误");
        }
        List<Long> times = param.getTimes();
        if (ObjectUtils.isNotEmpty(times) && times.size() == 2) {
            Long startTime = times.get(0);
            startTime = DateUtils.getDayStartTime(startTime);
            Long endTime = times.get(1);
            endTime = DateUtils.getDayEndTime(endTime);
            param.setStartTime(startTime);
            param.setEndTime(endTime);
        }
        Page<QuestInfo> page = questInfoDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.concurrent2PageModel(page, this::toModel));
    }

    public ResultContent deleteById(PsdParam param) {
        Assert.hasText(param.getPsd(), "psd不能为空");
        if (!param.getPsd().equals(psd)) {
            return ResultContent.buildFail("密码错误");
        }
        QuestInfo entity = questInfoDao.findTopById(param.getId());
        if (ObjectUtils.isEmpty(entity)) {
            return ResultContent.buildFail("数据不存在");
        }
        questInfoDao.delete(entity);
        return ResultContent.buildSuccess();
    }

    public void exportData(HttpServletRequest request, HttpServletResponse response, QuestInfoSearch param) throws Exception {
        Assert.hasText(param.getPsd(), "psd不能为空");
        if (!param.getPsd().equals(psd)) {
            throw new Exception("密码错误");
        }
        Pageable pageable = PageRequest.of(0, Integer.MAX_VALUE);
        Page<QuestInfo> page = questInfoDao.page(pageable, param);
        List<Map<String, Object>> maps = new ArrayList<>();

        HashMap<String, String> titleMap = new HashMap<>();
        List<QuestTitleModel> titles = new ArrayList<>();
        if (page.getContent() != null) {
            List<QuestInfo> list = page.getContent();
            maps = list.parallelStream().map(it -> {
                Map<String, Object> map = new HashMap<>();
                try {
                    Object data = it.getData();
                    if (data != null) {
                        List<LinkedHashMap> linkedHashMaps = (List<LinkedHashMap>) data;
                        for (LinkedHashMap linkedHashMap : linkedHashMaps) {
                            String questionId = linkedHashMap.get("questionId").toString();
                            if (!titleMap.containsKey(questionId)) {
                                QuestTitleModel titleModel = new QuestTitleModel();
                                titleModel.setQuestionId(questionId);
                                String question = linkedHashMap.get("question").toString();
                                titleModel.setQuestion(question);
                                titles.add(titleModel);
                                titleMap.put(questionId, question);
                            }
                            Object answer = linkedHashMap.get("answer");
                            String value = "";
                            if (answer != null) {
                                if (answer instanceof LinkedHashMap<?, ?>) {
                                    LinkedHashMap tempMap = (LinkedHashMap) answer;
                                    value = tempMap.get("value").toString();
                                    if (tempMap.containsKey("supplementary")) {
                                        if (StringUtils.isNotEmpty(value)) {
                                            value += "  补充: " + tempMap.get("supplementary").toString();
                                        } else {
                                            value += tempMap.get("supplementary").toString();
                                        }
                                    }
                                } else if (answer instanceof String) {
                                    value = answer.toString();
                                } else {
                                    value = answer.toString();
                                }
                            }
                            map.put(questionId, value);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                map.put("timeStr", DateUtils.paresTime(it.getCreateTime(), DateUtils.patternyyyyMis));
                return map;
            }).collect(Collectors.toList());
        }

        CommonExeclParam execlParam = new CommonExeclParam();
        execlParam.setTitle(String.format("问卷调查"));
        execlParam.setStartRow(2);
        execlParam.setDatas(maps);
        List<CommonExeclTd> tds = new ArrayList<>();
        for (QuestTitleModel titleModel : titles) {
            tds.add(CommonExeclTd.build(titleModel.getQuestion(), titleModel.getQuestionId(), 8));
        }
        tds.add(CommonExeclTd.build("时间", "timeStr"));
        execlParam.setTds(tds);
        ExcelUtils.commonExecuteExcel(request, response, execlParam);
    }

    private QuestInfoModel toModel(QuestInfo entity) {
        QuestInfoModel model = new QuestInfoModel();
        if (ObjectUtils.isNotEmpty(entity)) {
            BeanUtils.copyProperties(entity, model);
        }
        return model;
    }
}
