package com.yihu.wlyy.web.doctor.health;

import java.util.*;

import com.yihu.wlyy.entity.education.*;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.service.app.health.*;
import com.yihu.wlyy.service.app.label.SignPatientLabelInfoService;
import com.yihu.wlyy.service.common.account.PatientService;
import com.yihu.wlyy.util.SendP2PUtil;
import com.yihu.wlyy.web.WeixinBaseController;
import com.yihu.wlyy.web.doctor.message.DoctorMessageController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.htmlparser.Parser;
import org.htmlparser.beans.StringBean;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.TextExtractingVisitor;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.service.common.account.DoctorService;
import com.yihu.wlyy.task.PushMsgTask;
import com.yihu.wlyy.util.DateUtil;
import com.yihu.wlyy.util.MessageType;
import com.yihu.wlyy.web.BaseController;

/**
 * 医生端：健康教育控制类
 *
 * @author George
 */
@Controller
@RequestMapping(value = "/doctor/health/edu", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Api(description = "健康教育")
public class DoctorHealthEduArticleController extends WeixinBaseController {

    @Autowired
    private HealthEduArticleService healthEduArticleService;
    @Autowired
    private DoctorService doctorService;
    @Autowired
    private HealthEduArticleOpHistoryService healthEduArticleOpHistoryService;

    @Autowired
    private SignPatientLabelInfoService signPatientLabelInfoService;

    @Autowired
    private HealthEduArticlePatientService healthEduArticlePatientService;

    @Autowired
    private HealthEduArticleDoctorService healthEduArticleDoctorService;

    @Autowired
    private HealthEduArticleLabelService healthEduArticleLabelService;

    @Autowired
    private PatientService patientService;

    @Autowired
    SignFamilyDao signFamilyDao;

    /**
     * 查询
     *
     * @param pagesize 分页大小
     * @return 列表
     */
    @RequestMapping(value = "list")
    @ResponseBody
    public String list(@RequestParam(value = "page", required = true) int page, @RequestParam(value = "pagesize", required = true) int pagesize, @RequestParam(value = "filter", required = false) String filter, @RequestParam(value = "patient", required = false) String patient) {
        try {
            List<Map<String, Object>> list = healthEduArticleService.findAll(page, pagesize, filter, getUID(), patient);
            JSONArray jsonArray = new JSONArray();
            if (list != null) {
                for (Map<String, Object> map : list) {
                    JSONObject json = new JSONObject();
                    json.put("id", map.get("id"));
                    // 文章标识
                    json.put("code", map.get("code"));
                    // 文章标题
                    json.put("title", map.get("title"));
                    // 文章查看URL
                    json.put("url", map.get("url"));

                    // 文章简介
                    json.put("content", parsrHtml(map.get("content").toString()));
                    // 添加日期
                    json.put("czrq", DateUtil.dateToStrLong((Date) map.get("czrq")));

                    json.put("keyword", map.get("keyword") == null ? "" : map.get("keyword"));

                    json.put("send", map.get("send"));
                    //阅读量
                    json.put("readAmount", map.get("readAmount"));
                    //收藏量
                    json.put("collectionAmount", map.get("collectionAmount"));
                    //转发量
                    json.put("repeatAmount", map.get("repeatAmount"));

                    json.put("collection", map.get("collection"));
                    jsonArray.put(json);
                }
            }
            return write(200, "查询成功", "list", jsonArray);
        } catch (Exception ex) {
            error(ex);
            return invalidUserException(ex, -1, "查询失败!");
        }
    }

    /**
     * 查询发送给居民的文章列表
     *
     * @param pagesize 分页大小
     * @return 列表
     */
    @RequestMapping(value = "list_by_team", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    @ApiOperation(value = "查询发送给居民的文章列表")
    public String listByTeam(@RequestParam @ApiParam(value = "第几页") int page,
                             @RequestParam @ApiParam(value = "页大小") int pagesize,
                             @RequestParam @ApiParam(value = "居民code") String patient,
                             @RequestParam @ApiParam(value = "团队code") Long teamCode) {
        try {
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "请输入需查询的居民");
            }
            if (teamCode == null || teamCode < 1) {
                return error(-1, "请输入需查询的居民的团队");
            }
            List<Map<String, Object>> list = healthEduArticleService.findByPatientAndTeam(patient, teamCode, page, pagesize);
            JSONArray jsonArray = new JSONArray();
            if (list != null) {
                for (Map<String, Object> map : list) {
                    JSONObject json = new JSONObject();
                    // 文章标识
                    json.put("doctorCode", map.get("code"));
                    // 文章标识
                    json.put("doctorName", map.get("name"));
                    // 文章标识
                    json.put("doctorPhoto", map.get("photo"));
                    // 文章标识
                    json.put("code", map.get("article"));
                    // 文章标题
                    json.put("title", map.get("title"));
                    // 文章查看URL
                    json.put("url", map.get("url"));
                    // 文章简介
                    json.put("content", parsrHtml(map.get("content").toString()));
                    // 发送日期
                    json.put("czrq", DateUtil.dateToStrLong((Date) map.get("czrq")));
                    // 发送团队
                    json.put("adminTeamCode", map.get("admin_team_code"));
                    jsonArray.put(json);
                }
            }
            return write(200, "查询成功", "list", jsonArray);
        } catch (Exception ex) {
            error(ex);
            return invalidUserException(ex, -1, "查询失败!");
        }
    }

    /**
     * 查询医生收藏列表
     *
     * @param pagesize 分页大小
     * @return 列表
     */
    @RequestMapping(value = "listDoctor")
    @ResponseBody
    public String listDoctor(@RequestParam(value = "page", required = true) int page, @RequestParam(value = "pagesize", required = true) int pagesize, @RequestParam(value = "filter", required = false) String filter, @RequestParam(value = "patient", required = false) String patient) {
        try {
            List<Map<String, Object>> list = healthEduArticleDoctorService.list(page, pagesize, filter, getUID(), patient);
            JSONArray jsonArray = new JSONArray();
            for (Map<String, Object> map : list) {
                JSONObject json = new JSONObject();
                json.put("id", map.get("id"));
                // 文章标识
                json.put("code", map.get("article"));
                // 文章标题
                json.put("title", map.get("title"));
                // 文章查看URL
                json.put("url", map.get("url"));

                // 文章简介
                json.put("content", parsrHtml(map.get("content").toString()));
                // 添加日期
                json.put("czrq", DateUtil.dateToStrLong((Date) map.get("czrq")));

                json.put("keyword", map.get("keyword"));

                json.put("send", map.get("send"));
                //阅读量
                json.put("readAmount", map.get("readAmount"));
                //收藏量
                json.put("collectionAmount", map.get("collectionAmount"));
                //转发量
                json.put("repeatAmount", map.get("repeatAmount"));
                //是否收藏(医生收藏的列表肯定是收藏的无需额外校验)
                json.put("collection", 1);
                jsonArray.put(json);
            }
            return write(200, "查询成功", "list", jsonArray);
        } catch (Exception ex) {
            error(ex);
            return invalidUserException(ex, -1, "查询失败!");
        }
    }

    /**
     * 查询标签列表
     *
     * @param pagesize 分页大小
     * @return 列表
     */
    @RequestMapping(value = "listLabel")
    @ResponseBody
    public String listLabel(@RequestParam(value = "page", required = true) int page, @RequestParam(value = "pagesize", required = true) int pagesize, @RequestParam(value = "type", required = false, defaultValue = "0") int type) {
        try {
            Page<HealthEduArticleLabel> list = healthEduArticleLabelService.findAll(page, pagesize, type, getUID());
            return write(200, "查询成功", "list", list);
        } catch (Exception ex) {
            error(ex);
            return invalidUserException(ex, -1, "查询失败!");
        }
    }

    /**
     * 查询文章列表
     *
     * @param code 数据文章唯一标示code
     * @return 列表
     */
    @RequestMapping(value = "article")
    @ResponseBody
    public String article(@RequestParam(value = "code", required = true) String code) {
        try {
            //获取单条文章记录
            HealthEduArticle healthEduArticle = healthEduArticleService.findArticleByCode(code);
            int isRead = healthEduArticleOpHistoryService.countByUserStatus(getUID(), HealthEduArticleOpHistory.READ_STATUS);
            //插入文章读取状态第一次阅读记录浏览数量
            if (isRead == 0) {
                //更新浏览量
                healthEduArticleOpHistoryService.saveByStatus(HealthEduArticleOpHistory.READ_STATUS, healthEduArticle.getCode(), healthEduArticle.getTitle(), getUID());
            }
            JSONObject json = new JSONObject();
            json.put("id", healthEduArticle.getId());
            // 文章标识
            json.put("code", healthEduArticle.getCode());
            // 文章标题
            json.put("title", healthEduArticle.getTitle());

            json.put("url", healthEduArticle.getUrl() == null ? "" : healthEduArticle.getUrl());
            // 文章内容
            json.put("content", healthEduArticle.getContent());
            // 添加日期
            json.put("czrq", DateUtil.dateToStrLong(healthEduArticle.getCzrq()));
            int readAmount = healthEduArticleOpHistoryService.countReadAmount(code);
            json.put("readAmount", readAmount);
            HealthEduArticleDoctor healthEduArticleDoctor = healthEduArticleDoctorService.findByArticle(healthEduArticle.getCode(), getUID());
            if (healthEduArticleDoctor == null) {
                json.put("collection", 0);
            } else {
                json.put("collection", 1);
            }
            return write(200, "查询成功", "data", json);
        } catch (Exception ex) {
            error(ex);
            return invalidUserException(ex, -1, "查询失败!");
        }
    }


    /**
     * 发送文章给患者
     *
     * @param code    文章标识，多个以逗号分隔
     * @param patient 患者标识，多个以逗号分隔
     * @param group   所选群组，多个用逗号分隔
     * @return
     */
    @RequestMapping(value = "send")
    @ResponseBody
    public String send(@RequestParam(value = "code") String code,
                       @RequestParam(value = "patient", required = false) String patient,
                       @RequestParam(value = "group", required = false, defaultValue = "") String group,
                       @RequestParam(value = "labelType", required = false) String labelType,
                       @RequestParam(value = "teamCode", required = false) long teamCode) {
        try {
            List<HealthEduArticlePatient> list = new ArrayList<HealthEduArticlePatient>();
            if (StringUtils.isEmpty(code)) {
                return error(-1, "请至少选择一篇文章！");
            }
            if (StringUtils.isEmpty(patient) && StringUtils.isEmpty(group)) {
                return error(-1, "请至少选择一个患者！");
            }
            String[] articles = code.split(",");
            String[] patients = patient.split(",");
            String[] groups = group.split(",");
            if (articles.length == 0) {
                return error(-1, "请至少选择一篇文章！");
            }
            if (patients.length == 0 && groups.length == 0) {
                return error(-1, "请至少选择一个患者！");
            }
            Map<String, HealthEduArticle> maps = new HashMap<String, HealthEduArticle>();
            Set<String> patientSet = new HashSet<>();
            if (StringUtils.isNotBlank(group) && groups.length > 0) {
                //递归患者数据
                for (String g : groups) {
                    getPatientByGroup(g, labelType, teamCode, patientSet, 0, 100);
                }
            }
            //去重操作
            for (String p : patients) {
                if (StringUtils.isNotBlank(p)) {
                    patientSet.add(p);
                }
            }
            if (patientSet.size() == 0) {
                return error(-1, "请至少选择一个患者！");
            }
            // 查询医生信息
            Doctor doctor = doctorService.findDoctorByCode(getUID());
            String msgHead = doctor.getName() + "医生给您发来了一篇患教文章";
            String endMsg = "为了您的健康，" + doctor.getName() + "医生给您发送了一篇患教文章，请仔细查阅，如有问题，可随时咨询医生。";
            JSONArray messages = new JSONArray();
            for (String p : patientSet) {
                Patient patientTemp = patientService.findByCode(p);
                SignFamily signFamily = signFamilyDao.findByjiatingPatient(p);
                if(signFamily == null){
                    throw new Exception("can not find patient's family sign info");
                }
                for (String a : articles) {
                    // 查询文章信息
                    HealthEduArticle temp = maps.get(a);
                    if (temp == null) {
                        temp = healthEduArticleService.findArticleByCode(a);
                        // 添加到缓存
                        maps.put(a, temp);
                    }

                    HealthEduArticlePatient heap = new HealthEduArticlePatient();
                    // 设置文章标识
                    heap.setArticle(a);
                    // 设置文章简介
                    heap.setContent(temp.getContent());
                    // 设置文章标题
                    heap.setTitle(temp.getTitle());
                    // 设置文章查看URL
                    heap.setUrl(temp.getUrl());
                    // 设置发送时间
                    heap.setCzrq(new Date());
                    // 设置医生标识
                    heap.setDoctor(doctor.getCode());
                    // 设置医生姓名
                    heap.setDoctorName(doctor.getName());
                    // 设置患者标识
                    heap.setPatient(p);
                    // 设置为示读
                    heap.setRead(1);
                    // 签约类型
                    heap.setSignType(2);
                    // 行政团队
                    heap.setAdminTeamCode(signFamily.getAdminTeamId());
                    list.add(heap);
                    SendP2PUtil.sendP2Pmsg(doctor.getCode(), p, "4", "{\"title\":\"" + temp.getTitle() + "\",\"id\":\"" + temp.getCode() + "\",\"img\":\"" + temp.getUrl() + "\",\"content\":\"为了您的健康，我给您发送了一篇文章，请咨询查阅，如有问题，可随时与我沟通\"}");
                    if (StringUtils.isNotEmpty(patientTemp.getOpenid())) {
                        // 推送消息给微信端
                        JSONObject json = new JSONObject();
                        json.put("first", patientTemp.getName() + "，您好！\n" + msgHead);
                        json.put("toUser", p);
                        json.put("article", temp.getCode() + "");
                        json.put("title", temp.getTitle());
                        json.put("doctorName", doctor.getName());
                        json.put("date", DateUtil.dateToStrLong(DateUtil.getNowDate()));
                        json.put("remark", endMsg);
                        PushMsgTask.getInstance().putWxMsg(getAccessToken(), 9, patientTemp.getOpenid(), patientTemp.getName(), json);
                    }
                }
            }
            // 保存到数据库
            int row = healthEduArticleService.send(list);
            if (row <= 0) {
                return error(-1, "发送失败！");
            } else {
                // 推送消息给患者
                PushMsgTask.getInstance().put(messages);
                return success("发送成功！");
            }
        } catch (Exception e) {
            error(e);
            return error(-1, "发送失败！");
        }
    }

    private void getPatientByGroup(String labelCode, String labelType, Long teamCode, Set<String> patientSet, int page, int pagesize) throws Exception {
        JSONArray result = signPatientLabelInfoService.getPatientByLabel(getUID(), labelCode, labelType, teamCode, page, pagesize);
        for (Object o : result) {
            JSONObject json = (JSONObject) o;
            String patient = (String) json.get("code");
            patientSet.add(patient);
        }
        if (result.length() == 100) {
            getPatientByGroup(labelCode, labelType, teamCode, patientSet, page + 1, pagesize);
        }
    }

    /**
     * 文章收藏
     *
     * @param article 文章CODE
     * @return
     */
    @RequestMapping(value = "collectionArticle")
    @ResponseBody
    public String collectionArticle(@RequestParam(value = "article", required = true) String article) {
        HealthEduArticleDoctor healthEduArticleDoctor = healthEduArticleDoctorService.findByArticle(article, getUID());
        if (healthEduArticleDoctor != null) {
            return error(-1, "收藏失败,该文章已经收藏！");
        }
        HealthEduArticle healthEduArticle = healthEduArticleService.findArticleByCode(article);
        healthEduArticleDoctor = new HealthEduArticleDoctor();
        try {
            BeanUtils.copyProperties(healthEduArticle, healthEduArticleDoctor);
            healthEduArticleDoctor.setDoctor(getUID());
            healthEduArticleDoctor.setArticle(healthEduArticle.getCode());
            healthEduArticleDoctorService.save(healthEduArticleDoctor);
            //更新收藏量
            healthEduArticleOpHistoryService.saveByStatus(HealthEduArticleOpHistory.COLLECTION_STATUS, healthEduArticle.getCode(), healthEduArticle.getTitle(), getUID());
            return success("收藏成功！");
        } catch (Exception e) {
            error(e);
            return error(-1, "收藏失败！");
        }
    }

    /**
     * 文章收藏
     *
     * @param article 文章CODE
     * @return
     */
    @RequestMapping(value = "uncollectionArticle")
    @ResponseBody
    public String uncollectionArticle(@RequestParam(value = "article", required = true) String article) {
        try {
            healthEduArticleDoctorService.delete(article, getUID());

            return success("取消收藏成功！");
        } catch (Exception e) {
            error(e);
            return error(-1, "取消收藏失败！");
        }
    }

    private String parsrHtml(String html) {
        html = ("<span>" + html + "</span>");//拼接一个HTML标签，防止纯文字字符串转换在linux下面出现的异常。
        Parser parser = null;
        try {
            parser = new Parser(html);
            TextExtractingVisitor visitor = new TextExtractingVisitor();
            parser.visitAllNodesWith(visitor);
            return StringUtils.isNotBlank(visitor.getExtractedText()) ? visitor.getExtractedText() : "内容为图集，请点击查看";
        } catch (ParserException e) {
            return html;//纯文本内容会转换失败，直接返回文本内容
        }

    }

    public static void main(String arg[]) {
        System.out.println(MessageType.MESSAGE_TYPE_PATIENT_HEALTH_EDU.P_HE_01.name());
    }
}
