/*
 * @description: 合同数据相关操作
 * @Author: CP
 * @Date: 2020-10-27 11:28:24
 * @FilePath: \design_quantity\services\contract_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 ContractService interface {
	ValidRuleDepth(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
	ValidRuleTemplate(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
	ValidRuleSectionAdd(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
	ValidRuleSectionDelete(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
	ValidRuleSectionNot(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
	ValidRuleGet(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
	ValidRuleUpdateFile(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
	ValidRuleSerial(ctx iris.Context) (*viewmodels.TreeSectionContract, error)

	// 项目节
	GetSecionTree(operation string) *viewmodels.TreeSectionContract
	SetSection() error
	GetSection(id int) *viewmodels.TreeSectionDetail
	SectionAdd(sectionData *viewmodels.TreeSectionContract) (*models.CmTreeContracts, error)
	SectionSave(sectionData *viewmodels.TreeSectionContract) error
	UpdateSerial(sectionData *viewmodels.TreeSectionContract) error
	SectionDelete(treeId int) error
	MoveDepth(sectionData *viewmodels.TreeSectionContract) error
	MoveSerial(sectionData *viewmodels.TreeSectionContract) error
	UpdateContractId(id int, contractId int) error

	SaveUpload(Location string, Filename string, ext string) (string, error)
}

//返回service操作类
type contractService struct {
	treeContractDao   *dao.TreeContractDao
	contractDao       *dao.ContractDao
	contractReturnDao *dao.ContractReturnDao
	contractPaidDao   *dao.ContractPaidDao
	treeDao           *dao.TreeDao
	annexDao          *dao.AnnexDao
	uploadDao         *dao.UploadDao
}

//创建项目用户service
func NewContractService() ContractService {
	return &contractService{
		treeContractDao:   dao.NewTreeContractDao(datasource.InstanceDbMaster()),
		contractDao:       dao.NewContractDao(datasource.InstanceDbMaster()),
		contractReturnDao: dao.NewContractReturnDao(datasource.InstanceDbMaster()),
		contractPaidDao:   dao.NewContractPaidDao(datasource.InstanceDbMaster()),
		treeDao:           dao.NewTreeDao(datasource.InstanceDbMaster()),
		annexDao:          dao.NewAnnexDao(datasource.InstanceDbMaster()),
		uploadDao:         dao.NewUploadDao(datasource.InstanceDbMaster()),
	}
}

// 升级降级规则验证
func (s *contractService) ValidRuleDepth(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
	treeSectionVaild := &viewmodels.TreeSectionContract{}
	err := ctx.ReadJSON(treeSectionVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return treeSectionVaild, err
	}

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

	return treeSectionVaild, nil
}

// 模板规则验证
func (s *contractService) ValidRuleTemplate(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
	treeSectionVaild := &viewmodels.TreeSectionContract{}
	err := ctx.ReadJSON(treeSectionVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return treeSectionVaild, err
	}

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

	return treeSectionVaild, nil
}

// 模板规则新增项目节
func (s *contractService) ValidRuleSectionAdd(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
	treeSectionVaild := &viewmodels.TreeSectionContract{}
	err := ctx.ReadJSON(treeSectionVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return treeSectionVaild, err
	}

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

	return treeSectionVaild, nil
}

// 模板规则新增项目节
func (s *contractService) ValidRuleSectionDelete(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
	treeSectionVaild := &viewmodels.TreeSectionContract{}
	err := ctx.ReadForm(treeSectionVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return treeSectionVaild, err
	}

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

	return treeSectionVaild, nil
}

func (s *contractService) ValidRuleSectionNot(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
	treeSectionVaild := &viewmodels.TreeSectionContract{}
	err := ctx.ReadForm(treeSectionVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return treeSectionVaild, err
	}

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

	return treeSectionVaild, nil
}

func (s *contractService) ValidRuleGet(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
	treeSectionVaild := &viewmodels.TreeSectionContract{}
	err := ctx.ReadForm(treeSectionVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return treeSectionVaild, err
	}

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

// 验证序号相关
func (s *contractService) ValidRuleSerial(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
	treeSectionVaild := &viewmodels.TreeSectionContract{}
	err := ctx.ReadJSON(treeSectionVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return treeSectionVaild, err
	}

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

// 验证更新附件相关
func (s *contractService) ValidRuleUpdateFile(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
	treeSectionVaild := &viewmodels.TreeSectionContract{}
	err := ctx.ReadJSON(treeSectionVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return treeSectionVaild, err
	}

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

// 新增合同参数验证
func (s *contractService) ValidRuleContractAdd(ctx iris.Context) (*viewmodels.Contracts, error) {
	// 创建一个存放前端传过来参数
	contractsVaild := &viewmodels.Contracts{}
	// 存放raw的值，放入到contractsVaild
	err := ctx.ReadJSON(contractsVaild)
	if err != nil {
		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
		return contractsVaild, err
	}
	// 验证合同传参
	err = contractsVaild.ValidateAdd()
	if err != nil {
		log.Println("参数验证错误, error=", err)
		return contractsVaild, err
	}

	// xss
	contractsVaild.Code = html.EscapeString(contractsVaild.Code)
	contractsVaild.Name = html.EscapeString(contractsVaild.Name)
	contractsVaild.Price = html.EscapeString(contractsVaild.Price)

	return contractsVaild, nil
}

// 新增合同
func (s *contractService) Add(contractData *viewmodels.Contracts, treeId int) error {
	// 1. 项目节存在
	contracts := s.treeContractDao.Get(treeId)
	if contracts.Id == 0 {
		return errors.New("未找到项目节")
	}

	// 2.项目节是没有合同
	if contracts.ContractId != 0 {
		return errors.New("该项目节上已经存在合同")
	}

	// 3.新增合同 --合计标段上的金额
	contractsCm := &models.CmContracts{}
	contractsCm.Code = contractData.Code
	contractsCm.Name = contractData.Name
	contractsCm.ContractsType = 1
	contractsCm.Price = contractData.Price
	contractsCm.Returned = "0"
	contractsCm.Paid = "0"
	contractsCm.TreeId = treeId
	contractsCm.Status = 0
	contractsCm.CreateTime = time.Now()
	contractsCm.UpdateTime = time.Now()

	err := s.contractDao.Add(contractsCm)
	if err != nil {
		return err
	}

	return nil
}

// 保存上传文件
func (s *contractService) SaveUpload(Location string, Filename string, ext string) (string, error) {
	// 文件保存
	uploadCm := &models.CmUpload{}

	uploadCm.Name = Filename
	uploadCm.Path = Location
	uploadCm.Ext = ext

	_, err := s.uploadDao.Add(uploadCm)
	if err != nil {
		return 0, err
	}

	id, _ := comm.AesEncrypt(strconv.Itoa(uploadCm.Id), conf.SignSecret)

	return id, nil
}
