package worker

import (
	"enterprise/common/dao"
	"enterprise/common/model"
	"git.u8t.cn/open/gosdk/qyweixin"
	log "github.com/sirupsen/logrus"
	"github.com/spf13/cast"
	"time"
)

type Approval struct {
	corp       *model.Corp
	corpConfig *model.CorpConfig
}

func NewApproval(corpId int64) *Approval {
	corp, _ := dao.NewCorpDao().Get(corpId)
	return &Approval{
		corp:       corp,
		corpConfig: corp.GetConfig(),
	}
}
func (s *Approval) getTemplateId(tp string) string {
	if tp == model.ApprovalTypeCheckin {
		return s.corpConfig.TplIdCheckin
	} else if tp == model.ApprovalTypeRefund {
		return s.corpConfig.TplIdRefund
	} else if tp == model.ApprovalTypeVacation {
		return s.corpConfig.TplIdVacation
	} else if tp == model.ApprovalTypePayment {
		return s.corpConfig.TplIdPayment
	}
	return ""
}

func (s *Approval) Sync(month, tp string) {
	corp, err := dao.NewCorpDao().Get(s.corp.Id)
	if err != nil {
		log.Errorf("db error:%s", err.Error())
		return
	}
	corpConfig := corp.GetConfig()
	templateId := s.getTemplateId(tp)

	approve := qyweixin.NewAppApprove(&qyweixin.AppConfig{Corpid: corpConfig.CorpId, Secret: corpConfig.ApproveSecret, Agent: corpConfig.ApproveAgent})
	startTime, _ := time.ParseInLocation("200601", month, time.Local)
	endTime := startTime.AddDate(0, 1, 0)
	spNos, err := approve.GetList(startTime.Unix(), endTime.Unix()-1, templateId)
	if err != nil {
		log.Errorf("approve getlist error :%s", err.Error())
		return
	}

	for _, spNo := range spNos {
		detail, err := approve.GetDetail(spNo)
		if err != nil {
			log.Errorf("approve GetDetail error :%s", err.Error())
			continue
		}
		if detail.SpStatus != 2 {
			continue
		}
		if tp == model.ApprovalTypeCheckin {
			s.saveCheckin(detail)
		} else if tp == model.ApprovalTypeRefund {
			s.saveRefund(detail)
		} else if tp == model.ApprovalTypeVacation {
			s.saveVacation(detail)
		} else if tp == model.ApprovalTypePayment {
			s.savePayment(detail)
		}
	}

	return
}

func (s *Approval) savePayment(detail *qyweixin.ApproveDetail) {
	dbDao := dao.NewApprovalPaymentDao()
	newData := new(model.ApprovalPayment)
	newData.From(detail)
	old, err := dbDao.GetBySpNo(s.corp.Id, detail.SpNo)
	if err != nil {
		log.Errorf("db error :%s", err.Error())
		return
	}
	if old == nil {
		_, err = dbDao.Create(newData)
	} else {
		newData.Id = old.Id
		newData.CreateTime = old.CreateTime
		err = dbDao.Update(newData)
	}
	if err != nil {
		log.Errorf("db error :%s", err.Error())
	}
}

func (s *Approval) saveCheckin(detail *qyweixin.ApproveDetail) {
	dbDao := dao.NewApprovalCheckinDao()
	newData := new(model.ApprovalCheckin)
	newData.From(detail)
	old, err := dbDao.GetBySpNo(s.corp.Id, detail.SpNo)
	if err != nil {
		log.Errorf("db error :%s", err.Error())
		return
	}
	if old == nil {
		_, err = dbDao.Create(newData)
	} else {
		newData.Id = old.Id
		newData.CreateTime = old.CreateTime
		err = dbDao.Update(newData)
	}
	if err != nil {
		log.Errorf("db error :%s", err.Error())
	}
}

func (s *Approval) saveRefund(detail *qyweixin.ApproveDetail) {
	dbDao := dao.NewApprovalRefundDao()
	newData := new(model.ApprovalRefund)
	newData.From(detail)
	newData.CorpId = s.corp.Id
	old, err := dbDao.GetBySpNo(s.corp.Id, detail.SpNo)
	if err != nil {
		log.Errorf("db error :%s", err.Error())
		return
	}
	if old != nil {
		newData.Id = old.Id
		err = dbDao.Update(newData)
		if err != nil {
			log.Errorf("db error :%s", err.Error())
		}
		return
	}
	_, err = dbDao.Create(newData)
	if err != nil {
		log.Errorf("db error :%s", err.Error())
	}
}

func (s *Approval) saveVacation(detail *qyweixin.ApproveDetail) {
	dbDao := dao.NewApprovalVacationDao()
	newData := new(model.ApprovalVacation)
	newData.CorpId = s.corp.Id
	newData.From(detail)
	newData.VacationDuration = newData.VacationDuration / (cast.ToFloat64(s.corpConfig.WorkerHouer) * float64(3600))

	old, err := dbDao.GetBySpNo(s.corp.Id, detail.SpNo)
	if err != nil {
		log.Errorf("db error :%s", err.Error())
		return
	}
	if old != nil {
		newData.Id = old.Id
		err = dbDao.Update(newData)
		if err != nil {
			log.Errorf("db error :%s", err.Error())
		}
		return
	}
	_, err = dbDao.Create(newData)
	if err != nil {
		log.Errorf("db error :%s", err.Error())
	}
}