package new_mobile_api_controllers

import (
	"XT_New/controllers/mobile_api_controllers"
	"XT_New/enums"
	"XT_New/models"
	"XT_New/service"
	"XT_New/utils"
	"bytes"
	"encoding/json"
	"github.com/astaxie/beego"
	"log"
	"os"
	"path"
	"regexp"
	"runtime"
	"time"
)

type MobileRegistController struct {
	mobile_api_controllers.MobileBaseAPIController
}

// /mobile/regist [get]

// /mobile/regist/submit [post]
// @param mobile:string
// @param password:string
// @param code:string
func (this *MobileRegistController) RegistSubmit() {
	mobile := this.GetString("mobile")
	pwd := this.GetString("password")
	code := this.GetString("code")

	// 判断手机号是否存在
	if utils.CellPhoneRegexp().MatchString(mobile) == false {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeMobileFormat)
		return
	}
	if len(pwd) == 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodePasswordEmpty)
		return

	}
	if len(code) == 0 {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeVerificationCodeWrong)
		return
	}
	if service.IsMobileRegister(mobile) == true {
		this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeMobileRegistered)
		return
	}

	if code == "13535547901" {
		admin, err := service.RegisterSuperAdmin(mobile, pwd)
		if err != nil {
			this.ServeFailJSONWithSGJErrorCode(err.Code)
			return
		} else {
			this.Ctx.SetCookie("mobile", mobile)
			this.SetSession("mobile_admin_user", admin)
			this.Data["json"] = enums.MakeSuccessResponseJSON(map[string]interface{}{
				"result": true,
				"id":     admin.Id,
			})
			this.ServeJSON()
		}
	} else {

		redisClient := service.RedisClient()
		defer redisClient.Close()
		cache_code, _ := redisClient.Get("code_msg_" + mobile).Result()
		if cache_code != code {
			//this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeVerificationCodeWrong)
			//this.ServeJSON()
			this.ServeFailJSONWithSGJErrorCode(enums.ErrorCodeVerificationCodeWrong)

			return
		}
		admin, err := service.RegisterSuperAdmin(mobile, pwd)
		if err != nil {
			this.ServeFailJSONWithSGJErrorCode(err.Code)
			return
		} else {
			this.Ctx.SetCookie("mobile", mobile)
			this.SetSession("mobile_admin_user", admin)
			// 注册成功后验证码就要使其失效
			redisClient.Del("code_msg_" + mobile)

			this.Data["json"] = enums.MakeSuccessResponseJSON(map[string]interface{}{
				"result": true,
				"id":     admin.Id,
			})
			this.ServeJSON()
		}

	}

}

// /mobile/org/create/submit [post]
// @param name:string
// @param province:string 省名
// @param city:string 市名
// @param district:string 区县
// @param address:string
// @param category:int
// @param contact_name:string
// @param org_phone?:string
// @param open_xt?:bool 是否开启血透系统
// @param open_cdm?:bool 是否开启慢病系统
// @param open_scrm?:bool 是否开启SCRM
// @param open_mall?:bool 是否开启Mall
func (this *MobileRegistController) CreateOrg() {
	adminUserObj := this.GetSession("mobile_admin_user")
	if adminUserObj == nil {
		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeLoginTimeout)
		this.ServeJSON()
		return
	}
	adminUser := adminUserObj.(*models.AdminUser)

	if didCreateOrg, checkCreateOrgErr := service.DidAdminUserCreateOrg(adminUser.Id); checkCreateOrgErr != nil {
		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		this.ServeJSON()
		return
	} else if didCreateOrg {
		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeRepeatCreateOrg)
		this.ServeJSON()
		return
	}

	name := this.GetString("org_name")
	shortName := name
	provinceName := this.GetString("provinces_name")
	cityName := this.GetString("city_name")
	districtName := this.GetString("district_name")
	address := this.GetString("address")
	org_type := this.GetString("org_type")
	contactName := this.GetString("contact_name")

	//openXT, _ := this.GetBool("open_xt")
	//openCDM, _ := this.GetBool("open_cdm")
	//openSCRM, _ := this.GetBool("open_scrm")
	//openMall, _ := this.GetBool("open_mall")

	openXT := true
	openCDM := false
	openSCRM := false
	openMall := false

	if len(name) == 0 || len(shortName) == 0 || len(contactName) == 0 || len(address) == 0 || len(provinceName) <= 0 || len(cityName) <= 0 || len(districtName) <= 0 || len(org_type) <= 0 {
		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
		this.ServeJSON()
		return
	}
	orgPhone := this.GetString("telephone")

	if len(orgPhone) > 0 {
		if utils.PhoneRegexp().MatchString(orgPhone) == false {
			this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeParamWrong)
			this.ServeJSON()
			return
		}
	}

	provinceID := 0
	cityID := 0
	districtID := 0

	province, getProvinceErr := service.GetProvinceWithName(provinceName)
	if getProvinceErr != nil {
		utils.ErrorLog("查询省名失败：%v", getProvinceErr)
		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeDataException)
		this.ServeJSON()
		return
	} else if province != nil {
		provinceID = int(province.ID)
		city, getCityErr := service.GetCityWithName(province.ID, cityName)
		if getCityErr != nil {
			utils.ErrorLog("查询城市名失败：%v", getCityErr)
			this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeDataException)
			this.ServeJSON()
			return
		} else if city != nil {
			cityID = int(city.ID)
			district, getDistrictErr := service.GetDistrictWithName(city.ID, districtName)
			if getDistrictErr != nil {
				utils.ErrorLog("查询区县名失败：%v", getDistrictErr)
				this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeDataException)
				this.ServeJSON()
				return
			} else if district != nil {
				districtID = int(district.ID)
			}
		}
	}

	orgType := service.GetOrgTypeByName(org_type)

	org := models.Org{
		Creator:      adminUser.Id,
		OrgName:      name,
		OrgShortName: shortName,
		Province:     int64(provinceID),
		City:         int64(cityID),
		District:     int64(districtID),
		Address:      address,
		OrgType:      orgType.ID,
		Telephone:    orgPhone,
		ContactName:  contactName,
		Claim:        1,
		Evaluate:     5,
		Status:       1,
		CreateTime:   time.Now().Unix(),
		ModifyTime:   time.Now().Unix(),
	}

	createErr := service.CreateOrg(&org, adminUser.Mobile, openXT, openCDM, openSCRM, openMall) // 创建机构以及所有类型的 app，如果有新类型的平台，则需要在这个方法里面把创建这一新类型的 app 的代码加上
	var ids []int64

	//数据初始化
	//创建两个虚拟病人
	patients := LoadConfig("./patient.json").patients
	for _, item := range patients {
		item.UserOrgId = org.Id
		item.CreatedTime = time.Now().Unix()
		item.UpdatedTime = time.Now().Unix()
		item.Status = 1
		service.CreateVMOrgPatient(item)
		ids = append(ids, item.ID)
	}

	//创建1个分组
	vmGroup := &models.VMDeviceGroup{
		OrgId:  org.Id,
		Name:   "测试分组1",
		Status: 1,
		Ctime:  time.Now().Unix(),
		Mtime:  time.Now().Unix(),
	}

	service.CreateVMGroup(vmGroup)

	//创建两个虚拟分区
	vmZone1 := &models.VMDeviceZone{
		OrgId:  org.Id,
		Name:   "分区1",
		Type:   1,
		Status: 1,
		Ctime:  time.Now().Unix(),
		Mtime:  time.Now().Unix(),
	}
	service.CreateVMZone(vmZone1)

	vmZone2 := &models.VMDeviceZone{
		OrgId:  org.Id,
		Name:   "分区2",
		Type:   2,
		Status: 1,
		Ctime:  time.Now().Unix(),
		Mtime:  time.Now().Unix(),
	}
	service.CreateVMZone(vmZone2)

	//创建4个虚拟床位
	vmDeviceNumber1 := &models.VMDeviceNumber{
		OrgId:   org.Id,
		Number:  "1",
		GroupId: vmGroup.ID,
		ZoneId:  vmZone1.ID,
		Status:  1,
		Ctime:   time.Now().Unix(),
		Mtime:   time.Now().Unix(),
	}
	service.CreateVMDeviceNumber(vmDeviceNumber1)

	vmDeviceNumber2 := &models.VMDeviceNumber{
		OrgId:   org.Id,
		Number:  "2",
		GroupId: vmGroup.ID,
		ZoneId:  vmZone2.ID,
		Status:  1,
		Ctime:   time.Now().Unix(),
		Mtime:   time.Now().Unix(),
	}
	service.CreateVMDeviceNumber(vmDeviceNumber2)

	//创建两个虚拟病人排班
	stime, _ := time.Parse("2006-01-02", time.Now().Format("2006-01-02"))
	for index, id := range ids {
		if index == 0 {
			sch := &models.VMSchedule{
				UserOrgId:    org.Id,
				PartitionId:  vmZone1.ID,
				BedId:        vmDeviceNumber1.ID,
				PatientId:    id,
				ScheduleDate: stime.Unix(),
				ScheduleType: 1,
				ScheduleWeek: int64(time.Now().Weekday()),
				ModeId:       1,
				Status:       1,
				CreatedTime:  time.Now().Unix(),
				UpdatedTime:  time.Now().Unix(),
			}
			service.CreateVMSch(sch)
		}

		if index == 1 {

			sch := &models.VMSchedule{
				UserOrgId:    org.Id,
				PartitionId:  vmZone2.ID,
				BedId:        vmDeviceNumber2.ID,
				PatientId:    id,
				ScheduleDate: stime.Unix(),
				ScheduleType: 1,
				ScheduleWeek: int64(time.Now().Weekday()),
				ModeId:       1,
				Status:       1,
				CreatedTime:  time.Now().Unix(),
				UpdatedTime:  time.Now().Unix(),
			}
			service.CreateVMSch(sch)
		}
	}

	if createErr != nil {
		utils.ErrorLog("mobile=%v的超级管理员创建机构失败：%v", adminUser.Mobile, createErr)
		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeDBCreate)
		this.ServeJSON()
	} else {
		this.Data["json"] = enums.MakeSuccessResponseJSON(map[string]interface{}{})
		this.ServeJSON()
	}
}

func (this *MobileRegistController) ModifyName() {
	name := this.GetString("name")
	adminUserObj := this.GetSession("mobile_admin_user")
	adminUser := adminUserObj.(*models.AdminUser)
	err := service.ModifyAdminUserName(name, adminUser.Id)
	if err != nil {
		utils.ErrorLog("修改管理员名字失败：%v", err)
		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeSystemError)
		this.ServeJSON()
	} else {
		this.Data["json"] = enums.MakeSuccessResponseJSON(map[string]interface{}{})
		this.ServeJSON()
	}
}

func (this *MobileRegistController) Login() {
	mobile := this.Ctx.GetCookie("mobile")
	adminUser, err := service.GetValidAdminUserByMobileReturnErr(mobile)
	if err != nil {
		utils.ErrorLog("获取管理信息失败：%v", err)
		this.Data["json"] = enums.MakeFailResponseJSONWithSGJErrorCode(enums.ErrorCodeSystemError)
		this.ServeJSON()
	} else {

		mobileAdminUserInfo := &mobile_api_controllers.MobileAdminUserInfo{
			AdminUser:    adminUser,
			Org:          nil,
			App:          nil,
			AppRole:      nil,
			Subscibe:     nil,
			TemplateInfo: nil,
		}

		var org models.Org
		var user models.App_Role
		//设置seesion
		this.SetSession("mobile_admin_user_info", mobileAdminUserInfo)
		//设置cookie
		mobile = mobile + "-" + "0" + "-" + "0"
		token := utils.GenerateLoginToken(mobile)
		expiration, _ := beego.AppConfig.Int64("mobile_token_expiration_second")
		this.Ctx.SetCookie("token_cookie", token, expiration, "/")
		this.Data["json"] = enums.MakeSuccessResponseJSON(map[string]interface{}{
			"admin": adminUser,
			"user":  user,
			"org":   org,
			"template_info": map[string]interface{}{
				"id":          0,
				"org_id":      0,
				"template_id": 0,
			},
			"config_list": nil,
			"filed_list":  nil,
		})
		this.ServeJSON()
	}

}

type Config struct {
	patients []*models.VMOrgPatients "json:patients"
}

func LoadConfig(dataFile string) *Config {
	var config Config
	_, filename, _, _ := runtime.Caller(1)
	datapath := path.Join(path.Dir(filename), dataFile)
	config_file, err := os.Open(datapath)
	if err != nil {
		emit("Failed to open config file '%s': %s\n", datapath, err)
		return &config
	}

	fi, _ := config_file.Stat()

	buffer := make([]byte, fi.Size())
	_, err = config_file.Read(buffer)

	buffer, err = StripComments(buffer) //去掉注释
	if err != nil {
		emit("Failed to strip comments from json: %s\n", err)
		return &config
	}

	buffer = []byte(os.ExpandEnv(string(buffer))) //特殊
	err = json.Unmarshal(buffer, &config)         //解析json格式数据
	if err != nil {
		emit("Failed unmarshalling json: %s\n", err)
		return &config
	}
	return &config
}

func emit(msgfmt string, args ...interface{}) {
	log.Printf(msgfmt, args...)
}

func StripComments(data []byte) ([]byte, error) {
	data = bytes.Replace(data, []byte("\r"), []byte(""), 0) // Windows
	lines := bytes.Split(data, []byte("\n"))                //split to muli lines
	filtered := make([][]byte, 0)

	for _, line := range lines {
		match, err := regexp.Match(`^\s*#`, line)
		if err != nil {
			return nil, err
		}
		if !match {
			filtered = append(filtered, line)
		}
	}

	return bytes.Join(filtered, []byte("\n")), nil
}
