package com.cyksj.service.mange.form.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.mapper.manage.form.*;
import com.cyksj.model.dto.FormTemplateDataDto;
import com.cyksj.model.entity.FormFields;
import com.cyksj.model.entity.FormFieldsDefault;
import com.cyksj.model.entity.FormTemplate;
import com.cyksj.model.entity.QuestionnairePromotion;
import com.cyksj.model.views.FormSubmitDataView;
import com.cyksj.service.mange.form.FormService;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.util.MapBuilder;
import com.ejlchina.searcher.util.MapUtils;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/*
 *项目名: netflix
 *文件名: FormServiceImpl
 *创建者: JavaZou
 *创建时间:2023/6/12 15:58
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FormServiceImpl implements FormService {
	private final FormFieldsMapper formFieldsMapper;

	private final FormFieldsDataMapper formFieldsDataMapper;

	private final FormTemplateMapper formTemplateMapper;

	private final FormFieldsDefaultMapper formFieldsDefaultMapper;

	private final QuestionnairePromotionMapper questionnairePromotionMapper;

	private final BeanSearcher beanSearcher;

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void saveOrUpdateTemplateAndRelationFields(FormTemplateDataDto dataDto) {
		Long templateId = saveOrUpdateTemplate(dataDto.getId(), dataDto.getName(), dataDto.getDescStr());

		saveOrUpdateTemplateFields(templateId, dataDto.getFormFieldsList());
	}

	@Override
	public void exportQuestionInfo(Long promotionId, Date start, Date end, HttpServletResponse response) throws Exception {
		QuestionnairePromotion promotion = questionnairePromotionMapper.selectById(promotionId);
		if (promotion == null) throw BusinessRuntimeException.getInstance("问卷活动不存在");
		String fileName = promotion.getName();
		response.setContentType("application/x-download");
		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Content-disposition",
				"attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO-8859-1") + ExcelTypeEnum.XLS.getValue());
		List<FormFields> formFields = formFieldsMapper.selectList(new LambdaQueryWrapper<FormFields>().eq(FormFields::getTemplateId, promotion.getTemplateId()).orderByAsc(FormFields::getSorted));
		List<List<String>> data = data(promotionId, formFields, start, end);
		EasyExcel.write(response.getOutputStream())
				// 这里放入动态头
				.head(head(formFields)).sheet("问卷信息")
				// 当然这里数据也可以用 List<List<String>> 去传入
				.doWrite(data);
	}

	@Override
	public void saveOrUpdateTemplateFieldsValue(List<FormFieldsDefault> values) {
		values.forEach(formFieldsDefault ->{
			FormFieldsDefault dbFieldDefault = formFieldsDefaultMapper.selectOne(Wrappers.lambdaQuery(FormFieldsDefault.class)
					.eq(FormFieldsDefault::getFieldsId, formFieldsDefault.getFieldsId()).last("limit 1"));
			if (dbFieldDefault == null){
				formFieldsDefaultMapper.insert(formFieldsDefault);
				return;
			}
			formFieldsDefault.setId(dbFieldDefault.getId());
			formFieldsDefaultMapper.updateById(formFieldsDefault);
		});
	}

	public Long saveOrUpdateTemplate(Long templateId, String name, String descStr) {
		FormTemplate formTemplate;
		if (templateId == null) {
			formTemplate = new FormTemplate();
			formTemplate.setName(name);
			formTemplate.setDescStr(descStr);
			formTemplateMapper.insert(formTemplate);
			return formTemplate.getId();
		}
		formTemplate = formTemplateMapper.selectById(templateId);
		formTemplate.setName(name);
		formTemplate.setDescStr(descStr);
		formTemplateMapper.updateById(formTemplate);
		return formTemplate.getId();
	}

	private void saveOrUpdateTemplateFields(Long templateId, List<FormFields> formFieldsList) {
		List<Long> filedIds = new ArrayList<>();
		formFieldsList.forEach(field -> {
			Long fieldId = field.getId();
			if (fieldId == null) {
				field.setTemplateId(templateId);
				formFieldsMapper.insert(field);
			} else {
				formFieldsMapper.updateById(field);
			}
			filedIds.add(fieldId);
		});

		formFieldsMapper.delete(Wrappers.lambdaQuery(FormFields.class)
				.eq(FormFields::getTemplateId, templateId)
				.notIn(FormFields::getId, filedIds));
	}


	private List<List<String>> head(List<FormFields> formFields) {
		List<List<String>> headTitles = new ArrayList<>();
		formFields.forEach((field) -> {
			headTitles.add(Lists.newArrayList(field.getFieldsName()));
		});
		headTitles.add(Lists.newArrayList("用户id"));
		headTitles.add(Lists.newArrayList("用户名"));
		headTitles.add(Lists.newArrayList("提交时间"));
		return headTitles;
	}

	private List<List<String>> data(Long promotionId, List<FormFields> formFields, Date start, Date end) {
//		List<FormFieldsData> fieldsDataList = formFieldsDataMapper.selectList(new LambdaQueryWrapper<FormFieldsData>().eq(FormFieldsData::getPromotionId, promotionId).eq(FormFieldsData::getDeleted, true).orderByAsc(FormFieldsData::getSorted));
		String timeSql = StrUtil.EMPTY;
		if (start != null) {
			timeSql += String.format(" and fd.created_time >= '%s'", start);
		}
		if (end != null) {
			timeSql += String.format(" and fd.created_time < '%s'", end);
		}
		MapBuilder builder = MapUtils.builder()
				.field(FormSubmitDataView::getPromotionId, promotionId)
				.orderBy(FormSubmitDataView::getSorted).asc();
		if (StrUtil.isNotBlank(timeSql)) {
			builder.put("time_sql", timeSql);
		}
		List<FormSubmitDataView> formSubmitDataViews = beanSearcher.searchAll(FormSubmitDataView.class, builder.build());
		if (formSubmitDataViews.isEmpty()) {
			throw BusinessRuntimeException.getInstance("暂无数据");
		}
		List<List<String>> contentList = Lists.newArrayList();
		Map<Long, List<FormSubmitDataView>> collect = formSubmitDataViews.stream().collect(Collectors.groupingBy(FormSubmitDataView::getGroupsId));
		collect.forEach((groupsId, answers) -> {
			Map<Long, List<FormSubmitDataView>> fieldsValueMap = answers.stream().collect(Collectors.groupingBy(FormSubmitDataView::getFieldsId));
			ArrayList<String> dataList = new ArrayList<>();
			formFields.forEach(fields -> {
				List<FormSubmitDataView> values = fieldsValueMap.get(fields.getId());
				if (CollUtil.isEmpty(values)) {
					dataList.add(StrUtil.EMPTY);
					return;
				}
				dataList.add(values.get(0).getContent());
			});

			dataList.add(answers.get(0).getUserId().toString());
			dataList.add(answers.get(0).getNickname());
			dataList.add(DateUtil.format(answers.get(answers.size() - 1).getCreatedTime(), "yyyy-MM-dd HH:mm:ss"));
			contentList.add(dataList);
		});
		return contentList;
	}
}
