package controllers

import (
	"FollowUp_Notice/Nats/NatsServer"
	"FollowUp_Notice/conf"
	"FollowUp_Notice/http"
	"FollowUp_Notice/http/submail"
	"FollowUp_Notice/lib"
	"FollowUp_Notice/logs"
	"FollowUp_Notice/models/Account"
	"FollowUp_Notice/models/Illness"
	"FollowUp_Notice/models/Patient"
	"FollowUp_Notice/models/Surgical"
	"FollowUp_Notice/models/System"
	"FollowUp_Notice/models/Tag"
	"encoding/json"
	"fmt"
	beego "github.com/beego/beego/v2/server/web"
	"github.com/robfig/cron/v3"
	"github.com/signintech/gopdf"
	"github.com/signintech/gopdf/fontmaker/core"
	"log"
	"math"
	"os"
	"strconv"
	"strings"
	"time"
)

type PatientController struct {
	beego.Controller
	User Account.User
}

func (c *PatientController) Prepare() {
	if Account.User_r != nil {
		c.User = *Account.User_r
	}
}

// 添加患者信息
func (c *PatientController) Patient_List() {
	// 分页参数 初始化
	page, _ := c.GetInt("page")
	if page < 1 {
		page = 1
	}
	page_z, _ := c.GetInt("page_z")
	if page_z < 1 {
		page_z = conf.Page_size
	}
	// 病历号
	T_number := c.GetString("T_number")
	// 姓名
	T_name := c.GetString("T_name")
	// 标签
	T_tag, _ := c.GetInt("T_tag")
	// 诊断
	T_illness, _ := c.GetInt("T_illness")
	// 术式
	T_surgical, _ := c.GetInt("T_surgical")
	// 通知状态 1待通知 2已通知
	T_notice, _ := c.GetInt("T_notice")
	// 复诊状态 1正常 2超时
	T_follow_up, _ := c.GetInt("T_follow_up")
	// 年龄排序 1-升序 2降序
	T_age_sort, _ := c.GetInt("T_age_sort")
	// 下次复诊时间 1-升序 2降序
	T_next_time_sort, _ := c.GetInt("T_next_time_sort")
	Tag.Read_Tag_All_Map()
	Illness.Read_Illness_All_Map()
	Surgical.Read_Surgical_All_Map()
	R_List, R_cnt := Patient.Read_Patient_List(c.User.Id, T_number, T_name, T_tag, T_illness, T_surgical, T_notice, T_follow_up, T_age_sort, T_next_time_sort, page, page_z)

	var r_jsons lib.R_JSONS
	r_jsons.Num = R_cnt
	r_jsons.Data = R_List
	r_jsons.Page = page
	r_jsons.Page_size = int(math.Ceil(float64(R_cnt) / float64(page_z)))

	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: r_jsons}
	c.ServeJSON()
	return
}

// 导入患者信息
func (c *PatientController) Patient_Add() {

	T_number := c.GetString("T_number")
	T_name := c.GetString("T_name")
	T_age, _ := c.GetInt("T_age")
	T_tag := c.GetString("T_tag")
	T_illness, _ := c.GetInt("T_illness")
	T_surgical, _ := c.GetInt("T_surgical")
	T_phone := c.GetString("T_phone")
	T_notice_phone, _ := c.GetInt("T_notice_phone")
	T_notice_message, _ := c.GetInt("T_notice_message")
	T_notice_interval := c.GetString("T_notice_interval")
	T_record := c.GetString("T_record")

	var_ := Patient.Patient{
		T_uid:             c.User.Id,
		T_number:          T_number,
		T_name:            T_name,
		T_age:             T_age,
		T_tag:             T_tag,
		T_illness:         T_illness,
		T_surgical:        T_surgical,
		T_phone:           T_phone,
		T_notice_phone:    T_notice_phone,
		T_notice_message:  T_notice_message,
		T_notice_interval: T_notice_interval,
		T_record:          T_record,
		T_State:           1,
	}
	T_record_list := strings.Split(strings.Trim(T_record, "|"), "|")
	var T_time string  // 复诊时间
	var T_interval int // 复诊间隔
	if len(T_record_list) > 0 {
		temp := T_record_list[len(T_record_list)-1]
		T_time = strings.Split(temp, ",")[0]
		T_interval, _ = strconv.Atoi(strings.Split(temp, ",")[1])
		t, _ := lib.DateStrToTime(T_time)
		nextTime := t.AddDate(0, 0, T_interval)
		// 复诊状态 1正常 2超时 3结束
		var_.T_follow_up = 1
		if nextTime.Before(time.Now()) {
			var_.T_follow_up = 2
		}
		if T_interval == 0 {
			var_.T_follow_up = 3
		}
		var_.T_next_time = nextTime.Format("2006-01-02")
		var_.T_notice = 1
	}

	_, err := Patient.Add_Patient(var_)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 209, Msg: "添加失败!"}
		c.ServeJSON()
		return
	}

	System.Add_UserLogs_T(c.User.T_uuid, "患者", "新增", var_)

	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
	c.ServeJSON()
	return

}

// 修改患者信息
func (c *PatientController) Patient_Edit() {

	T_uuid := c.GetString("T_uuid")
	T_number := c.GetString("T_number")
	T_name := c.GetString("T_name")
	T_age, _ := c.GetInt("T_age")
	T_tag := c.GetString("T_tag")
	T_illness, _ := c.GetInt("T_illness")
	T_surgical, _ := c.GetInt("T_surgical")
	T_phone := c.GetString("T_phone")
	T_notice_phone, _ := c.GetInt("T_notice_phone")
	T_notice_message, _ := c.GetInt("T_notice_message")
	T_notice_interval := c.GetString("T_notice_interval")
	T_record := c.GetString("T_record")
	var err error
	var patient Patient.Patient

	if len(T_uuid) == 0 {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_uuid Err!"}
		c.ServeJSON()
		return
	}

	patient, err = Patient.Read_Patient_ByT_uuid(T_uuid)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_uuid Err!"}
		c.ServeJSON()
		return
	}
	var cols []string
	if len(T_number) > 0 {
		patient.T_number = T_number
		cols = append(cols, "T_number")
	}
	if len(T_name) > 0 {
		patient.T_name = T_name
		cols = append(cols, "T_name")
	}
	if T_age > 0 {
		patient.T_age = T_age
		cols = append(cols, "T_age")
	}

	patient.T_tag = T_tag
	cols = append(cols, "T_tag")

	patient.T_illness = T_illness
	cols = append(cols, "T_illness")

	patient.T_surgical = T_surgical
	cols = append(cols, "T_surgical")

	if len(T_phone) > 0 {
		patient.T_phone = T_phone
		cols = append(cols, "T_phone")
	}
	patient.T_notice_phone = T_notice_phone
	cols = append(cols, "T_notice_phone")

	patient.T_notice_message = T_notice_message
	cols = append(cols, "T_notice_message")

	if len(T_notice_interval) > 0 {
		patient.T_notice_interval = T_notice_interval
		cols = append(cols, "T_notice_interval")
	}
	if len(T_record) > 0 {
		patient.T_record = T_record
		cols = append(cols, "T_record")
	}
	T_record_list := strings.Split(strings.Trim(T_record, "|"), "|")
	var T_time string  // 复诊时间
	var T_interval int // 复诊间隔
	if len(T_record_list) > 0 {
		temp := T_record_list[len(T_record_list)-1]
		T_time = strings.Split(temp, ",")[0]
		T_interval, _ = strconv.Atoi(strings.Split(temp, ",")[1])
		t, _ := lib.DateStrToTime(T_time)
		nextTime := t.AddDate(0, 0, T_interval)
		nextTimeStr := nextTime.Format("2006-01-02")
		if nextTimeStr != patient.T_next_time {
			patient.T_follow_up = 1
			if nextTime.Before(time.Now()) {
				patient.T_follow_up = 2
			}
			if T_interval == 0 {
				patient.T_follow_up = 3
			}
			patient.T_next_time = nextTimeStr
			patient.T_notice = 1
		}

	}
	cols = append(cols, "T_next_time", "T_notice", "T_follow_up")

	if err = Patient.Update_Patient(patient, cols...); err != nil {
		c.Data["json"] = lib.JSONS{Code: 208, Msg: "修改失败!"}
		c.ServeJSON()
		return
	}

	System.Add_UserLogs_T(c.User.T_uuid, "用户", "修改个人信息", patient)

	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
	c.ServeJSON()
	return

}

// 删除患者信息
func (c *PatientController) Patient_Del() {
	T_uuid := c.GetString("T_uuid")
	if len(T_uuid) == 0 {
		c.Data["json"] = lib.JSONS{Code: 201, Msg: "T_uuid Err!"}
		c.ServeJSON()
		return
	}

	patient, err := Patient.Read_Patient_ByT_uuid(T_uuid)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_uuid Err!"}
		c.ServeJSON()
		return
	}
	if c.User.Id != 1 && c.User.Id != patient.T_uid {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "无权删除!"}
		c.ServeJSON()
		return
	}

	if err = Patient.Delete_Patient(patient); err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "删除失败!"}
		c.ServeJSON()
		return
	}

	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
	c.ServeJSON()
	return

}

// 发送患者满意度调查
func (c *PatientController) Patient_Send_Satisfaction() {
	T_pid := c.GetString("T_pid")
	if len(T_pid) == 0 {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_pid Err!"}
		c.ServeJSON()
		return
	}
	pidList := strings.Split(T_pid, ",")

	go func() {

		for _, v := range pidList {
			pid, _ := strconv.Atoi(v)
			patient, err := Patient.Read_Patient_ById(pid)
			playInfoList := http.GetSatisfactionPlayInfoList([]string{patient.T_name, c.User.T_user})
			res, err := http.VoiceNotifyAPI(conf.VoiceCall_Phone, "+86"+patient.T_phone, playInfoList)
			if err != nil {
				c.Data["json"] = lib.JSONS{Code: 202, Msg: "电话通知失败!"}
				c.ServeJSON()
				return
			}

			// 保存电话通知发送记录
			send := Patient.PatientSend{
				T_uid:   c.User.Id,
				T_pid:   patient.Id,
				T_phone: patient.T_phone,
				T_type:  3,
				T_id:    res.SessionId,
				T_code:  res.Resultcode,
				T_State: 0,
			}

			_, err = Patient.Add_PatientSend(send)
			if err != nil {
				System.Add_SysLogs_T("复诊通知", "添加发送记录失败", send)
			}

			if res.Resultcode != "0" {
				System.Add_SysLogs_T("复诊通知", "添加发送记录失败", send)
			}
		}

	}()
	c.Data["json"] = lib.JSONS{Code: 200, Msg: "发送成功!"}
	c.ServeJSON()
	return
}

func (c *PatientController) VoiceCall_Status() {
	// {"eventType":"callout","statusInfo":{"sessionId":"1201_14852_4294967295_20230529072219@callenabler245.huaweicaas.com","timestamp":"2023-05-29 07:22:19","caller":"+8651668971369","called":"+8618086869080"}}
	logs.Println("VoiceCall RequestBody-", string(c.Ctx.Input.RequestBody))

	type RequestBody struct {
		EventType  string `json:"eventType"`
		StatusInfo struct {
			SessionId string `json:"sessionId"`
			Timestamp string `json:"timestamp"`
			Caller    string `json:"caller"`
			Called    string `json:"called"`
			StateCode int    `json:"stateCode"`
			StateDesc string `json:"stateDesc"`
			DigitInfo string `json:"digitInfo"`
		} `json:"statusInfo"`
	}

	var body RequestBody
	data := c.Ctx.Input.RequestBody
	err := json.Unmarshal(data, &body)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "json.Unmarshal is err:" + err.Error()}
		c.ServeJSON()
	}
	r, err := Patient.Read_PatientSend_ByT_id(body.StatusInfo.SessionId)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "SessionId Err!"}
		c.ServeJSON()
		return
	}

	if body.EventType == "disconnect" {
		if body.StatusInfo.StateCode == 0 {
			r.T_State = 1
		}
		r.T_code = strconv.Itoa(body.StatusInfo.StateCode)
		r.T_remark = body.StatusInfo.StateDesc
		err = Patient.Update_PatientSend(r, "T_State", "T_remark", "T_code")
		if err != nil {
			c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改发送状态失败!"}
			c.ServeJSON()
			return
		}
	}

	if body.EventType == "collectInfo" {
		// 放音收号回调
		r.T_type = 3
		r.T_code = strconv.Itoa(body.StatusInfo.StateCode)
		if len(r.T_digitInfo) == 0 {
			r.T_digitInfo = body.StatusInfo.DigitInfo
		} else if len(r.T_digitInfo) > 0 {
			r.T_digitInfo += "," + body.StatusInfo.DigitInfo
		}
		err = Patient.Update_PatientSend(r, "T_type", "T_digitInfo")
		if err != nil {
			c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改放音收号结果失败!"}
			c.ServeJSON()
			return
		}
	}

	if r.T_type == 3 {
		go Add_PatientSatisfaction(body.StatusInfo.SessionId)
	}

	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
	c.ServeJSON()
	return

}

func Add_PatientSatisfaction(SessionId string) {
	r, err := Patient.Read_PatientSend_ByT_id(SessionId)
	if err != nil {
		logs.Error(lib.FuncName(), err)
	}
	//if len(r.T_digitInfo) == 0 {
	//	return
	//}
	var T_digitInfo []string
	if len(r.T_digitInfo) > 0 {
		T_digitInfo = strings.Split(r.T_digitInfo, ",")
	}
	// 补齐长度为5
	for len(T_digitInfo) < 5 {
		T_digitInfo = append(T_digitInfo, "0")
	}

	satis := Patient.PatientSatisfaction{
		T_id:        SessionId,
		T_uid:       r.T_uid,
		T_pid:       r.T_pid,
		T_question1: T_digitInfo[0],
		T_question2: T_digitInfo[1],
		T_question3: T_digitInfo[2],
		T_question4: T_digitInfo[3],
		T_question5: T_digitInfo[4],
	}
	Patient.Add_PatientSatisfaction(satis)
}

// 导入患者信息
func (c *PatientController) Patient_Import() {

	T_number := c.GetString("T_number")
	T_name := c.GetString("T_name")
	T_age, _ := c.GetInt("T_age")

	T_tag := c.GetString("T_tag")

	T_tag_list := strings.Split(strings.Trim(T_tag, " "), "、")
	tagIdList := []string{}
	for _, t := range T_tag_list {
		id, err := Tag.ReadOrCreate_Tag(Tag.Tag{
			T_uid:   c.User.Id,
			T_name:  t,
			T_State: 1,
		})

		if err != nil {
			c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加标签失败!"}
			c.ServeJSON()
			return
		}
		tagIdList = append(tagIdList, strconv.Itoa(int(id)))
	}

	T_illness := c.GetString("T_illness")
	illnesslId, err := Illness.ReadOrCreate_Illness(Illness.Illness{
		T_uid:   c.User.Id,
		T_name:  T_illness,
		T_State: 1,
	})
	T_surgical := c.GetString("T_surgical")
	surgicalId, err := Surgical.ReadOrCreate_Surgical(Surgical.Surgical{
		T_uid:   c.User.Id,
		T_name:  T_surgical,
		T_State: 1,
	})
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加术式失败!"}
		c.ServeJSON()
		return
	}

	T_phone := c.GetString("T_phone")
	T_notice_phone := c.GetString("T_notice_phone")
	phone := 0
	if strings.Contains(T_notice_phone, "是") {
		phone = 1
	}
	T_notice_message := c.GetString("T_notice_message")
	message := 0
	if strings.Contains(T_notice_message, "是") {
		message = 1
	}
	// 下次复诊间隔天数
	T_next_interval := c.GetString("T_next_interval")
	T_record := time.Now().Format("2006-01-02") + "," + T_next_interval + "|"
	var_ := Patient.Patient{
		T_uid:             c.User.Id,
		T_number:          T_number,
		T_name:            T_name,
		T_age:             T_age,
		T_tag:             "|" + strings.Join(tagIdList, "|") + "|",
		T_illness:         int(illnesslId),
		T_surgical:        int(surgicalId),
		T_phone:           T_phone,
		T_notice_phone:    phone,
		T_notice_message:  message,
		T_notice_interval: "1,3",
		T_record:          T_record,
		T_State:           1,
	}
	T_record_list := strings.Split(strings.Trim(T_record, "|"), "|")
	var T_time string  // 复诊时间
	var T_interval int // 复诊间隔
	if len(T_record_list) > 0 {
		temp := T_record_list[len(T_record_list)-1]
		T_time = strings.Split(temp, ",")[0]
		T_interval, _ = strconv.Atoi(strings.Split(temp, ",")[1])
		t, _ := lib.DateStrToTime(T_time)
		nextTime := t.AddDate(0, 0, T_interval)
		// 复诊状态 1正常 2超时 3结束
		var_.T_follow_up = 1
		if nextTime.Before(time.Now()) {
			var_.T_follow_up = 2
		}
		if T_interval == 0 {
			var_.T_follow_up = 3
		}
		var_.T_next_time = nextTime.Format("2006-01-02")
		var_.T_notice = 1
	}

	_, err = Patient.Add_Patient(var_)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 209, Msg: "添加失败!"}
		c.ServeJSON()
		return
	}

	System.Add_UserLogs_T(c.User.T_uuid, "患者", "导入", var_)

	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
	c.ServeJSON()
	return

}

// 导出模板
func (c *PatientController) Patient_ExportTemplate() {

	//第一个参数是文件的地址，第二个参数是下载显示的文件的名称
	c.Ctx.Output.Download("static/导入患者模板.xlsx", "导入患者模板.xlsx")
	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!"}
	c.ServeJSON()
	return
}

func (c *PatientController) VoiceCall_Satisfaction_PDF() {
	T_id := c.GetString("T_id")
	var err error
	r, err := Patient.Read_PatientSatisfaction_ByT_id(T_id)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "SessionId Err!"}
		c.ServeJSON()
		return
	}
	username := "某某医院某某科室"
	if r.T_pid > 0 {
		user, err := Account.Read_User_ByT_id(r.T_uid)
		if err != nil {
			c.Data["json"] = lib.JSONS{Code: 202, Msg: "获取用户信息失败!"}
			c.ServeJSON()
			return
		}
		username = user.T_user
	}

	//读取pdf文件
	pdf := &gopdf.GoPdf{}
	pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4}) //595.28, 841.89 = A4
	pdf.AddPage()
	err = pdf.AddTTFFont("simsun", "static/fonts/MiSans-Medium.ttf")
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
		c.ServeJSON()
		return
	}
	err = pdf.SetFont("simsun", "", 26)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
		c.ServeJSON()
		return
	}

	textw, _ := pdf.MeasureTextWidth("患者满意度调查表")
	pdf.SetX((595 / 2) - (textw / 2))
	pdf.SetY(60)
	pdf.Text("患者满意度调查表")

	fontSize := 14
	err = pdf.SetFont("simsun", "", fontSize)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
		c.ServeJSON()
		return
	}

	var parser core.TTFParser
	err = parser.Parse("static/fonts/MiSans-Medium.ttf")
	if err != nil {
		log.Print(err.Error())
		return
	}

	cap := float64(float64(parser.CapHeight()) * 1000.00 / float64(parser.UnitsPerEm()))
	//convert
	realHeight := cap * (float64(fontSize) / 1000.0) * 3
	var x float64 = 45
	pdf.SetXY(x, 100)
	pdf.Cell(nil, "尊敬的各位患者朋友：")

	msg := fmt.Sprintf("为了解各位对%s向社会和广大群众提供医疗服务的真实状况，请根据您的亲身经历或感受就以下5个问题对本科室进行真实、客观的评价，请在您认为合适的选项方框内划勾，非常感谢您的配合与支持！", username)
	msgRune := []rune(msg)
	for i := 0; i < len(msgRune); {
		pdf.Br(realHeight)

		end := 0
		step := 0
		if i == 0 {
			pdf.SetX(x + float64(fontSize*2))
			end = i + 34
			step = 34
		} else {
			pdf.SetX(x)
			end = i + 36
			step = 36
		}
		if end > len(msgRune) {
			end = len(msgRune)
		}
		pdf.Cell(nil, string(msgRune[i:end]))
		i += step

	}

	realHeight2 := cap * (float64(fontSize) / 1000.0) * 4

	pdf.Br(realHeight2)
	RectFill(pdf, "1、您对初入病房时医护人员及时询问病情和检查，是否满意？", fontSize, x, realHeight2, r.T_question1)
	pdf.Br(realHeight2)
	RectFill2(pdf, "2、您入院后是否有告知您的管床医生和护士是谁？", fontSize, x, realHeight2, r.T_question2)
	pdf.Br(realHeight2)
	RectFill(pdf, "3、您对住院期间入院注意事项的交代是否满意？", fontSize, x, realHeight2, r.T_question3)
	pdf.Br(realHeight2)
	RectFill(pdf, "4、在住院期间，您对病情解释是否满意？", fontSize, x, realHeight2, r.T_question4)
	pdf.Br(realHeight2)
	RectFill(pdf, "5、您对医护人员的服务态度是否满意？", fontSize, x, realHeight2, r.T_question3)
	pdf.Br(realHeight2)
	pdf.Br(realHeight2)
	pdf.SetX(400)
	pdf.Cell(nil, fmt.Sprintf("日期：%s", r.CreateTime.Format("2006-01-02")))

	timeStr := "ofile/" + time.Now().Format("20060102150405") + ".pdf"

	err = pdf.WritePdf(timeStr)
	if err != nil {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: err.Error()}
		c.ServeJSON()
		return
	}
	// 上传 OSS
	url, is := NatsServer.Qiniu_UploadFile(lib.GetCurrentDirectory()+"/"+timeStr, timeStr)
	if !is {
		c.Data["json"] = lib.JSONS{Code: 202, Msg: "oss!"}
		c.ServeJSON()
		return
	}

	//删除目录
	err = os.Remove(timeStr)
	if err != nil {
		fmt.Println(err)
	}

	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: url}
	c.ServeJSON()
	return

}

func RectFill(pdf *gopdf.GoPdf, text string, fontSize int, x, realHeight float64, digitInfo string) {
	pdf.SetX(x)
	pdf.Cell(nil, text)

	pdf.Br(realHeight)

	//textw, _ := pdf.MeasureTextWidth(text)

	//y := x + textw
	y := x

	var LineWidth float64 = 1

	var text1 = ""
	if digitInfo == "1" {
		text1 = "√"
	}
	pdf.SetX(y + float64(fontSize*2))
	pdf.SetLineWidth(LineWidth)
	pdf.SetLineType("") // 线条样式
	pdf.CellWithOption(&gopdf.Rect{
		W: float64(fontSize),
		H: float64(fontSize),
	}, text1, gopdf.CellOption{Align: gopdf.Center | gopdf.Middle,
		Border: gopdf.Left | gopdf.Right | gopdf.Bottom | gopdf.Top,
	})
	pdf.Cell(nil, " 非常满意")

	var text2 = ""
	if digitInfo == "2" {
		text2 = "√"
	}

	pdf.SetX(y + float64(fontSize*9))
	pdf.SetLineWidth(LineWidth)
	pdf.SetLineType("") // 线条样式
	pdf.CellWithOption(&gopdf.Rect{
		W: float64(fontSize),
		H: float64(fontSize),
	}, text2, gopdf.CellOption{Align: gopdf.Center | gopdf.Middle,
		Border: gopdf.Left | gopdf.Right | gopdf.Bottom | gopdf.Top,
	})
	pdf.Cell(nil, " 满意")

	var text3 = ""
	if digitInfo == "3" {
		text3 = "√"
	}

	pdf.SetX(y + float64(fontSize*14))
	pdf.SetLineWidth(LineWidth)
	pdf.SetLineType("") // 线条样式
	pdf.CellWithOption(&gopdf.Rect{
		W: float64(fontSize),
		H: float64(fontSize),
	}, text3, gopdf.CellOption{Align: gopdf.Center | gopdf.Middle,
		Border: gopdf.Left | gopdf.Right | gopdf.Bottom | gopdf.Top,
	})
	pdf.Cell(nil, " 不满意")

}

func RectFill2(pdf *gopdf.GoPdf, text string, fontSize int, x, realHeight float64, digitInfo string) {
	pdf.SetX(x)
	pdf.Cell(nil, text)

	pdf.Br(realHeight)

	//textw, _ := pdf.MeasureTextWidth(text)

	//y := x + textw
	y := x

	var LineWidth float64 = 1

	var text1 = ""
	if digitInfo == "1" {
		text1 = "√"
	}
	pdf.SetX(y + float64(fontSize*2))
	pdf.SetLineWidth(LineWidth)
	pdf.SetLineType("") // 线条样式
	pdf.CellWithOption(&gopdf.Rect{
		W: float64(fontSize),
		H: float64(fontSize),
	}, text1, gopdf.CellOption{Align: gopdf.Center | gopdf.Middle,
		Border: gopdf.Left | gopdf.Right | gopdf.Bottom | gopdf.Top,
	})
	pdf.Cell(nil, " 是")

	var text2 = ""
	if digitInfo == "2" {
		text2 = "√"
	}

	pdf.SetX(y + float64(fontSize*9))
	pdf.SetLineWidth(LineWidth)
	pdf.SetLineType("") // 线条样式
	pdf.CellWithOption(&gopdf.Rect{
		W: float64(fontSize),
		H: float64(fontSize),
	}, text2, gopdf.CellOption{Align: gopdf.Center | gopdf.Middle,
		Border: gopdf.Left | gopdf.Right | gopdf.Bottom | gopdf.Top,
	})
	pdf.Cell(nil, " 否")
}

func Cron_Patient() {

	//创建一个定时任务对象
	c := cron.New(cron.WithSeconds())
	//给对象增加定时任务
	//c.AddFunc("0 */1 * * * ?", Cron_Patient_ChangeFollowUp)
	c.AddFunc("@daily", Cron_Patient_ChangeFollowUp) // 修改复诊状态
	c.AddFunc("0 0 12 * * *", Cron_Patient_Notice)   // 消息通知

	//启动定时任务
	c.Start()
	defer c.Stop()

	//查询语句，阻塞，让main函数不退出，保持程序运行
	select {}

}

// 修改患者复诊状态 每晚0点统计
// 已通知并且下次复诊时间超过当期时间 已过期
func Cron_Patient_ChangeFollowUp() {

	T_date := time.Now().Format("2006-01-02")
	logs.Info("开始处理" + T_date + "患者通知状态")
	// T_notice 通知状态 1待通知 2已通知
	// T_follow_up 复诊状态 1正常 2超时
	list, _ := Patient.Read_Patient_List(0, "", "", 0, 0, 0, 2, 1, 0, 0, 0, 9999)
	for _, v := range list {
		nextTime, _ := lib.DateStrToTime(v.T_next_time)
		if nextTime.Before(time.Now()) {
			var_ := Patient.Patient{Id: v.Id, T_follow_up: 2}
			if err := Patient.Update_Patient(var_, "T_follow_up"); err != nil {
				System.Add_SysLogs_T("复诊状态", "修改失败", var_)
			}
		}
	}
}

// 给患者发送消息提醒 每天8点
// 发送成功将通知状态修改未已通知H
func Cron_Patient_Notice() {

	T_date := time.Now().Format("2006-01-02")
	logs.Info("开始发送" + T_date + "患者通知")
	// T_notice 通知状态 1待通知 2已通知
	// T_follow_up 复诊状态 1正常 2超时 3结束
	now := time.Now()
	nowDate := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local)
	userList, _ := Account.Read_User_List("", 0, 9999)
	for _, user := range userList {
		// T_arrears_notice 欠费通知 1继续通知  2终止通知
		// T_State 0删除 1启用 2停用
		// 欠费终止通知或者停用后，不再继续发送通知
		if (user.T_money <= 0 && user.T_arrears_notice == 2) || user.T_State == 2 {
			continue
		}
		patientList, _ := Patient.Read_Patient_List(user.Id, "", "", 0, 0, 0, 0, 1, 0, 0, 0, 9999)
		for _, v := range patientList {
			nextTime, _ := lib.DateStrToTime(v.T_next_time)
			var success bool
			// 提前1天
			if strings.Contains(v.T_notice_interval, "1") && nextTime.AddDate(0, 0, -1) == nowDate {
				success = Send_Notice(nextTime, user, v)
			}
			// 提前2天
			if strings.Contains(v.T_notice_interval, "2") && nextTime.AddDate(0, 0, -2) == nowDate {
				success = Send_Notice(nextTime, user, v)
			}
			// 提前3天
			if strings.Contains(v.T_notice_interval, "3") && nextTime.AddDate(0, 0, -3) == nowDate {
				success = Send_Notice(nextTime, user, v)
			}
			// 提前7天
			if strings.Contains(v.T_notice_interval, "7") && nextTime.AddDate(0, 0, -7) == nowDate {
				success = Send_Notice(nextTime, user, v)
			}
			if success == true {
				// 通知状态 1待通知 2已通知
				var_ := Patient.Patient{Id: v.Id, T_notice: 2}
				if err := Patient.Update_Patient(var_, "T_notice"); err != nil {
					System.Add_SysLogs_T("复诊通知", "修改失败", var_)
				}
			}

		}
	}
}

// 发送通知（短信、电话）
func Send_Notice(nextTime time.Time, user Account.User_R, patient Patient.Patient_R) (Success bool) {

	//发送短信通知
	if patient.T_notice_message == 1 {
		res, err := submail.SmsXSend(user.T_template_id, patient.T_phone, patient.T_name, nextTime.Format("2006年01月02日"))
		if err != nil {
			System.Add_SysLogs_T("复诊通知", "短信通知失败", patient)
		}
		// 保存短信发送记录
		smsSend := Patient.PatientSend{
			T_uid:    user.Id,
			T_pid:    patient.Id,
			T_phone:  patient.T_phone,
			T_type:   1,
			T_id:     res.Send_id,
			T_remark: res.Status,
			T_fee:    res.Fee,
			T_code:   res.Code,
			T_State:  1,
		}
		if res.Status == "error" {
			smsSend.T_State = 0
		}
		if res.Status == "success" {
			Success = true
		}
		_, err = Patient.Add_PatientSend(smsSend)
		if err != nil {
			System.Add_SysLogs_T("复诊通知", "添加发送记录失败", patient)
		}
	}

	if patient.T_notice_phone == 1 {
		// ----------- 华为语音通知
		//playInfoList := http.GetPlayInfoList(conf.VoiceCall_Template, []string{user.T_user, patient.T_name, nextTime.Format("2006/01/02")})
		//res, err := http.VoiceNotifyAPI(conf.VoiceCall_Phone, "+86"+patient.T_phone, playInfoList)
		//if err != nil {
		//	System.Add_SysLogs_T("复诊通知", "电话通知失败", patient)
		//}
		//// 保存短信发送记录
		//smsSend := Patient.PatientSend{
		//	T_uid:    user.Id,
		//	T_pid:    patient.Id,
		//	T_phone:  patient.T_phone,
		//	T_type:   2,
		//	T_id:     res.SessionId,
		//	T_remark: res.Resultdesc,
		//	T_State:  0,
		//}
		//if res.Resultcode != "0" {
		//	smsSend.T_State = 0
		//}
		//if res.Resultcode == "0" {
		//	Success = true
		//}
		//_, err = Patient.Add_PatientSend(smsSend)
		//if err != nil {
		//	System.Add_SysLogs_T("复诊通知", "添加发送记录失败", patient)
		//}

		// ----------- 塞班语音通知
		res, err := submail.VoiceXSend(patient.T_phone, user.T_user, patient.T_name, nextTime.Format("2006年01月02日"))
		if err != nil {
			System.Add_SysLogs_T("复诊通知", "电话通知失败", patient)
		}

		// 保存短信发送记录
		send := Patient.PatientSend{
			T_uid:    user.Id,
			T_pid:    patient.Id,
			T_phone:  patient.T_phone,
			T_type:   2,
			T_id:     res.Send_id,
			T_remark: res.Status,
			T_fee:    res.Fee,
			T_code:   res.Code,
			T_State:  1,
		}

		_, err = Patient.Add_PatientSend(send)
		if err != nil {
			System.Add_SysLogs_T("复诊通知", "添加语音发送记录失败", send)
		}
		if res.Status == "error" {
			send.T_State = 0
		}
		if res.Status == "success" {
			Success = true
		}
		_, err = Patient.Add_PatientSend(send)
		if err != nil {
			System.Add_SysLogs_T("复诊通知", "添加语音发送记录失败", send)
		}

	}

	return Success
}
