/*******************************************************************************
 * Copyright (c) 2005, 2014 springside.github.io
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 *******************************************************************************/
package com.yihu.wlyy.service.common.account;

import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorPatient;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.entity.security.Token;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.doctor.DoctorPatientDao;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.repository.security.TokenDao;
import com.yihu.wlyy.task.SignSsGetTask;
import com.yihu.wlyy.util.EncodesUtil;
import com.yihu.wlyy.util.IdcardInfoExtractor;
import com.yihu.wlyy.util.SystemData;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.utils.Clock;

import java.util.Date;
import java.util.List;

/**
 * 患者基本信息类.
 *
 * @author George
 */
@Component
@Transactional(rollbackFor = Exception.class)
public class PatientService extends TokenService {

    @Autowired
    private SignFamilyDao signFamilyDao;
    @Autowired
    private PatientDao patientDao;
    @Autowired
    private DoctorDao doctorDao;
    @Autowired
    private DoctorPatientDao doctorPatientDao;
    @Autowired
    TokenDao tokenDao;
    @Autowired
    JdbcTemplate jdbcTemplate;

    private Clock clock = Clock.DEFAULT;

    public void setClock(Clock clock) {
        this.clock = clock;
    }

    public Patient findByCode(String code) {
        return patientDao.findByCode(code);
    }

    public Patient findByIdcard(String idcard) {
        return patientDao.findByIdcard(idcard);
    }

    public Patient findBySsc(String ssc) {
        return patientDao.findBySsc(ssc);
    }

    public Patient findByMobile(String mobile) {
        return patientDao.findByMobile(mobile);
    }

    public Patient findByOpenid(String openid) {
        return patientDao.findByOpenid(openid);
    }

    public int countByOpenid(String openid) {
        return patientDao.countByOpenid(openid);
    }

    /**
     * 修改患者密码
     *
     * @param patient
     */
    public void updatePatientPwd(Patient patient) {
        patientDao.save(patient);
    }

    public void updatePatientInfo(Patient patient) {
        patientDao.save(patient);
    }

    /**
     * 修改患者openid
     *
     * @param patient
     */
    public void updatePatient(Patient patient, String openid) throws Exception {
        Sort sort = new Sort(Sort.Direction.ASC, "czrq");
        PageRequest pageRequest = new PageRequest(0, 100, sort);
        Page<Token> tokens = tokenDao.findByOpenid(openid, pageRequest);

        if (tokens != null && tokens.getContent().size() >= 10) {
            int i = 0;
            int last = tokens.getContent().size() - 10;
            for (Token token : tokens) {
                i++;
                Patient p = patientDao.findByCode(token.getUser());
                if (p == null || i <= last) {
                    tokenDao.delete(token);
                    SystemData.wxPatientTokens.remove(token.getUser());
                    continue;
                }
                p.setOpenid("");
                signFamilyDao.updateOpenidByPatient("", p.getCode());
                patientDao.save(p);
                tokenDao.delete(token);
                SystemData.wxPatientTokens.remove(p.getCode());
                break;
            }
        }
        //如果之前患者的openId为空并且openID有值更新时间
        if (!org.springframework.util.StringUtils.isEmpty(openid) && org.springframework.util.StringUtils.isEmpty(patient.getOpenid())) {
            patient.setOpenidTime(new Date());
        }
        patient.setOpenid(openid);
        Patient ps = patientDao.save(patient);
        System.out.print(new JSONObject(ps));
        if (StringUtils.isNotEmpty(patient.getOpenid())) {
            signFamilyDao.updateOpenidByPatient(patient.getOpenid(), patient.getCode());
        }
    }

    public void deletePatient(Patient patient) {
        patientDao.delete(patient);
    }

    public void deletePatients(Iterable<Patient> patients) {
        patientDao.delete(patients);
    }

    /**
     * 患者註冊
     *
     * @param patient
     * @return
     * @throws Exception
     */
    public JSONObject register_bak(Patient patient, String imei, int platform) throws Exception {
        IdcardInfoExtractor ie = new IdcardInfoExtractor(patient.getIdcard());
        patient.setBirthday(ie.getBirthday());
        patient.setSex(ie.getGender());
        patient.setCode(getCode());
        patient.setStatus(1);
        patient.setCzrq(clock.getCurrentDate());
        patient.setDisease(0);
        patient.setDiseaseCondition(0);
        patient.setRecordAmount(0);
        patient.setPoints(0);
        patient.setOpenid("");
        Patient temp = patientDao.save(patient);
        if (temp != null) {
            // 更新openid
            updatePatient(temp, imei);
            // 生成登录tokey
            Token token = newToken(temp.getCode(), imei, platform);
            if (token != null) {
                // 生成登录信息成功
                JSONObject json = new JSONObject();
                json.put("id", temp.getId());
                json.put("uid", temp.getCode());
                json.put("token", token.getToken());
                json.put("name", temp.getName());
                json.put("photo", temp.getPhoto());
                //new Thread(new SignSsGetTask(patient.getIdcard())).start();
                return json;
            }
        }
        return null;
    }

    /**
     * 患者注册
     *
     * @param idcard
     * @param ssc
     * @param name
     * @param mobile
     * @param password
     * @param salt
     * @param imei
     * @param platform
     * @return
     * @throws Exception
     */
    public JSONObject register(String idcard, String ssc, String name, String mobile
            , String password, String salt, String imei, int platform) throws Exception {
        IdcardInfoExtractor ie = new IdcardInfoExtractor(idcard);
        String code = getCode();
        String sql = "insert wlyy_patient(code,idcard,name,ssc,mobile,password,salt,openid" +
                ",status,birthday,sex,czrq,disease,disease_condition,record_amount,points)" +
                " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";

        jdbcTemplate.update(sql, new Object[]{code, idcard, name, ssc, mobile, password, salt, imei, 1, ie.getBirthday()
                , ie.getGender(), clock.getCurrentDate(), 0, 0, 0, 0});

        Patient temp = patientDao.findByCode(code);
        if (temp != null) {
            // 更新openid
            updatePatient(temp, imei);
            // 生成登录tokey
            Token token = newToken(temp.getCode(), imei, platform);
            if (token != null) {
                // 生成登录信息成功
                JSONObject json = new JSONObject();
                json.put("id", temp.getId());
                json.put("uid", temp.getCode());
                json.put("token", token.getToken());
                json.put("name", temp.getName());
                json.put("photo", temp.getPhoto());
                //new Thread(new SignSsGetTask(patient.getIdcard())).start();
                return json;
            }
        }
        return null;
    }

    /**
     * 建立三师团队与患者的关系
     *
     * @param sf
     * @param patient
     * @param doctorCode
     * @param doctorType
     */
    private void bindDoctorPatient(SignFamily sf, Patient patient, String doctorCode, int doctorType) {
        DoctorPatient dp = doctorPatientDao.findByPatientDoctorTeamType(patient.getCode(), doctorCode, doctorType);
        if (dp == null) {
            Doctor doctor = doctorDao.findByCode(doctorCode);
            dp = new DoctorPatient();
            dp.setBirthday(patient.getBirthday());
            dp.setCzrq(new Date());
            dp.setDoctor(doctor.getCode());
            dp.setDoctorName(doctor.getName());
            // 健康管理师
            dp.setDoctorType(doctorType);
            dp.setPatient(patient.getCode());
            dp.setPatientName(patient.getName());
            dp.setSex(patient.getSex());
            if (sf != null) {
                // 三师和家庭都存在
                dp.setSignType("11");
            } else {
                // 只有家庭签约
                dp.setSignType("01");
            }
            dp.setStatus(1);
            // 设置为三师团队
            dp.setTeamType(1);
            // 保存到数据库
            doctorPatientDao.save(dp);
        }
    }

    /**
     * 微信端患者註冊
     *
     * @param patient
     * @return
     * @throws Exception
     */
    public JSONObject register(Patient patient) throws Exception {
        patient.setCode(getCode());
        patient.setCzrq(clock.getCurrentDate());
        EncodesUtil.entryptPassword(patient);
        Patient temp = patientDao.save(patient);
        if (temp != null) {
            JSONObject json = new JSONObject();
            json.put("id", temp.getId());
            json.put("uid", temp.getCode());
            json.put("name", "");
            json.put("openid", temp.getOpenid());
            return json;
        }
        return null;
    }

}
