package services

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"strconv"

	"go.mod/web/utils"

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

type RuleService interface {
	Get(pid int, id int) viewmodels.ViewRule
	Post(pid int, id int, key string, value string) error
	AutoCode(bid int, pid int, codeType string) (string, string, error)
	ValidRule(ctx iris.Context) (viewmodels.ValidField, error)
}

// //返回service操作类
type ruleService struct {
	daoRule         *dao.RuleDao
	daoSafe         *dao.SafeDao
	daoQuality      *dao.QualityDao
	daoContract     *dao.ContractDao
	daoContractPaid *dao.ContractPaidDao
	validAutoPath   string
}

//创建项目用户service
func NewRuleService() RuleService {
	return &ruleService{
		validAutoPath: "/api/rule/auto",
		daoRule:       dao.NewRuleDao(datasource.InstanceDbMaster()),
		daoSafe:       dao.NewSafeDao(datasource.InstanceDbMaster()),
		daoQuality:    dao.NewQualityDao(datasource.InstanceDbMaster()),
		daoContract:   dao.NewContractDao(datasource.InstanceDbMaster()),
	}
}

func (s *ruleService) Get(pid int, id int) viewmodels.ViewRule {
	data := s.daoRule.FindByPidWithBid(pid, id)
	viewData := viewmodels.ViewRule{SafeRule: data.SafeRule, QualityRule: data.QualityRule, ContractPaidRule: data.ContractPaidRule, ContractReturnRule: data.ContractReturnRule}
	return viewData
}

func (s *ruleService) Post(pid int, id int, key string, value string) error {
	err := s.daoRule.UpdateOrCreate(pid, id, key, value)
	return err
}

// 生成code
func (s *ruleService) AutoCode(bid int, pid int, codeType string) (string, string, error) {
	// 获取该标段的规则
	rule := s.daoRule.FindByPidWithBid(pid, bid)
	if codeType == "safeRule" {
		if rule.SafeRule == "" {
			return "", "", errors.New("该标段未设置编号规则")
		}
		var code viewmodels.RuleCode
		err := json.Unmarshal([]byte(rule.SafeRule), &code)
		total, err := s.daoSafe.CountRuleCode(bid)
		k, _ := strconv.Atoi(code.Code)
		newCode := utils.CreateRuleCode(int64(k), total, len(code.Code))
		return rule.SafeRule, newCode, err

	} else if codeType == "contractReturnRule" {
		if rule.ContractReturnRule == "" {
			return "", "", errors.New("该标段未设置编号规则")
		}
		var code viewmodels.RuleCode
		err := json.Unmarshal([]byte(rule.ContractReturnRule), &code)
		total, err := s.daoContract.CountRuleCode(bid, 1)
		fmt.Printf("-----------------------", total)
		k, _ := strconv.Atoi(code.Code)
		newCode := utils.CreateRuleCode(int64(k), total, len(code.Code))
		return rule.ContractReturnRule, newCode, err

	} else if codeType == "contractPaidRule" {
		if rule.ContractPaidRule == "" {
			return "", "", errors.New("该标段未设置编号规则")
		}
		var code viewmodels.RuleCode
		err := json.Unmarshal([]byte(rule.ContractPaidRule), &code)
		total, err := s.daoContract.CountRuleCode(bid, 2)
		k, _ := strconv.Atoi(code.Code)
		newCode := utils.CreateRuleCode(int64(k), total, len(code.Code))
		return rule.ContractPaidRule, newCode, err

	} else if codeType == "contractPaidRule" {
		if rule.ContractPaidRule == "" {
			return "", "", errors.New("该标段未设置编号规则")
		}
		var code viewmodels.RuleCode
		err := json.Unmarshal([]byte(rule.ContractPaidRule), &code)
		total, err := s.daoContractPaid.CountPaidRuleCode(bid)
		k, _ := strconv.Atoi(code.Code)
		newCode := utils.CreateRuleCode(int64(k), total, len(code.Code))
		return rule.ContractPaidRule, newCode, err

	} else if codeType == "contractPaidRule" {
		if rule.ContractPaidRule == "" {
			return "", "", errors.New("该标段未设置编号规则")
		}
		var code viewmodels.RuleCode
		err := json.Unmarshal([]byte(rule.ContractPaidRule), &code)
		total, err := s.daoContractPaid.CountPaidRuleCode(bid)
		k, _ := strconv.Atoi(code.Code)
		newCode := utils.CreateRuleCode(int64(k), total, len(code.Code))
		return rule.ContractPaidRule, newCode, err
	} else {
		if rule.QualityRule == "" {
			return "", "", errors.New("该标段未设置编号规则")
		}
		var code viewmodels.RuleCode
		err := json.Unmarshal([]byte(rule.QualityRule), &code)
		total, err := s.daoQuality.CountRuleCode(bid)
		k, _ := strconv.Atoi(code.Code)
		newCode := utils.CreateRuleCode(int64(k), total, len(code.Code))
		return rule.QualityRule, newCode, err
	}
}

func (s *ruleService) ValidRule(ctx iris.Context) (viewmodels.ValidField, error) {
	safeVaild := viewmodels.ValidField{}
	if ctx.Method() == "GET" {
		err := ctx.ReadForm(&safeVaild)
		if err != nil {
			log.Println("safe-ValidRule-ReadForm转换异常, error=", err)
			return safeVaild, err
		}
		err = safeVaild.Validate()
		return safeVaild, err
	}

	if ctx.Method() == "POST" {
		err := ctx.ReadJSON(&safeVaild)
		if err != nil {
			log.Println("safe-ValidRule-ReadJson转换异常, error=", err)
			return safeVaild, err
		}
		if ctx.Path() == s.validAutoPath {
			err = safeVaild.ValidateAuto()
		} else {
			err = safeVaild.Validate()
		}

	}
	return safeVaild, nil

}
