package service

import (
	"encoding/json"
	"enterprise/common/config"
	"enterprise/common/dao"
	"enterprise/common/model"
	"enterprise/server/api"
	"enterprise/server/session"
	"git.u8t.cn/open/gosdk/qyweixin"
	"github.com/google/uuid"
	log "github.com/sirupsen/logrus"
	"github.com/smbrave/goutil"
	"github.com/spf13/cast"
	"time"
)

type StaffUser struct {
}

func NewStaffUser() *StaffUser {
	return &StaffUser{}
}

func (s *StaffUser) Login(sess *session.AdminSession, req *api.StaffLoginReq) interface{} {
	host := sess.GetHeader().Host
	log.Infof("login host[%s] req[%s]", host, goutil.EncodeJSON(req))

	corp, err := dao.NewCorpDao().GetByHost(host)
	session.CheckDBError(err)
	session.CheckNilError(corp, "企业不存在的域名")

	user, err := dao.NewStaffUserDao().GetByUsername(corp.Id, req.Username)
	session.CheckDBError(err)
	session.CheckNilError(user, "企业用户不存在")

	if user.Password == "" || user.Password != req.Password {
		panic("密码错误")
	}

	token := new(model.StaffToken)
	token.UserId = user.Id
	token.ExpireTime = time.Now().Unix() + 86400*30
	token.Token = uuid.New().String()
	_, err = dao.NewStaffTokenDao().Create(token)
	session.CheckDBError(err)

	data := token.ToLogin()
	data["username"] = user.Username
	data["realname"] = user.Realname
	return data
}

func (s *StaffUser) List(sess *session.AdminSession, req *api.StaffListReq) (int64, interface{}) {

	staffs, total, err := dao.NewStaffUserDao().Query(req.Page, req.Size, sess.GetCorpId(), cast.ToInt(req.Status), req.Username, req.Realname, req.Phone, req.Idno)
	session.CheckDBError(err)
	items := make([]*api.StaffUser, 0)

	corpStaffConfig := cast.ToSlice(config.GetCorpConfig(sess.GetCorpId(), "staff_config", nil))

	for _, st := range staffs {
		i := new(api.StaffUser)
		i.From(st)
		calculator, _ := dao.NewSalaryCalculatorDao().Get(cast.ToInt64(i.SalaryCalculator))
		if calculator != nil {
			i.SalaryCalculatorName = calculator.Name
		}

		// config
		staffConfig := make(map[string]interface{})
		corpConfig := make([]map[string]interface{}, 0)
		json.Unmarshal([]byte(goutil.EncodeJSON(corpStaffConfig)), &corpConfig)
		json.Unmarshal([]byte(st.Config), &staffConfig)
		config := make([]map[string]interface{}, 0)
		for _, kv := range corpConfig {
			obj := cast.ToStringMap(kv)
			obj["value"] = cast.ToString(staffConfig[cast.ToString(obj["key"])])
			config = append(config, obj)
		}
		i.Config = config
		items = append(items, i)
	}
	return total, items
}
func (s *StaffUser) Create(sess *session.AdminSession, req *api.StaffCreateReq) {

	staffUser, err := dao.NewStaffUserDao().GetByUsername(sess.GetAdmin().CorpId, req.Username)
	session.CheckDBError(err)
	if staffUser != nil {
		panic("用户已存在")
	}

	hrAssiant := s.getHrAssiant(sess.GetCorpId())

	staffInfo, err := hrAssiant.GetStaffInfo(req.Username)
	if err != nil {
		log.Warnf("getstaff info username[%s] error :%s", req.Username, err.Error())
	}

	staffUser = new(model.StaffUser)
	if staffInfo != nil {
		staffUser.Realname = staffInfo.RealName
		staffUser.Phone = staffInfo.Phone
		staffUser.Idno = staffInfo.Idno
		staffUser.EntryDate = staffInfo.EntryDate
		staffUser.OfficialDate = staffInfo.OfficialDate
		payee := staffUser.GetPayee()
		payee.BankName = staffInfo.BankName
		payee.BankCard = staffInfo.BankCard
		staffUser.Payee = goutil.EncodeJSON(payee)
	}

	staffUser.CorpId = sess.GetAdmin().CorpId
	staffUser.Username = req.Username
	staffUser.Status = model.StaffUserStatusOnline
	_, err = dao.NewStaffUserDao().Create(staffUser)
	session.CheckDBError(err)
}

func (s *StaffUser) Update(sess *session.AdminSession, req *api.StaffUpdateReq) {

	staffUser, err := dao.NewStaffUserDao().Get(cast.ToInt64(req.Id))
	session.CheckDBError(err)
	session.CheckNilError(staffUser, "用户不存在")

	hrAssiant := s.getHrAssiant(sess.GetCorpId())
	staffInfo, err := hrAssiant.GetStaffInfo(req.Username)
	if err != nil {
		log.Warnf("getstaff info username[%s] error :%s", req.Username, err.Error())
	}
	if staffInfo != nil {
		staffUser.Realname = goutil.If(staffUser.Realname == "", staffInfo.RealName, staffUser.Realname)
		staffUser.Phone = goutil.If(staffUser.Phone == "", staffInfo.Phone, staffUser.Phone)
		staffUser.Idno = goutil.If(staffUser.Idno == "", staffInfo.Idno, staffUser.Idno)
		staffUser.OfficialDate = goutil.If(staffUser.OfficialDate == "" || staffUser.OfficialDate == "NaN-NaN-NaN", staffInfo.OfficialDate, staffUser.OfficialDate)
		staffUser.EntryDate = goutil.If(staffUser.EntryDate == "" || staffUser.EntryDate == "NaN-NaN-NaN", staffInfo.EntryDate, staffUser.EntryDate)
		payee := staffUser.GetPayee()
		payee.BankName = goutil.If(payee.BankName == "", staffInfo.BankName, payee.BankName)
		payee.BankCard = goutil.If(payee.BankCard == "", staffInfo.BankCard, payee.BankCard)
		staffUser.Payee = goutil.EncodeJSON(payee)
	}

	staffUser.Username = goutil.If(req.Username != "", req.Username, staffUser.Username)
	staffUser.Realname = goutil.If(req.Realname != "", req.Realname, staffUser.Realname)
	staffUser.Phone = goutil.If(req.Phone != "", req.Phone, staffUser.Phone)
	staffUser.Idno = goutil.If(req.Idno != "", req.Idno, staffUser.Idno)
	staffUser.EntryDate = goutil.If(req.EntryDate != "" && req.EntryDate != "NaN-NaN-NaN", req.EntryDate, staffUser.EntryDate)
	staffUser.OfficialDate = goutil.If(req.OfficialDate != "" && req.OfficialDate != "NaN-NaN-NaN", req.OfficialDate, staffUser.OfficialDate)

	staffSalary := staffUser.GetSalary()
	staffSalary.Base = goutil.If(req.SalaryBase != "", req.SalaryBase, staffSalary.Base)
	staffSalary.Target = goutil.If(req.SalaryTarget != "", req.SalaryTarget, staffSalary.Target)
	staffSalary.Calculator = goutil.If(req.SalaryCalculator != "", req.SalaryCalculator, staffSalary.Calculator)
	staffUser.Salary = goutil.EncodeJSON(staffSalary)

	staffPayee := staffUser.GetPayee()
	staffPayee.BankName = goutil.If(req.PayeeBankName != "", req.PayeeBankName, staffPayee.BankName)
	staffPayee.BankCard = goutil.If(req.PayeeBankCard != "", req.PayeeBankCard, staffPayee.BankCard)
	staffPayee.AlipayUid = goutil.If(req.PayeeAlipayUid != "", req.PayeeAlipayUid, staffPayee.AlipayUid)
	staffUser.Payee = goutil.EncodeJSON(staffPayee)

	//状态处理
	if req.Status != "" {
		status := cast.ToInt(req.Status)
		staffUser.Status = goutil.If(req.Status != "", cast.ToInt(req.Status), staffUser.Status)
		if status == model.StaffUserStatusOffline {
			staffUser.LeaveDate = goutil.If(req.LeaveDate != "", req.LeaveDate, staffUser.LeaveDate)
		} else {
			staffUser.LeaveDate = ""
		}
	}

	if req.Config != "" {
		var oldCfg map[string]interface{}
		var newCfg map[string]interface{}
		json.Unmarshal([]byte(staffUser.Config), &oldCfg)
		json.Unmarshal([]byte(req.Config), &newCfg)
		if oldCfg == nil {
			oldCfg = make(map[string]interface{})
		}
		for k, v := range newCfg {
			oldCfg[k] = v
		}
		staffUser.Config = goutil.EncodeJSON(oldCfg)
	}

	err = dao.NewStaffUserDao().Update(staffUser)
	session.CheckDBError(err)
}

func (s *StaffUser) Pay(sess *session.AdminSession, req *api.StaffPayReq) {
	corp, err := dao.NewCorpDao().Get(sess.GetCorpId())
	session.CheckDBError(err)
	session.CheckNilError(corp, "企业不存在")

	var payReq api.PayReq
	payReq.Title = req.Title
	payReq.Amount = cast.ToInt64(req.Amount)

	user, err := dao.NewStaffUserDao().Get(cast.ToInt64(req.StaffId))
	session.CheckDBError(err)
	session.CheckNilError(user, "用户不存在")
	log.Errorf("pay user[%s] amount[%s]", user.Username, goutil.FormatMoney(cast.ToInt64(req.Amount)))
	return
	NewPay().Pay(corp, user, req.Title, req.PayType, cast.ToInt64(req.Amount))
}

func (s *StaffUser) getHrAssiant(corpId int64) *qyweixin.AppHr {
	corp, err := dao.NewCorpDao().Get(corpId)
	session.CheckDBError(err)
	session.CheckNilError(corp, "企业不存在")
	corpCfg := corp.GetConfig()
	hrAssiant := qyweixin.NewAppHr(&qyweixin.AppConfig{
		Corpid: corpCfg.CorpId,
		Secret: corpCfg.EnterpriseSecret,
		Agent:  corpCfg.EnterpriseAgent,
	})
	return hrAssiant
}