/*
 * @description: 项目相关数据处理
 * @Author: CP
 * @Date: 2020-09-04 14:42:27
 * @FilePath: \construction_management\services\project_service.go
 */
package services

import (
	"errors"
	"html"
	"log"
	"strconv"
	"time"

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

// 定义项目Service接口
type ProjectService interface {
	//ValidManager(code string, account string, password string) error
	ValidRule(iris.Context) (viewmodels.Project, error)
	ValidRulePage(iris.Context) (viewmodels.ProjectPage, error)
	ValidRuleId(ctx iris.Context) (viewmodels.Project, error)

	Get(projectId int) (*viewmodels.Project, error)
	GetList(page int, size int) []viewmodels.Project
	GetName(code string) []viewmodels.Project
	GetNameBs(code string) models.CmProject
	Save(projectId int, projectVM viewmodels.Project) error
	Add(projectVM viewmodels.Project) error
	SaveBs(projectVM viewmodels.Project, id int, manager *models.CmManager) error
	GetListBs(pageData viewmodels.ProjectPage, staffName string, category string) (data []viewmodels.Project, total int64)
}

// 返回service操作类
type projectService struct {
	dao       *dao.ProjectDao
	validSave string
}

// 创建项目service
func NewProjectService() ProjectService {
	return &projectService{
		dao:       dao.NewProjectDao(datasource.InstanceDbMaster()),
		validSave: "/api/projectSetting/project/save",
	}
}

func (s *projectService) ValidRulePage(ctx iris.Context) (viewmodels.ProjectPage, error) {
	projectVaild := viewmodels.ProjectPage{}
	err := ctx.ReadJSON(&projectVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return projectVaild, err
	}

	err = projectVaild.ValidatePage()
	if err != nil {
		log.Println("参数验证错误, error=", err)
		return projectVaild, err
	}

	return projectVaild, nil
}

// 验证项目
func (s *projectService) ValidRuleId(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 *projectService) ValidRule(ctx iris.Context) (viewmodels.Project, error) {
	projectVaild := viewmodels.Project{}
	var err error
	if ctx.Method() == "POST" {
		err = ctx.ReadJSON(&projectVaild)
		if err != nil {
			log.Println("project-ValidRule-ReadForm转换异常, error=", err)
			return projectVaild, err
		}
	} else {
		err = ctx.ReadForm(&projectVaild)
		if err != nil {
			log.Println("project-ValidRule-ReadForm转换异常, error=", err)
			return projectVaild, err
		}
	}

	if ctx.Path() == s.validSave {
		err = projectVaild.ValidateName()
	} else {
		err = projectVaild.Validate()
	}

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

	projectVaild.Code = html.EscapeString(projectVaild.Code)
	projectVaild.Name = html.EscapeString(projectVaild.Name)

	return projectVaild, nil
}

// ID获得项目信息-TODO
func (s *projectService) Get(projectId int) (*viewmodels.Project, error) {
	data, err := s.dao.FindById(projectId)
	if err != nil {
		return nil, errors.New("获得项目详情出错")
	}
	project := makeProjectVM(data)

	return &project, nil
}

// 获得一组项目信息 -项目编号
func (s *projectService) GetList(page int, size int) []viewmodels.Project {
	if size > 100 {
		size = 100
	}
	datalist := make([]viewmodels.Project, 0)
	projectData := s.dao.GetPage(page, size)
	for _, data := range projectData {
		projectVM := makeProjectVM(&data)
		datalist = append(datalist, projectVM)
	}
	return datalist
}

// 后端获得列表
func (s *projectService) GetListBs(pageData viewmodels.ProjectPage, staffName string, category string) (data []viewmodels.Project, total int64) {
	if pageData.Size > 100 {
		pageData.Size = 100
	}
	datalist := make([]viewmodels.Project, 0)
	// 1.获得管理员信息
	managerDao := dao.NewManagerDao(datasource.InstanceDbMaster())
	managerData := managerDao.GetUserName(staffName)
	if managerData.Id == 0 {
		return datalist, 0
	}

	// 2024-01-10 改成 拥有超级管理员 所有项目
	// 办事处只能访问改办事处的
	//待启用
	category = managerData.Office
	if managerData.IsAdmin == 1 {
		category = ""
	}
	//待启用

	// pageData里的InsideCategoryId 去除，不需要判断
	projectData, count := s.dao.GetPageBsByCategory(pageData, category)

	for _, data := range projectData {
		projectVM := makeProjectVM(&data)
		datalist = append(datalist, projectVM)
	}
	return datalist, count
}

// 获得项目名称
func (s *projectService) GetName(code string) []viewmodels.Project {
	datalist := make([]viewmodels.Project, 0)
	if code != "" {
		projectData := s.dao.GetListByCode(code)
		for _, data := range projectData {
			projectVM := makeProjectNameVM(&data)
			datalist = append(datalist, projectVM)
		}
		return datalist
	}
	return datalist
}

// 获得项目名称
func (s *projectService) GetNameBs(code string) models.CmProject {
	result := s.dao.GetListByCode(code)
	if len(result) == 0 {
		return models.CmProject{}
	}
	return result[0]
}

// 保存项目信息
func (s *projectService) Save(id int, projectVM viewmodels.Project) error {
	project := models.CmProject{}
	project.Id = id
	project.Name = projectVM.Name

	err := s.dao.Update(&project, []string{"Name"})

	return err
}

// 新增项目
func (s *projectService) Add(projectVM viewmodels.Project) error {

	// 1.是否已经有相关的项目编号了
	projectData := s.dao.GetCode(projectVM.Code)
	if projectData.Id != 0 {
		return errors.New("项目编号已存在")
	}

	project := &models.CmProject{}
	project.Name = projectVM.Name
	project.Code = projectVM.Code
	project.CategoryId = projectVM.CategoryId
	project.Category = projectVM.Category
	project.InsideCategoryid = projectVM.InsideCategoryid
	project.InsideCategory = projectVM.InsideCategory
	project.StaffId = projectVM.StaffId
	project.StaffName = projectVM.StaffName
	project.CreateTime = time.Now()
	project.CreateName = projectVM.CreateName
	project.CreateCategory = projectVM.CreateCategory
	project.Remark = projectVM.Remark

	err := s.dao.Add(project)
	return err
}

// 更新项目-后台
func (s *projectService) SaveBs(projectVM viewmodels.Project, id int, manager *models.CmManager) error {

	// 1.获得项目信息
	projectData, _ := s.dao.FindById(id)
	// 管理员和自己可以更新
	if manager.IsAdmin != 1 {
		if manager.Username != projectData.StaffName {
			return errors.New("无权编辑")
		}
	}

	project := &models.CmProject{}
	project.Id = id
	project.Name = projectVM.Name
	project.InsideCategoryid = projectVM.InsideCategoryid
	project.InsideCategory = projectVM.InsideCategory

	project.CategoryId = projectVM.CategoryId
	project.Category = projectVM.Category

	project.StaffId = projectVM.StaffId
	project.StaffName = projectVM.StaffName
	project.StaffPhone = projectVM.StaffPhone
	project.StaffQq = projectVM.StaffQq
	project.StaffTelephone = projectVM.StaffTelephone

	project.Remark = projectVM.Remark
	project.Status = projectVM.Status

	err := s.dao.Update(project, []string{"Name", "InsideCategoryid", "InsideCategory", "CategoryId", "Category", "StaffId", "StaffName", "Remark", "Status"})

	return err
}

// 构造视图层models
func makeProjectVM(projectCM *models.CmProject) viewmodels.Project {
	projectVM := viewmodels.Project{}
	id, _ := comm.AesEncrypt(strconv.Itoa(projectCM.Id), conf.SignSecret)
	userId, _ := comm.AesEncrypt(strconv.Itoa(projectCM.UserId), conf.SignSecret)
	staffId, _ := comm.AesEncrypt(projectCM.StaffId, conf.SignSecret)

	projectVM.Id = id
	projectVM.Code = projectCM.Code
	projectVM.Name = projectCM.Name
	projectVM.CategoryId = projectCM.CategoryId
	projectVM.Category = projectCM.Category
	projectVM.StaffIdEncrypted = staffId
	projectVM.StaffId = projectCM.StaffId
	projectVM.StaffName = projectCM.StaffName
	projectVM.StaffPhone = projectCM.StaffPhone
	projectVM.StaffQq = projectCM.StaffQq
	projectVM.StaffTelephone = projectCM.StaffTelephone
	projectVM.UserId = userId
	projectVM.UserAccount = projectCM.UserAccount
	projectVM.CreateName = projectCM.CreateName
	projectVM.Status = projectCM.Status
	projectVM.InsideCategory = projectCM.InsideCategory
	projectVM.InsideCategoryid = projectCM.InsideCategoryid

	if !projectCM.CreateTime.IsZero() {
		projectVM.CreateTime = projectCM.CreateTime.Format(conf.SysTimeform)
	}

	return projectVM
}

func makeProjectNameVM(projectCM *models.CmProject) viewmodels.Project {
	projectVM := viewmodels.Project{}
	projectVM.Code = projectCM.Code
	projectVM.Name = projectCM.Name
	return projectVM
}

// 获得单个项目信息-ID 编号
// func (s *projectService) Get(projectVM *viewmodels.Project) {
// 	projectCM := models.CmProject{}

// 	// 项目ID或编号
// 	if projectVM.Id == "" && projectVM.Code == "" {
// 		projectVM.Id = "0"
// 		return
// 		//return errors.New("项目ID或者项目编号不存在")
// 	}

// 	if projectVM.Id != "" {
// 		projectId, err := comm.AesDecrypt(projectVM.Id, conf.SignSecret)
// 		if err != nil {
// 			projectVM.Id = "0"
// 			return
// 		}
// 		projectIdInt, err := strconv.Atoi(projectId)
// 		if err != nil {
// 			projectVM.Id = "0"
// 			return
// 		}
// 		if projectIdInt != 0 {
// 			projectCM.Id = projectIdInt
// 		}
// 	} else if projectVM.Code != "" {
// 		projectCM.Code = projectVM.Code
// 	} else {
// 		projectVM.Id = "0"
// 		return
// 	}

// 	s.dao.Get(&projectCM)
// 	if projectCM.Id != 0 {
// 		// 项目信息补充完整
// 		projectB := makeProjectVM(&projectCM)
// 		projectVM = &projectB
// 	} else {
// 		projectVM.Id = "0"
// 		return
// 	}
// }
