package ink.wgink.module.form.service.report.impl;

import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.base.SystemException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.module.form.enums.design.FormStatusEnum;
import ink.wgink.module.form.pojo.pos.design.FormPO;
import ink.wgink.module.form.service.design.IFormFieldService;
import ink.wgink.module.form.service.design.IFormService;
import ink.wgink.module.form.service.report.IFormReportRouteService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

/**
 * @ClassName: FormReportServiceImpl
 * @Description: 表单上报
 * @Author: wanggeng
 * @Date: 2022/3/10 7:33 PM
 * @Version: 1.0
 */
@Service
public class FormReportRouteServiceImpl extends DefaultBaseService implements IFormReportRouteService {

    @Autowired
    private IFormService formService;
    @Autowired
    private IFormFieldService formFieldService;
    private Configuration configuration = new Configuration(Configuration.getVersion());

    @PostConstruct
    private void init() {
        StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
        configuration.setTemplateLoader(stringTemplateLoader);
        configuration.setDefaultEncoding(ISystemConstant.CHARSET_UTF8);
    }

    @Override
    public void save(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        Map<String, Object> modal = getHashMap(10);
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getSavePageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void save(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Map<String, Object> modal) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getSavePageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void update(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        Map<String, Object> modal = getHashMap(10);
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getUpdatePageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void update(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Map<String, Object> modal) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getUpdatePageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void show(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        Map<String, Object> modal = getHashMap(10);
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getShowPageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void show(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Map<String, Object> modal) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getShowPageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void appSave(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        Map<String, Object> modal = getHashMap(10);
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getAppSavePageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void appSave(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Map<String, Object> modal) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getAppSavePageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void appUpdate(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        Map<String, Object> modal = getHashMap(10);
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getAppUpdatePageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void appUpdate(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Map<String, Object> modal) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getAppUpdatePageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void appShow(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        Map<String, Object> modal = getHashMap(10);
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getAppShowPageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    @Override
    public void appShow(String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Map<String, Object> modal) {
        FormPO formPO = getFormPO(formCode, formVersion);
        if (formPO == null) {
            return;
        }
        setModal(formPO, modal);
        showPage(modal, formCode, formPO.getAppShowPageCode(), httpSession, httpServletRequest, httpServletResponse);
    }

    /**
     * 展示页面
     *
     * @param modal
     * @param formCode
     * @param pageCode
     * @param httpSession
     * @param httpServletRequest
     * @param httpServletResponse
     */
    @Override
    public void showPage(Map<String, Object> modal, String formCode, String pageCode, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        httpServletResponse.setContentType("text/html; charset=" + ISystemConstant.CHARSET_UTF8);
        try {
            Template template = getTemplate(formCode, pageCode);
            PrintWriter out = httpServletResponse.getWriter();
            template.process(modal, out);
        } catch (IOException e) {
            httpServletResponse.setStatus(HttpStatus.NOT_FOUND.value());
        } catch (TemplateException e) {
            LOG.error(e.getMessage(), e);
            throw new SystemException("模板错误");
        }
    }

    /**
     * 设置模型
     *
     * @param formPO
     * @param modal
     * @return
     */
    @Override
    public void setModal(FormPO formPO, Map<String, Object> modal) {
        modal.put("contextPath", httpServletRequest.getContextPath() + "/");
        modal.put("formName", formPO.getFormName());
        modal.put("formCode", formPO.getFormCode());
        modal.put("formVersion", formPO.getFormVersion());
    }

    /**
     * 获取表单
     *
     * @param formCode
     * @param formVersion
     * @return
     */
    private FormPO getFormPO(String formCode, Integer formVersion) {
        FormPO formPO = formService.getPOByCodeAndVersion(formCode, formVersion);
        if (formPO == null) {
            httpServletResponse.setStatus(HttpStatus.NOT_FOUND.value());
            return null;
        }
        if (!StringUtils.equals(formPO.getFormStatus(), FormStatusEnum.ACTIVE.getValue())) {
            LOG.error("表单 {} 未激活", formCode);
            httpServletResponse.setStatus(HttpStatus.NOT_FOUND.value());
            return null;
        }
        return formPO;
    }

    private Template getTemplate(String templateName, String templateCode) throws IOException {
        return new Template(templateName, templateCode, configuration);
    }

}
