package com.yihu.wlyy.service.app.sign;

import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.organization.Hospital;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.organization.HospitalDao;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.service.common.SMSService;
import com.yihu.wlyy.task.PushMsgTask;
import com.yihu.wlyy.util.DateUtil;
import com.yihu.wlyy.wechat.util.WeiXinAccessTokenUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 缴费提醒服务
 * <p>
 * Created by lyr on 2016/10/24.
 */
@Service
public class ExpensesRemindService extends BaseService {

    @Autowired
    SignFamilyDao signFamilyDao;
    @Autowired
    DoctorDao doctorDao;
    @Autowired
    PatientDao patientDao;
    @Autowired
    HospitalDao hospitalDao;
    @Autowired
    SMSService smsService;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    WeiXinAccessTokenUtils tokenUtils;
    @Autowired
    JdbcTemplate jdbcTemplate;

    /**
     * 缴费提醒
     *
     * @param doctor 医生
     * @throws Exception
     */
    @Async
    public void remindPatientExpensesAll(String doctor) throws Exception {
        try {
            Doctor doc = doctorDao.findByCode(doctor);
            if (doc == null) {
                throw new Exception("doctor info can not find");
            }

            Hospital hos = hospitalDao.findByCode(doc.getHospital());
            if (hos == null) {
                throw new Exception("hospital info can not find");
            }

            RemindAll(doc, hos);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 所有未缴费提醒
     *
     * @param doc
     * @param hos
     */
    public void RemindAll( Doctor doc, Hospital hos) {
        try {
            String sql = "select distinct a.patient from " +
                    " (select patient,expenses_status,LENGTH(trim(ifnull(expenses_status,''))) len " +
                    "     from " +
                    "        wlyy_sign_family " +
                    "     where "
                    + (doc.getLevel() == 2 ? "doctor" : "doctor_health") + " = ? " +
                    "        and status > 0 " +
                    "        and type = 2 " +
                    "        order by begin desc ) a" +
                    " where a.expenses_status = '0' or a.len < 1";

            List<Map<String, Object>> result = jdbcTemplate.queryForList(sql, new Object[]{doc.getCode()});

            if (result != null && result.size() > 0) {
                for (Map<String, Object> map : result) {
                    Patient p = patientDao.findByCode(String.valueOf(map.get("patient")));

                    if (p != null) {
                        remindPatientExpenses(p, doc, hos);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 提醒患者缴费
     *
     * @param patient 患者
     * @param doctor  医生
     * @return
     */
    public int remindPatientExpenses(String patient, String doctor) {
        try {
            Doctor doc = doctorDao.findByCode(doctor);
            if (doc == null) {
                throw new Exception("doctor info can not find");
            }

            Hospital hos = hospitalDao.findByCode(doc.getHospital());
            if (hos == null) {
                throw new Exception("hospital info can not find");
            }

            Patient p = patientDao.findByCode(patient);

            if (p == null) {
                throw new Exception("patient info can not find");
            }

            if(remindPatientExpenses(p, doc, hos) == 1){
                return 1;
            }else{
                return 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 提醒患者缴费
     *
     * @param p   患者
     * @param doc 医生
     * @param hos 医院
     * @return
     */
    public int remindPatientExpenses(Patient p, Doctor doc, Hospital hos) throws Exception {
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            boolean mFlag = false;
            boolean wFlag = false;

            if (StringUtils.isNotEmpty(p.getMobile()) ) {
                int result = smsService.sendMsg(p.getMobile(), "厦门市民健康系统】" + doc.getName() + "医生提醒您：为完成家庭医生签约，" +
                        "尽早为您提供家庭医生服务，请尽快到" + hos.getName() + "（地址：" + hos.getAddress() + "）缴费");
                if(result == 1){
                    mFlag = true;
                }
            }
            if(StringUtils.isNotEmpty(p.getOpenid())){
                // 微信提醒
                JSONObject json = new JSONObject();
                json.put("first", "缴费提醒");
                json.put("toUser", p.getCode());
                json.put("doctor", doc.getCode());
                json.put("doctorName", doc.getName());
                json.put("date", DateUtil.dateToStrShort(new Date()));
                json.put("content", "为完成家庭医生签约，尽早为您提供家庭医生服务，请尽快到" + hos.getName() + "（地址：" + hos.getAddress() + "）缴费");
                json.put("remark", "");
                // 添加到发送队列
                PushMsgTask.getInstance().putWxMsg(tokenUtils.getAccessToken(), 8, p.getOpenid(), p.getName(), json);
                wFlag = true;
            }

            if(wFlag || mFlag) {
                redisTemplate.opsForValue().set("expenses:remind:" + p.getCode(), df.format(new Date()));
                return 1;
            }else{
                return 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}
