package services

import (
	"fmt"
	"log"
	"strconv"
	"time"

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

type QualityService interface {
	Get(id int, pid int, pageNo int, pageSize int) ([]viewmodels.QualityList, int64)
	Post(data models.CmQuality) error
	Del(id int) error
	GetDetail(id int, pid int) viewmodels.QualityDetail
	GetSurvey(projectId int, bidsectionId int) map[string]interface{}
	GetPending(projectId int, projectAccountId int) []viewmodels.Quality
	ValidRule(ctx iris.Context) (viewmodels.Quality, error)
}

// //返回service操作类
type qualityService struct {
	daoQuality        *dao.QualityDao
	daoQualityAudit   *dao.QualityAuditDao
	daoProjectAccount *dao.ProjectAccountDao
	daoAnnex          *dao.AnnexDao
	daoRule           *dao.RuleDao
	daoApprover       *dao.ApproverDao
	validDetail       string
}

//创建项目用户service
func NewQualityService() QualityService {
	return &qualityService{
		validDetail:       "/api/quality/detail",
		daoQuality:        dao.NewQualityDao(datasource.InstanceDbMaster()),
		daoAnnex:          dao.NewAnnexDao(datasource.InstanceDbMaster()),
		daoQualityAudit:   dao.NewQualityAuditDao(datasource.InstanceDbMaster()),
		daoProjectAccount: dao.NewProjectAccountDao(datasource.InstanceDbMaster()),
		daoApprover:       dao.NewApproverDao(datasource.InstanceDbMaster()),
	}
}
func (s *qualityService) Get(id int, pid int, pageNo int, pageSize int) ([]viewmodels.QualityList, int64) {
	datalist, total := s.daoQuality.GetListByBid(id, pageNo, pageSize)
	qualityList := make([]viewmodels.QualityList, 0)
	for _, item := range datalist {
		qualityVM := viewmodels.QualityList{}
		qualityVM.Code = item.Code
		account := s.daoProjectAccount.Get(item.Uid, pid)
		qualityVM.AuditName = account.Name
		qualityVM.CreateTime = item.CreateTime.Format(conf.SysTimeform)
		qualityVM.Demand = item.Demand
		id, _ := comm.AesEncrypt(strconv.Itoa(item.Id), conf.SignSecret)
		qualityVM.Id = id
		qualityVM.Inspection = item.Inspection
		qualityVM.InspectionDetail = item.InspectionDetail
		qualityVM.Position = item.Position
		qualityVM.Status = item.Status
		counts, _ := s.daoAnnex.GetCount(3, item.Id)
		qualityVM.FileCounts = counts
		qualityList = append(qualityList, qualityVM)
	}
	return qualityList, total
}

// post请求，插入单条数据
func (s *qualityService) Post(data models.CmQuality) error {
	// has := s.daoQuality.FindByCode(data.Code)
	// if has {
	// 	return errors.New("该编号已存在!")
	// }
	// Inserted, err := s.daoQuality.InsertRecord(data)
	// if Inserted == true {
	// 	return nil
	// }
	err := s.daoQuality.CreateQuality(data)
	return err
}

// delete请求，删除数据
func (s *qualityService) Del(id int) error {
	err := s.daoQuality.DeleteRecord(id)
	return err
}

// 详情页数据拼装
func (s *qualityService) GetDetail(id int, pid int) viewmodels.QualityDetail {

	qualityData := s.daoQuality.FindById(id)
	qualityId, _ := comm.AesEncrypt(strconv.Itoa(qualityData.Id), conf.SignSecret)
	bid, _ := comm.AesEncrypt(strconv.Itoa(qualityData.BidsectionId), conf.SignSecret)
	uid, _ := comm.AesEncrypt(strconv.Itoa(qualityData.Uid), conf.SignSecret)
	data := viewmodels.QualityDetail{}
	data.Id = qualityId
	data.BidsectionId = bid
	data.Uid = uid
	data.Code = qualityData.Code
	data.Inspection = qualityData.Inspection
	data.InspectionDetail = qualityData.InspectionDetail
	data.Demand = qualityData.Demand
	account := s.daoProjectAccount.Get(qualityData.Uid, pid)
	data.AuditName = account.Name
	data.CreateTime = qualityData.CreateTime
	data.Times = qualityData.Times
	data.Status = qualityData.Status
	fileList, total := s.daoAnnex.GetList(2, qualityData.Id, 1, conf.PageSize)
	// 加密id
	fileArr := make([]viewmodels.AnnexListView, 0)
	for _, item := range fileList {
		fileListVM := viewmodels.AnnexListView{}
		fileId, _ := comm.AesEncrypt(item.Id, conf.SignSecret)
		fileListVM.Id = fileId
		uid, _ := comm.AesEncrypt(item.AccountId, conf.SignSecret)
		fileListVM.AccountId = uid
		fileListVM.AccountName = item.AccountName
		fileListVM.CreateTime = item.CreateTime
		fileListVM.FileName = item.FileName
		fileListVM.FilePath = item.FilePath
		fileArr = append(fileArr, fileListVM)
	}
	fileVM := viewmodels.FileStruct{}
	fileVM.FileList = fileArr
	fileVM.Total = total
	data.File = fileVM
	auditors := s.daoApprover.GetAuditorsWithOwner(qualityData.BidsectionId, int(1), qualityData.Id, account.Id)
	encryptAuditors := make([]viewmodels.Auditors, 0)
	for _, item := range auditors {
		auditorVM := viewmodels.Auditors{}
		if item.Id != "" {
			id, _ := comm.AesEncrypt(item.Id, conf.SignSecret)
			auditorVM.Id = id
		}
		auditId, _ := comm.AesEncrypt(item.AuditId, conf.SignSecret)
		auditorVM.AuditId = auditId
		auditorVM.Name = item.Name
		auditorVM.Position = item.Position
		auditorVM.Mobile = item.Mobile
		auditorVM.AuditOrder = item.AuditOrder
		auditorVM.AccountGroup = item.AccountGroup
		auditorVM.Progress = item.Progress
		auditorVM.Company = item.Company
		auditorVM.Status = item.Status
		encryptAuditors = append(encryptAuditors, auditorVM)
	}
	auditHistory := s.daoQualityAudit.GetAuditHistory(qualityData.Id, qualityData.Times)
	data.AuditHistory = auditHistory
	// 整改单
	rectifiedInfo, _ := s.daoQualityAudit.GetLastedOrder(qualityData.Id)
	data.RectifiedInfo = rectifiedInfo

	// 最新审批人信息
	latestAuditor := s.daoApprover.GetLastedAuditor(qualityData.BidsectionId, 1, qualityData.Id)
	data.LatestdAuditor = latestAuditor
	data.Auditors = encryptAuditors

	return data
}

// 质量概况
func (s *qualityService) GetSurvey(projectId int, bidsectionId int) map[string]interface{} {
	// 1.获得安全巡检
	year := time.Now().Year()
	qualityList := s.daoQuality.GetTypeYear(bidsectionId, year)
	// 2.初始化
	rectifylist := make([]viewmodels.QualitySurveyList, 0)
	rectifyTotal := 0
	approvalTotal := 0
	rectifyedTotal := 0

	columnarData := make([]map[string]interface{}, 0)
	lineData := columnarData
	for i := 1; i <= 12; i++ {
		item := map[string]interface{}{
			"name":  "rectifyed",
			"month": fmt.Sprintf("%d-%02d", year, i),
			"count": 0,
		}
		columnarData = append(columnarData, item)
		item = map[string]interface{}{
			"name":  "submit",
			"month": fmt.Sprintf("%d-%02d", year, i),
			"count": 0,
		}
		columnarData = append(columnarData, item)
		item = map[string]interface{}{
			"month":      fmt.Sprintf("%d-%02d", year, i),
			"percentage": 0,
		}
		lineData = append(lineData, item)

	}

	// 3.当年数据初始化
	submitData := map[string]int{
		fmt.Sprintf("%d-01", year): 0,
		fmt.Sprintf("%d-02", year): 0,
		fmt.Sprintf("%d-03", year): 0,
		fmt.Sprintf("%d-04", year): 0,
		fmt.Sprintf("%d-05", year): 0,
		fmt.Sprintf("%d-06", year): 0,
		fmt.Sprintf("%d-07", year): 0,
		fmt.Sprintf("%d-08", year): 0,
		fmt.Sprintf("%d-09", year): 0,
		fmt.Sprintf("%d-10", year): 0,
		fmt.Sprintf("%d-11", year): 0,
		fmt.Sprintf("%d-12", year): 0,
	}
	rectifyedData := map[string]int{
		fmt.Sprintf("%d-01", year): 0,
		fmt.Sprintf("%d-02", year): 0,
		fmt.Sprintf("%d-03", year): 0,
		fmt.Sprintf("%d-04", year): 0,
		fmt.Sprintf("%d-05", year): 0,
		fmt.Sprintf("%d-06", year): 0,
		fmt.Sprintf("%d-07", year): 0,
		fmt.Sprintf("%d-08", year): 0,
		fmt.Sprintf("%d-09", year): 0,
		fmt.Sprintf("%d-10", year): 0,
		fmt.Sprintf("%d-11", year): 0,
		fmt.Sprintf("%d-12", year): 0,
	}
	for _, item := range qualityList {
		if item.Status == 2 {
			id, _ := comm.AesEncrypt(item.Id, conf.SignSecret)
			item.Id = id
			rectifylist = append(rectifylist, item)
			rectifyTotal++
		}

		approvalTotal++
		if item.Status == 4 {
			rectifyedTotal++
		}

		index := item.CreateTime.Format(conf.SysTimeformMonth)
		submitData[index] = submitData[index] + 1

		if item.Status == 4 {
			rectifyedData[index] = rectifyedData[index] + 1
		}

	}

	for index, columnar := range columnarData {

		if columnar["name"] == "rectifyed" {
			columnarData[index]["count"] = rectifyedData[columnar["month"].(string)]
		}
		if columnar["name"] == "submit" {
			columnarData[index]["count"] = submitData[columnar["month"].(string)]
		}
	}

	for index, line := range lineData {
		rectifyedCount := 0
		submitCount := 0
		for _, columnar := range columnarData {
			if line["month"] == columnar["month"] {
				if columnar["name"] == "rectifyed" {
					rectifyedCount = columnar["count"].(int)
				}
				if columnar["name"] == "submit" {
					submitCount = columnar["count"].(int)
				}
			}
		}
		lineData[index]["percentage"] = 0.00
		if rectifyedCount != 0 && submitCount != 0 {
			decimal.DivisionPrecision = 2
			percentage, _ := decimal.NewFromFloat(float64(rectifyedCount)).Div(decimal.NewFromFloat(float64(submitCount))).Float64()
			lineData[index]["percentage"] = percentage * 100
		}
	}

	// 整改占总数比例 - 完成整改/提交巡检
	surveryData := map[string]interface{}{
		"rectifylist":    rectifylist,
		"rectifyTotal":   rectifyTotal,
		"approvalTotal":  approvalTotal,
		"rectifyedTotal": rectifyedTotal,
		"columnarData":   columnarData,
		"lineData":       lineData,
	}

	return surveryData
}

// 获得账号下需要审批的巡检
func (s *qualityService) GetPending(projectId int, projectAccountId int) []viewmodels.Quality {

	data := s.daoQuality.GetStatusByProjectAndAccount(projectId, projectAccountId, 1)

	safeList := make([]viewmodels.Quality, 0)
	for _, item := range data {
		safeVM := viewmodels.Quality{}

		Id, _ := comm.AesEncrypt(strconv.Itoa(item.Id), conf.SignSecret)
		BidsectionId, _ := comm.AesEncrypt(strconv.Itoa(item.BidsectionId), conf.SignSecret)
		// AuditId, _ := comm.AesEncrypt(item.AuditId, conf.SignSecret)
		Uid, _ := comm.AesEncrypt(strconv.Itoa(item.Uid), conf.SignSecret)
		// ProjectId, _ := comm.AesEncrypt(strconv.Itoa(item.ProjectId), conf.SignSecret)

		safeVM.Id = Id
		safeVM.BidsectionId = BidsectionId
		safeVM.Uid = Uid
		safeVM.Code = item.Code
		safeVM.CreateTime = item.CreateTime.Format(conf.SysTimeform)
		safeVM.EndTime = item.EndTime.Format(conf.SysTimeform)
		safeVM.Position = item.Position
		safeVM.Inspection = item.Inspection
		safeVM.InspectionDetail = item.InspectionDetail
		safeVM.Demand = item.Demand
		safeVM.Status = item.Status
		safeList = append(safeList, safeVM)
	}

	return safeList
}

// 规则校验
func (s *qualityService) ValidRule(ctx iris.Context) (viewmodels.Quality, error) {
	qualityVaild := viewmodels.Quality{}
	// fmt.Println("---------------------------safeVaild", safeVaild)
	if ctx.Method() == "GET" {
		err := ctx.ReadForm(&qualityVaild)
		if err != nil {
			log.Println("safe-ValidRule-ReadForm转换异常, error=", err)
			return qualityVaild, err
		}
		if ctx.Path() == s.validDetail {
			// 一样要传id，所以用delete的方法判断
			err = qualityVaild.ValidateQualityDelete()
		} else {
			err = qualityVaild.ValidateQualityList()
		}
		return qualityVaild, err
	}

	if ctx.Method() == "POST" {
		err := ctx.ReadJSON(&qualityVaild)
		if err != nil {
			log.Println("safe-ValidRule-ReadJson转换异常, error=", err)
			return qualityVaild, err
		}
		err = qualityVaild.ValidateQualityCreate()
		return qualityVaild, err
		// if ctx.Path() == s.validCreate {
		// }
		// if ctx.Path() == s.validFile {
		// 	err = safeVaild.ValidateFile()
		// 	return safeVaild, err
		// }
	}

	if ctx.Method() == "PUT" {
		err := ctx.ReadForm(&qualityVaild)
		if err != nil {
			log.Println("safe-ValidRule-ReadForm转换异常, error=", err)
			return qualityVaild, err
		}
		err = qualityVaild.ValidateQualityDelete()
		return qualityVaild, err
	}
	return qualityVaild, nil

}
