package com.cftech.showroom.appform.web;

import com.alibaba.fastjson.JSONObject;
import com.cftech.base.codingrule.utils.CodingruleUtils;
import com.cftech.common.send.util.CommonSendUtils;
import com.cftech.common.typeappform.model.TypeAppForm;
import com.cftech.core.scope.OrderType;
import com.cftech.core.sql.Conds;
import com.cftech.core.sql.Sort;
import com.cftech.core.util.DateUtils;
import com.cftech.core.util.MpTokenUtil;
import com.cftech.core.util.StringUtils;
import com.cftech.core.util.SystemConfig;
import com.cftech.showroom.appform.model.AppForm;
import com.cftech.showroom.appform.service.AppFormService;
import com.cftech.showroom.appform.util.DocToPdf;
import com.cftech.showroom.explainer.model.Explainer;
import com.cftech.showroom.explainer.service.ExplainerService;
import com.cftech.showroom.relevanter.model.Relevanter;
import com.cftech.showroom.relevanter.service.RelevanterService;
import com.cftech.showroom.sdepartment.model.Sdepartment;
import com.cftech.showroom.sdepartment.service.SdepartmentService;
import com.cftech.showroom.svideo.model.Svideo;
import com.cftech.showroom.svideo.service.SvideoService;
import com.cftech.showroom.visitorCategory.model.VisitorCategory;
import com.cftech.showroom.visitorCategory.service.VisitorCategoryService;
import com.cftech.workshop.template.model.Template;
import com.cftech.workshop.template.service.TemplateService;
import org.mp.api.wxsendmsg.JwTemplateMessageAPI;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.configuration.consts.EsapiConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.File;
import java.text.ParseException;
import java.util.*;

/**
 * @Auther: lisw
 * @Date: 2019/8/1 15:40
 * @Description:
 */
@RestController
@RequestMapping("/mobile/auth/appform")
public class MobileAppFormController {

    @Autowired
    private SdepartmentService sdepartmentService;

    @Autowired
    private VisitorCategoryService visitorCategoryService;

    @Autowired
    private ExplainerService explainerService;

    @Autowired
    private AppFormService appFormService;

    @Autowired
    private SvideoService svideoService;

    @Autowired
    private CodingruleUtils codingruleUtils;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private RelevanterService relevanterService;

    @Autowired
    private MpTokenUtil tokenUtil;

    @Autowired
    private JedisPool jedisPool;



    /**
     * 获取部门
     *
     * @return
     */
    @RequestMapping(value = "getDept", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject getDept() {
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorNo", 0);
        try {
            Conds conds = new Conds();
            conds.equal("del_flag", 0);
            Sort sort = new Sort("sort", OrderType.ASC);

            List<Sdepartment> sdepartmentList = sdepartmentService.fetchSearchByPage(conds, sort, 0, 0);
            for (Sdepartment sdepartment : sdepartmentList) {
                sdepartment.setName(ESAPI.encoder().decodeForHTML(sdepartment.getName()));
            }
            rtnJson.put("datas", sdepartmentList);
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }

        return rtnJson;
    }

    /**
     * 获取来访者类别
     *
     * @return
     */
    @RequestMapping(value = "getvisitorCategory", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject getvisitorCategory() {
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorNo", 0);
        try {
            Conds conds = new Conds();
            conds.equal("del_flag", 0);
            Sort sort = new Sort("sort", OrderType.ASC);
            List<VisitorCategory> visitorCategories = visitorCategoryService.fetchSearchByPage(conds, sort, 0, 0);
            for (VisitorCategory visitorCategory : visitorCategories) {
                visitorCategory.setName(ESAPI.encoder().decodeForHTML(visitorCategory.getName()));
            }
            rtnJson.put("datas", visitorCategories);
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }

        return rtnJson;
    }

    /**
     * 获取讲解人列表
     *
     * @return
     */
    @RequestMapping(value = "getexplainer", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject getexplainer() {
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorNo", 0);
        try {
            Conds conds = new Conds();
            conds.equal("del_flag", 0);
            conds.equal("status", 1);
            Sort sort = new Sort("sort", OrderType.ASC);

            List<Explainer> explainers = explainerService.fetchSearchByPage(conds, sort, 0, 0);
            for (Explainer explainer : explainers) {
                explainer.setName(ESAPI.encoder().decodeForHTML(explainer.getName()));
                explainer.setDescription(ESAPI.encoder().decodeForHTML(explainer.getDescription()));
            }
            rtnJson.put("datas", explainers);
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }
        return rtnJson;
    }

    /**
     *
     */
    @RequestMapping(value = "getAppFormList", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject getAppFormList(String date) {
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorNo", 0);
        try {
            Conds conds = new Conds();
            conds.equal("date(t.reservation_begin_time) ", date);
            conds.notEqual("t.status", "1");
            List<AppForm> appForms = appFormService.fetchSearchByPageMobile(conds, null, 0, 0);
            rtnJson.put("datas", appForms);
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }
        return rtnJson;
    }

    /**
     * 验证时间段是否已被预订
     */
    @RequestMapping(value = "isAppointment", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject appFormSubmit(String beginDateTimeStr, String endDateTimeStr) {
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorNo", 0);
        Integer count = appFormService.isAppointment(beginDateTimeStr, endDateTimeStr);
        if (count != 0) {
            rtnJson.put("errorNo", 1);
        }
        return rtnJson;
    }

    /**
     * 提交展厅申请单
     *
     * @param appForm
     * @return
     */
    @RequestMapping(value = "appFormSubmit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject appFormSubmit(AppForm appForm, String first, String remarks, String keyword1, String keyword2, String keyword3, String paperUrl) {

        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorNo", 0);
        try {
            if (StringUtils.isNotBlank(appForm.getBeginDateTimeStr()) && StringUtils.isNotBlank(appForm.getEndDateTimeStr())) {
                Date beginDate = DateUtils.parseDate(appForm.getBeginDateTimeStr(), "yyyy-MM-dd HH:mm");
                Date endDate = DateUtils.parseDate(appForm.getEndDateTimeStr(), "yyyy-MM-dd HH:mm");
                appForm.setReservationBeginTime(beginDate);
                appForm.setReservationEndTime(endDate);
            }
            Integer count = appFormService.isAppointment(appForm.getBeginDateTimeStr(), appForm.getEndDateTimeStr());
            if (count == 0) {
                Conds conds = new Conds();
                conds.equal("t.del_flag", 0);
                conds.equal("YEAR(t.create_time)", 1900 + new Date().getYear());
                Sort sort = new Sort("t.create_time", OrderType.DESC);
                List<AppForm> appForms = appFormService.fetchSearchByPage(conds, sort, 0, 1);
                Integer num = 1;
                if (appForms != null && !appForms.isEmpty()) {
                    AppForm appFormTemp = appForms.get(0);
                    num = Integer.valueOf(appFormTemp.getNo()) + 1;
                    appForm.setNo(num.toString());
                    appForm.setNumber(DateUtils.formatDate(new Date(), "yyyyMMdd") + (num));
                } else {
                    appForm.setNo(num.toString());
                    appForm.setNumber(DateUtils.formatDate(new Date(), "yyyyMMdd") + (num));
                }
                //固化
                appFormService.save(appForm);
                //异步处理邮件
                threadPoolTaskExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            /**
                             * 添加结束时间到了之后推送模板消息的定时任务
                             */
                            String templateId = SystemConfig.p.getProperty("showroomTemplateIdNew");
                            String t_first = "尊敬的" + appForm.getName() + "，您预约的展厅参观之旅已结束。我们期待您的评价和建议。";
                            String t_remarks = "欢迎点击详情，提交评价和建议。";
                            String t_url = ESAPI.encoder().decodeForHTML(paperUrl + "&id=" + appForm.getId());
                            Template template = new Template();
                            template.setAccountsId(appForm.getAccountsId());
                            template.setTemplateId(templateId);
                            template.setJobname("展厅预约结束推送模板消息");
                            template.setType("4");
                            template.setSendTime(DateUtils.parseDate(appForm.getEndDateTimeStr()));
                            template.setSendTimeStr(appForm.getEndDateTimeStr());
                            template.setMeetingId(String.valueOf(appForm.getId()));
//                            String reservationDate = DateUtils.formatDate(appForm.getReservationBeginTime(), "yyyy-MM-dd");
//                            String reservationDateBeginTime = DateUtils.formatDate(appForm.getReservationBeginTime(), "HH:mm");
//                            String reservationDateEndTime = DateUtils.formatDate(appForm.getReservationEndTime(), "HH:mm");
//                            template.setContent(rtnTemplate(templateId, t_first, t_remarks, appForm.getOpenid(), t_url, reservationDate, reservationDateBeginTime + "-" + reservationDateEndTime, appForm.getApplyContent()));
                            template.setContent(rtnTemplate(templateId, t_first, t_remarks, appForm.getOpenid(), t_url, appForm.getNumber(), "展厅预约"));
                            String uuid = UUID.randomUUID().toString();
                            template.setUuid(uuid);
                            Jedis jedis = jedisPool.getResource();
                            JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(template));
                            JSONObject result = new JSONObject();
                            result.put("status", "1");
                            result.put("data", data);
                            jedis.publish("job_listener", result.toJSONString());
                            jedis.close();
                            //发送模板消息通知申请人
                            CommonSendUtils.sendShowRoomTemplateMessageSuccess(tokenUtil.getToken(appForm.getAccountsId()), keyword1, keyword2, keyword3, remarks, first, appForm.getId(), appForm.getOpenid());
                            Conds conds = new Conds();
                            conds.equal("del_flag", 0);
                            Sort sort = new Sort("sort", OrderType.ASC);
                            String manager = "";
                            String releManager = "";
                            //抄送人
                            Set<String> releManagerEmail = new HashSet<>();
                            //收件人
                            Set<String> managerEmail = new HashSet<>();
                            List<Relevanter> relevanters = relevanterService.fetchSearchByPage(conds, sort, 0, 0);
                            for (Relevanter relevanter : relevanters) {
                                //展厅管理员纳入收件人列表
                                if (StringUtils.equals(relevanter.getStatus(), "0")) {
                                    managerEmail.add(relevanter.getEmail());
                                    manager += relevanter.getName() + ",";
                                } else {
                                    //其他管理员纳入抄送人列表
                                    releManagerEmail.add(relevanter.getEmail());
                                    releManager += relevanter.getName() + ",";
                                }
                            }
//                            if (StringUtils.isNotBlank(appForm.getEmail())) {
//                                //申请人纳入收件人列表
//                                managerEmail.add(appForm.getEmail());
//                            }
                            if (appForm.getExplainer() != null) {
                                Explainer explainer = explainerService.fetchById(appForm.getExplainer());
                                //讲解人纳入收件人列表
                                managerEmail.add(explainer.getEmail());
                            }
                            if (StringUtils.isNotBlank(manager)) {
                                manager = manager.substring(0, manager.length() - 1);
                            }
                            if (StringUtils.isNotBlank(releManager)) {
                                releManager = releManager.substring(0, releManager.length() - 1);
                            }
                            Map<String, Object> params = new HashMap<String, Object>();
                            params.put("showroomManager", manager);
                            params.put("relevanter", releManager);
                            data(appForm, params);
                            String pdfPath = DocToPdf.DocToPdf(params, "document.xml", "template.docx");
                            List<File> files = new ArrayList<File>();
                            File file = new File(pdfPath);
                            files.add(file);
                            String[] results = CommonSendUtils.sendshowRoomMail(files, managerEmail, releManagerEmail, appForm.getNumber());
                            if (results != null && "0".equals(results[0]) && file != null && file.exists()) {
                                file.delete();
                            }
                            appForm.setTomail(StringUtils.join(managerEmail, ","));
                            appForm.setCcmail(StringUtils.join(releManagerEmail, ","));
                            appFormService.update(appForm);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            } else {
                rtnJson.put("errorNo", 2);
            }
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }
        return rtnJson;
    }

    /**
     * 封装word填充Map
     */
    public void data(AppForm appForm, Map<String, Object> params) {
        if (StringUtils.isNotBlank(appForm.getEname())) {
            params.put("explainerName", appForm.getEname());
        } else if (StringUtils.equals(appForm.getExplainerStatus(), "1")) {
            params.put("explainerName", "不需要");
        } else {
            params.put("explainerName", "品牌大使时间冲突，无法预约");
        }
        params.put("nowdate", DateUtils.getDate("yyyy/MM/dd"));
        params.put("applyEmail", appForm.getEmail());
        params.put("name", appForm.getName());
        params.put("dept", appForm.getDname());
        Date beginDate = null;
        Date endDate = null;
        try {
            beginDate = DateUtils.parseDate(appForm.getBeginDateTimeStr(), "yyyy-MM-dd HH:mm");
            endDate = DateUtils.parseDate(appForm.getEndDateTimeStr(), "yyyy-MM-dd HH:mm");
        } catch (ParseException e) {
            e.printStackTrace();
        }

        params.put("date", DateUtils.formatDate(beginDate, "yyyy/MM/dd"));
        params.put("begin", DateUtils.formatDate(beginDate, "HH:mm"));
        params.put("end", DateUtils.formatDate(endDate, "HH:mm"));
        params.put("content", appForm.getApplyContent());
        params.put("type", appForm.getVname());
        params.put("num", appForm.getVisitorNum().toString());
        params.put("remarks", StringUtils.isNotBlank(appForm.getDescription()) ? appForm.getDescription() : "无");
        params.put("createDate", DateUtils.formatDate(new Date(), "yyyy/MM/dd"));
    }

    /**
     * 模板消息JSON拼装
     */
    public String rtnTemplate(String templateId, String first, String remarks, String openId, String url, String... keywords) {
        String v = "value";
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("template_id", templateId);
        rtnJson.put("touser", openId);
        rtnJson.put("url", url);
        JSONObject dataJson = new JSONObject();

        JSONObject firstJson = new JSONObject();
        firstJson.put(v, first);
        dataJson.put("first", firstJson);

        JSONObject remarksJson = new JSONObject();
        remarksJson.put(v, remarks);
        dataJson.put("remark", remarksJson);
        for (int i = 0; i < keywords.length; i++) {
            JSONObject keywordJson = new JSONObject();
            keywordJson.put(v, keywords[i]);
            dataJson.put("keyword" + (i + 1), keywordJson);
        }
        rtnJson.put("data", dataJson);
        return rtnJson.toString();
    }


    /**
     * 获取视频图文
     */
    @RequestMapping(value = "getSvideo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject appFormSubmit(String status) {
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorNo", 0);
        try {
            if (StringUtils.isEmpty(status)) {
                status = "0";
            }
            Conds conds = new Conds();
            conds.equal("status", status);
            Svideo svideo = svideoService.fetchSearchByConds(conds);
            svideo.setPersonContent(ESAPI.encoder().decodeForHTML(svideo.getPersonContent()));
            rtnJson.put("data", svideo);
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }
        return rtnJson;
    }

    /**
     * 获取申请单详情
     */
    @RequestMapping(value = "getAppform", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject getAppform(Long id, String openId) {
        JSONObject rtnJson = new JSONObject();
        rtnJson.put("errorNo", 0);
        try {
            AppForm appForm = null;
            Conds conds = new Conds();
            if (id != null) {
                conds.equal("t.id", id);
                appForm = appFormService.fetchSearchByConds(conds);
            } else {
                conds.equal("t.openid", openId);
                Sort sort = new Sort("t.create_time", OrderType.DESC);
                List<AppForm> appForms = appFormService.fetchSearchByPage(conds, sort, 0, 1);
                if (appForms != null && !appForms.isEmpty()) {
                    appForm = appForms.get(0);
                }
            }
            if (appForm != null) {
                appForm.setDname(ESAPI.encoder().decodeForHTML(appForm.getDname()));
                rtnJson.put("data", appForm);
            }
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }
        return rtnJson;
    }

    @Autowired
    private TemplateService templateService;

    /**
     * 更新预约单为取消状态
     */
    @RequestMapping(value = "cancelAppform", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public JSONObject cancelAppform(Long id, Long accountsId, String keyword1, String first, String remarks, String openid, String createDate, String nowDate) {
        JSONObject rtnJson = new JSONObject();
        if (id == null) {
            rtnJson.put("errorNo", "1");
            return rtnJson;
        }
        rtnJson.put("errorNo", 0);
        try {
            AppForm appForm = new AppForm();
            appForm.setId(id);
            appForm.setStatus("1");
            appForm.setCancelTime(new Date());
            appFormService.update(appForm);
            //发送模板消息通知申请人
            String[] keyword = {keyword1, createDate, nowDate};
            JwTemplateMessageAPI.sendMessage(SystemConfig.p.getProperty("cancelApplyReserveTemplateId"), tokenUtil.getToken(accountsId), openid, first, remarks, keyword, null);
            threadPoolTaskExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    /**
                     * 删除定时任务
                     *
                     */
                    Conds tConds = new Conds();
                    tConds.equal("type", "4");
                    tConds.equal("meeting_id", id);
                    Template template = templateService.fetchSearchByConds(tConds);
                    Jedis jedis = jedisPool.getResource();
                    JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(template));
                    JSONObject result = new JSONObject();
                    result.put("status", "0");
                    result.put("data", data);
                    jedis.publish("job_listener", result.toJSONString());
                    jedis.close();
                    Conds conds = new Conds();
                    conds.equal("t.id", id);
                    AppForm appFormTemp = appFormService.fetchSearchByConds(conds);
                    Set<String> tomails = null;
                    Set<String> ccmails = null;
                    if (StringUtils.isNotBlank(appFormTemp.getTomail())) {
                        tomails = new HashSet<>(Arrays.asList(appFormTemp.getTomail().split(",")));
                    }
                    if (StringUtils.isNotBlank(appFormTemp.getCcmail())) {
                        ccmails = new HashSet<>(Arrays.asList(appFormTemp.getCcmail().split(",")));
                    }
                    CommonSendUtils.sendCancelShowRoomMailMessage(tomails, ccmails, appFormTemp);
                }
            });
        } catch (Exception e) {
            rtnJson.put("errorNo", 1);
            e.printStackTrace();
        }
        return rtnJson;
    }
}
