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

import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.yihu.wlyy.entity.patient.SignWeb;
import com.yihu.wlyy.repository.patient.SignWebDao;
import com.yihu.wlyy.service.BaseService;

/**
 * 网络签约业务处理类
 *
 * @author George
 */
@Component
@Transactional
public class SignWebService extends BaseService {

    @Autowired
    private SignWebDao signWebDao;
    @Autowired
    private SignFamilyDao signFamilyDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 根据医生代码及签约状态编码 获取该医生签约患者的信息列表
     *
     * @param doctor
     * @param status
     * @param page
     * @param pageSize
     * @return
     */
    public List<Map<String, Object>> getSignWebByDoctor(String doctor, int status, int page, int pageSize) {
        // 查询语句
        String sql = "select " +
                "    a.code " +
                "    ,a.doctor " +
                "    ,b.code  as  patient" +
                "    ,b.idcard " +
                "    ,b.name " +
                "    ,b.province_name  as provinceName" +
                "    ,b.city_name  as cityName" +
                "    ,b.town_name  as townName" +
                "    ,b.address " +
                "    ,b.photo " +
                "    ,a.status " +
                "    ,a.id " +
                (status == 1 ? "    ,a.patient_apply_date as applyDate " : "    ,a.expenses_time as applyDate ") +
                "    ,a.reason " +
                "    ,b.street_name as streetName" +
                "    ,b.sex" +
                "    ,b.openid" +
                " from " +
                " ( select code,patient,doctor,status,id,apply_date,patient_apply_date,expenses_time,reason,begin from wlyy_sign_family where (doctor = ? or doctor_health = ?) and status = ? and type = 2" +
                (status == 3 ? " and expenses_status = '1'" : "") + " order by begin desc ) a " +
                " ,wlyy_patient b " +
                " where a.patient = b.code  order by a.begin desc limit " + page * pageSize + "," + pageSize;

        // 未缴费查询语句
        String sqlExpenses = "select " +
                "    a.code " +
                "    ,a.doctor " +
                "    ,b.code  as  patient" +
                "    ,b.name " +
                "    ,b.idcard " +
                "    ,b.province_name  as provinceName" +
                "    ,b.city_name  as cityName" +
                "    ,b.town_name  as townName" +
                "    ,b.address " +
                "    ,b.photo " +
                "    ,a.status " +
                "    ,a.id " +
                "    ,a.apply_date as applyDate " +
                "    ,a.reason " +
                "    ,b.street_name as streetName" +
                "    ,b.sex" +
                "    ,b.openid" +
                " from " +
                " ( select code,patient,doctor,status,id,apply_date,reason,begin,expenses_status,LENGTH(trim(ifnull(expenses_status,''))) len from wlyy_sign_family where (doctor = ? or doctor_health = ?) and status > ? and type = 2 order by begin desc ) a " +
                " ,wlyy_patient b " +
                " where a.patient = b.code and (a.expenses_status = '0' or a.len < 1) order by a.begin desc limit " + page * pageSize + "," + pageSize;

        // 已解约查询语句
        String surrSql = "select " +
                "    a.code " +
                "    ,a.doctor " +
                "    ,b.code  as  patient" +
                "    ,b.name " +
                "    ,b.idcard " +
                "    ,b.province_name  as provinceName" +
                "    ,b.city_name  as cityName" +
                "    ,b.town_name  as townName" +
                "    ,b.address " +
                "    ,b.photo " +
                "    ,a.status " +
                "    ,a.id " +
                "    ,a.apply_unsign_date as applyDate" +
                "    ,a.reason " +
                "    ,b.street_name as streetName" +
                "    ,b.sex" +
                "    ,b.openid" +
                " from " +
                " ( select code,patient,doctor,status,id,apply_date,apply_unsign_date,reason,begin from wlyy_sign_family where (doctor = ? or doctor_health = ?) and ( status = ? or status = ? ) and type = 2 order by begin desc ) a " +
                " ,wlyy_patient b " +
                " where a.patient = b.code  order by a.begin desc limit " + page * pageSize + "," + pageSize;

        // 分页信息
        //PageRequest pageRequest = new PageRequest(page - 1, pageSize);
        //1:待签约 2, 待解约 3 已签约,4已经解约
        Page<Object> list = null;
        List<Map<String, Object>> patients = null;
        switch (status) {
            case 1:// 待签约
                patients = jdbcTemplate.queryForList(sql, new Object[]{doctor, doctor, 0});
                break;
            case 2:// 待解约
                patients = jdbcTemplate.queryForList(sql, new Object[]{doctor, doctor, 2});
                break;
            case 3:// 已签约
                patients = jdbcTemplate.queryForList(sql, new Object[]{doctor, doctor, 1});
                break;
            case 4:// 4已经解约
                patients = jdbcTemplate.queryForList(surrSql, new Object[]{doctor, doctor, -3, -4});
                break;
            case 5: // 未缴费
                patients = jdbcTemplate.queryForList(sqlExpenses, new Object[]{doctor, doctor, 0});
        }

        return patients;
    }

    /**
     * 查询家庭签约已缴费未关注人数
     *
     * @param doctor
     * @return
     */
    public int isRemindFocusAll(String doctor) {
        boolean isAll = true;
        // 查询语句
        String sql = "select distinct b.code" +
                " from " +
                "     wlyy_sign_family f" +
                "     ,wlyy_patient b " +
                " where " +
                "     f.patient = b.code " +
                "     and (f.doctor = ? or f.doctor_health = ?)" +
                "     and f.expenses_status = '1' " +
                "     and f.status > 0 " +
                "     and f.type = 2 " +
                "     and LENGTH(trim(ifnull(b.openid,''))) < 1";

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

        if (result != null && result.size() > 0) {
            Set<String> set = redisTemplate.opsForSet().members("wechat:focus:remind:set");
            if (set == null) {
                isAll = false;
            } else if(!set.containsAll(result)) {
                isAll = false;
            }
        } else {
            isAll = false;
        }

        return isAll ? 1 : 0;
    }

    /**
     * 查询家庭签约已缴费未关注人数
     *
     * @param doctor
     * @return
     */
    public int isRemindExpensesAll(String doctor) {
        boolean isAll = true;
        // 查询语句
        String sql = "select distinct f.patient" +
                " from " +
                "     wlyy_sign_family f" +
                " where " +
                "     (f.doctor = ? or f.doctor_health = ?)" +
                "     and f.status > 0 " +
                "     and f.type = 2 " +
                "     and (f.expenses_status = 0 or LENGTH(trim(ifnull(f.expenses_status,''))) < 1)";

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

        if (result != null && result.size() > 0) {
            Set<String> set = redisTemplate.opsForSet().members("expenses:remind:set");
            if (set == null) {
                isAll = false;
            } else if(!set.containsAll(result)) {
                isAll = false;
            }
        } else {
            isAll = false;
        }

        return isAll ? 1 : 0;
    }

    /**
     * 根据代码查找签约信息明细
     *
     * @param code
     * @return
     */
    public SignWeb getSignWebByCode(String code) {
        return signWebDao.findByCode(code);
    }

    /**
     * 更新签约信息
     *
     * @return
     */
    public boolean saveSignWeb(SignWeb signWeb) {
        if (StringUtils.isEmpty(signWeb.getCode())) {
            signWeb.setCode(getCode());
            // 计算签约 月数
            if (signWeb.getBeginDate() != null && signWeb.getEndDate() != null) {
                Calendar startDate = Calendar.getInstance();
                Calendar endDate = Calendar.getInstance();
                startDate.setTime(signWeb.getBeginDate());
                endDate.setTime(signWeb.getEndDate());

                int startYear = startDate.get(Calendar.YEAR);
                int startMonth = startDate.get(Calendar.MONTH);

                int endYear = endDate.get(Calendar.YEAR);
                int endMonth = endDate.get(Calendar.MONTH);

                int result = Math.abs(endMonth - startMonth);
                if (startYear != endYear) {
                    result = 12 * (endYear - startYear) + result;
                }
                signWeb.setMonths(result);
            }
        }
        signWebDao.save(signWeb);
        return true;
    }

    /**
     * 根据患者Code 获取患者当前签约的医生信息
     *
     * @param patient
     * @return
     */
    public SignWeb getSignWebByPatient(String patient) {
        return signWebDao.findSignWebByPatient(patient);
    }

    /**
     * 根据患者Code 查询条件 以及签约状态获取签约信息
     *
     * @param patient 患者Code
     * @param status  签约状态
     * @return
     */
    public Page<Object> getSignInfoByPatient(String patient, int status, long id, int pageSize) {
        if (pageSize <= 0) {
            pageSize = 10;
        }
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pageSize);

        Page<Object> listInfo = null;
        if (id > 0) {
            switch (status) {
                case 0:// 待签约
                    listInfo = signWebDao.findToBedSignInfoByPatient(patient, id, pageRequest);
                    break;
                case 1:// 已解约
                    listInfo = signWebDao.findCancelledSignInfoByPatient(patient, id, pageRequest);
                    break;
                case 2:// 已签约
                    listInfo = signWebDao.findSignedSignInfoByPatient(patient, id, pageRequest);
                    break;
                case 3:// 待解约
                    listInfo = signWebDao.findToCancelSignInfoByPatient(patient, id, pageRequest);
                    break;
                default:
                    listInfo = signWebDao.findSignInfoByPatient(patient, id, pageRequest);
            }
        } else {
            switch (status) {
                case 0:// 待签约
                    listInfo = signWebDao.findToBedSignInfoByPatient(patient, pageRequest);
                    break;
                case 1:// 已解约
                    listInfo = signWebDao.findCancelledSignInfoByPatient(patient, pageRequest);
                    break;
                case 2:// 已签约
                    listInfo = signWebDao.findSignedSignInfoByPatient(patient, pageRequest);
                    break;
                case 3:// 待解约
                    listInfo = signWebDao.findToCancelSignInfoByPatient(patient, pageRequest);
                    break;
                default:
                    listInfo = signWebDao.findSignInfoByPatient(patient, pageRequest);
            }
        }
        return listInfo;
    }

    /**
     * 获取已签约信息
     *
     * @param patient
     * @return
     */
    public List<Object> getSignInfoByStatus(String patient) {
        return signWebDao.findSignedSignInfoBystatus(patient);
    }

    /**
     * 通过身份证获取签约信息
     */
    public List<SignFamily> getSignInfoByIdcard(String idcard) {
        return signFamilyDao.findAllByIdcard(idcard);
    }
}
