/*
 * @description:登陆相关数据操作
 * @Author: CP
 * @Date: 2020-09-02 09:56:28
 * @FilePath: \construction_management\services\backstage_service.go
 */
package services

import (
	"errors"
	"log"
	"net/http"
	"net/url"
	"time"

	"github.com/kataras/iris/v12"
	"go.mod/comm"
	"go.mod/conf"
	"go.mod/dao"
	"go.mod/datasource"
	"go.mod/lib"
	"go.mod/models"
	"go.mod/web/viewmodels"
)

//定义项目用户Service接口
type BackstageService interface {
	ValidRuleLogin(ctx iris.Context) (viewmodels.StaffCld, error)
	ValidCldStaff(loginData viewmodels.StaffCld, writer http.ResponseWriter) (*viewmodels.ResultCld, error)
	ValidRuleProject(ctx iris.Context) (viewmodels.Project, error)
	ValidRuleProjectAdd(ctx iris.Context) (viewmodels.Project, error)
	ValidRuleProjectSave(ctx iris.Context) (viewmodels.Project, error)
	ValidRuleAccountAdd(ctx iris.Context) (viewmodels.ProjectAccount, error)
	ValidRuleAccountSave(ctx iris.Context) (viewmodels.ProjectAccount, error)
	ValidRuleAccountEnable(ctx iris.Context) (viewmodels.ProjectAccount, error)
	ValidRuleAccountPassword(ctx iris.Context) (viewmodels.ProjectAccount, error)

	GetCldByCategoryId(categoryId string) (map[string]interface{}, error)
	Out(ctx iris.Context) error
}

//返回service操作类
type backstageService struct {
	// projectAccountDao *dao.ProjectAccountDao
	managerDao *dao.ManagerDao
}

//创建项目用户service
func NewBackstageService() BackstageService {
	return &backstageService{
		// projectAccountDao: dao.NewProjectAccountDao(datasource.InstanceDbMaster()),
		managerDao: dao.NewManagerDao(datasource.InstanceDbMaster()),
	}
}

// 登陆验证
func (s *backstageService) ValidRuleLogin(ctx iris.Context) (viewmodels.StaffCld, error) {
	loginVaild := viewmodels.StaffCld{}
	err := ctx.ReadJSON(&loginVaild)
	if err != nil {
		log.Println("ReadForm转换异常, error=", err)
		return loginVaild, err
	}

	err = loginVaild.ValidateLogin()
	if err != nil {
		log.Println("登录验证, error=", err)
		return loginVaild, err
	}
	return loginVaild, nil
}

// 验证项目
func (s *backstageService) ValidRuleProject(ctx iris.Context) (viewmodels.Project, error) {
	projectVaild := viewmodels.Project{}
	err := ctx.ReadForm(&projectVaild)
	if err != nil {
		log.Println("ReadForm转换异常, error=", err)
		return projectVaild, err
	}

	err = projectVaild.ValidateId()
	if err != nil {
		log.Println("验证项目, error=", err)
		return projectVaild, err
	}
	return projectVaild, nil
}

// 验证项目
func (s *backstageService) ValidRuleProjectAdd(ctx iris.Context) (viewmodels.Project, error) {
	projectVaild := viewmodels.Project{}
	err := ctx.ReadJSON(&projectVaild)
	if err != nil {
		log.Println("ReadForm转换异常, error=", err)
		return projectVaild, err
	}

	err = projectVaild.ValidateAdd()
	if err != nil {
		log.Println("添加项目验证, error=", err)
		return projectVaild, err
	}
	return projectVaild, nil
}

// 项目保存
func (s *backstageService) ValidRuleProjectSave(ctx iris.Context) (viewmodels.Project, error) {
	projectVaild := viewmodels.Project{}
	err := ctx.ReadJSON(&projectVaild)
	if err != nil {
		log.Println("ReadForm转换异常, error=", err)
		return projectVaild, err
	}

	err = projectVaild.ValidateSave()
	if err != nil {
		log.Println("添加项目验证, error=", err)
		return projectVaild, err
	}
	return projectVaild, nil
}

// 验证账号新增
func (s *backstageService) ValidRuleAccountAdd(ctx iris.Context) (viewmodels.ProjectAccount, error) {
	projectVaild := viewmodels.ProjectAccount{}
	err := ctx.ReadJSON(&projectVaild)
	if err != nil {
		log.Println("ReadForm转换异常, error=", err)
		return projectVaild, err
	}

	err = projectVaild.ValidateAddBs()
	if err != nil {
		log.Println("添加账号验证, error=", err)
		return projectVaild, err
	}
	return projectVaild, nil
}

// 验证账号编辑
func (s *backstageService) ValidRuleAccountSave(ctx iris.Context) (viewmodels.ProjectAccount, error) {
	projectVaild := viewmodels.ProjectAccount{}
	err := ctx.ReadJSON(&projectVaild)
	if err != nil {
		log.Println("ReadForm转换异常, error=", err)
		return projectVaild, err
	}

	err = projectVaild.ValidateSaveBs()
	if err != nil {
		log.Println("编辑账号验证, error=", err)
		return projectVaild, err
	}
	return projectVaild, nil
}

// 验证账号启用
func (s *backstageService) ValidRuleAccountEnable(ctx iris.Context) (viewmodels.ProjectAccount, error) {
	accounttVaild := viewmodels.ProjectAccount{}
	err := ctx.ReadForm(&accounttVaild)
	if err != nil {
		log.Println("ReadForm转换异常, error=", err)
		return accounttVaild, err
	}

	err = accounttVaild.ValidateEnableBs()
	if err != nil {
		log.Println("编辑账号验证, error=", err)
		return accounttVaild, err
	}
	return accounttVaild, nil
}

// 验证账号启用
func (s *backstageService) ValidRuleAccountPassword(ctx iris.Context) (viewmodels.ProjectAccount, error) {
	accounttVaild := viewmodels.ProjectAccount{}
	err := ctx.ReadForm(&accounttVaild)
	if err != nil {
		log.Println("ReadForm转换异常, error=", err)
		return accounttVaild, err
	}

	err = accounttVaild.ValidatePasswordBs()
	if err != nil {
		log.Println("账号密码验证, error=", err)
		return accounttVaild, err
	}
	return accounttVaild, nil
}

// 验证项目用户登陆相关
func (s *backstageService) ValidCldStaff(loginData viewmodels.StaffCld, writer http.ResponseWriter) (*viewmodels.ResultCld, error) {

	// 1.cld账号写入管理员表
	managerData := s.managerDao.GetUserName(loginData.StaffName)
	result := &lib.Result{}

	if managerData.Id != 0 && managerData.GroupId == 1 {
		result.Data.UserName = "admin"
		result.Data.Category = "admin"

		if !(managerData.Username == loginData.StaffName && managerData.Password == loginData.Password) {
			return nil, errors.New("账号或者密码不正确")
		}

	} else {
		// 1.验证CLD账号密码
		cld := lib.NewCld()
		result, err := cld.LoginValid(loginData)
		if err != nil {
			return nil, err
		}
		if result.Code != 0 {
			return nil, errors.New(result.Msg)
		}

		if managerData.Id == 0 {
			// 写入管理表
			manager := &models.CmManager{}

			manager.Username = result.Data.UserName

			manager.CreateTime = time.Now()
			manager.UpdateTime = time.Now()
			manager.LastLogin = time.Now()

			manager.Category = result.Data.Category
			manager.Office = result.Data.CategoryId
			manager.Telephone = result.Data.Telephone
			manager.Email = result.Data.Email
			manager.Qq = result.Data.Qq
			manager.Fixedphone = result.Data.Fixedphone
			manager.Position = result.Data.Position

			err = s.managerDao.Create(manager)
			if err != nil {
				return nil, err
			}
		}

	}

	// 2-1
	if managerData.CanLogin == 0 {
		return nil, errors.New("不允许登陆")
	}

	// 3.写入登录态
	// 加密用户标识
	identity, err := comm.AesEncrypt(result.Data.UserName, conf.CookieSecret)
	if err != nil {
		return nil, err
	}
	// 加密项目标识
	category, err := comm.AesEncrypt(result.Data.Category, conf.CookieSecret)
	if err != nil {
		return nil, err
	}

	digitalToken := comm.CreateSign(conf.CookieSecret + identity)

	// 设置cookie
	maxAge := 60 * 60 * 24 * 7
	params := url.Values{}
	params.Add("identity", identity)
	params.Add("attachedIdentity", category)
	params.Add("digitalToken", digitalToken)
	c := &http.Cookie{
		Name:     "cmBackstage",
		Value:    params.Encode(),
		Path:     "/",
		MaxAge:   maxAge,
		HttpOnly: true,
	}
	http.SetCookie(writer, c)

	// staffCld := &viewmodels.StaffCld{}
	// staffCld.Category = result.Data.Category
	// staffCld.StaffName = result.Data.UserName

	return &result.Data, nil
}

// 登出
func (s *backstageService) Out(ctx iris.Context) error {
	// 移除cookie
	ctx.RemoveCookie("cmBackstage")
	return nil
}

// 获得cld办事处和员工 列表
func (s *backstageService) GetCldByCategoryId(categoryId string) (map[string]interface{}, error) {
	cld := lib.NewCld()

	result, err := cld.GetList(categoryId)
	if err != nil {
		return nil, err
	}

	if result["code"].(float64) != 0 {
		return nil, errors.New(result["code"].(string))
	}
	return result, nil
}
