package user

import (
	"fmt"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/application/auth"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/application/factory"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/application/partnerInfo/query"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/application/partnerInfo/service"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/constant"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/domain"
	domain_service_i "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/domain/service"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/domain_service"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/pg/transaction"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/log"
	"gitlab.fjmaimaimai.com/mmm-go/partner/pkg/protocol"
	protocolx "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/protocol/auth"
	userx "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/protocol/user"
	"strconv"
	"strings"
)

//用户信息
func UserInfo(header *protocol.RequestHeader, request *protocol.UserInfoRequest) (rsp *protocol.UserInfoResponse, err error) {
	var (
		partnerInfo           *domain.PartnerInfo
		transactionContext, _ = factory.CreateTransactionContext(nil)
		CompanyRepository, _  = factory.CreateCompanyRepository(transactionContext)
		PartnerInfoService, _ = factory.CreatePartnerInfoRepositoryIn(transactionContext)
		UsersRepository, _    = factory.CreateUsersRepository(transactionContext)
		ImInfoRepository, _   = factory.CreateImInfoRepository(transactionContext)
		company               *domain.Company
		user                  *domain.Users
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	rsp = &protocol.UserInfoResponse{}

	funcPartnerInfo := func() {
		if partnerInfo, err = PartnerInfoService.FindOne(map[string]interface{}{"id": header.UserId}); err != nil {
			err = protocol.NewErrWithMessage(502, err) //账号不存在
			return
		}
		if company, err = CompanyRepository.FindOne(map[string]interface{}{"id": header.CompanyId}); err != nil {
			return
		}
		rsp.User = protocol.User{
			Id:          partnerInfo.Id,
			PartnerName: partnerInfo.PartnerName,
			Phone:       partnerInfo.Account,
			CooperateCompany: protocol.Company{
				Id:    company.Id,
				Name:  company.Name,
				Phone: company.Phone,
			},
			JoinWay:       partnerInfo.PartnerCategoryInfo(),
			District:      map[string]interface{}{"id": partnerInfo.RegionInfo.RegionId, "name": partnerInfo.RegionInfo.RegionName},
			SerialNo:      partnerInfo.Id,
			CooperateTime: partnerInfo.CooperateTime.Unix() * 1000,
		}
		if len(partnerInfo.Salesman) > 0 {
			rsp.User.Salesman = map[string]interface{}{"uname": partnerInfo.Salesman[0].Name, "phone": partnerInfo.Salesman[0].Telephone}
		} else {
			rsp.User.Salesman = map[string]interface{}{}
		}
	}
	funcManagerInfo := func() {
		if user, err = UsersRepository.FindOne(map[string]interface{}{"id": header.UserId}); err != nil {
			err = protocol.NewErrWithMessage(502, err) //账号不存在
			return
		}
		if company, err = CompanyRepository.FindOne(map[string]interface{}{"id": header.CompanyId}); err != nil {
			return
		}
		rsp.User = protocol.User{
			Id:          user.Id,
			PartnerName: user.Name,
			Phone:       user.Phone,
			CooperateCompany: protocol.Company{
				Id:    company.Id,
				Name:  company.Name,
				Phone: company.Phone,
			},
		}
	}
	switch header.AdminType {
	case int(protocolx.AdminTypePartner):
		funcPartnerInfo()
		break
	case int(protocolx.AdminTypeManager):
		funcManagerInfo()
		break
	default:
		funcPartnerInfo()
		break
	}

	if imInfo, e := ImInfoRepository.FindOne(map[string]interface{}{"user_id": header.SimNum}); e == nil && imInfo != nil {
		rsp.User.ImToken = imInfo.ImToken
		rsp.User.AccountID, _ = strconv.ParseInt(imInfo.ImId, 10, 64)
		rsp.User.CsAccountID = fmt.Sprintf("%v", imInfo.CustomerImId)
	}
	err = transactionContext.CommitTransaction()
	return
}

//验证smscode
func CheckSmsCode(header *protocol.RequestHeader, request *protocol.CheckSmsCodeRequest) (rsp *protocol.CheckSmsCodeResponse, err error) {
	var (
		PartnerInfoService = service.NewPartnerInfoService(nil)
		partnerInfo        *domain.PartnerInfo
	)
	if partnerInfo, err = PartnerInfoService.GetPartnerInfo(&query.GetPartnerInfoQuery{Id: int(header.UserId)}); err != nil {
		err = protocol.NewErrWithMessage(502, err) //账号不存在
		return
	}
	if _, err = auth.CheckSmsCode(strings.TrimSpace(partnerInfo.Account), request.Captcha); err != nil {
		log.Error(err, partnerInfo.Account, request.Captcha)
		return
	}
	return
}

//修改手机号
func ChangePhone(header *protocol.RequestHeader, request *protocol.ChangePhoneRequest) (rsp *protocol.ChangePhoneResponse, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		UserAuthService       = CreateUserAuthService(header.AdminType, transactionContext)
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if err = UserAuthService.ChangeUserPhone(header.UserId, request.Phone, request.OldPhone); err != nil {
		err = protocol.NewCustomMessage(1, err.Error())
		return
	}
	err = transactionContext.CommitTransaction()
	return
}

//重置密码
func ResetPassword(header *protocol.RequestHeader, request *protocol.ResetPasswordRequest) (rsp *protocol.ResetPasswordResponse, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		UserAuthService       = CreateUserAuthService(header.AdminType, transactionContext)
	)
	rsp = &protocol.ResetPasswordResponse{}
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	if err = UserAuthService.ResetUserPassword(header.UserId, request.Phone, request.NewPwd); err != nil {
		err = protocol.NewCustomMessage(1, err.Error())
		return
	}
	err = transactionContext.CommitTransaction()
	return
}

//修改密码
func ChangePassword(header *protocol.RequestHeader, request *protocol.ChangePasswordRequest) (rsp *protocol.ChangePasswordResponse, err error) {
	var (
		transactionContext, _ = factory.CreateTransactionContext(nil)
		UserAuthService       = CreateUserAuthService(header.AdminType, transactionContext)
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	rsp = &protocol.ChangePasswordResponse{}
	if err = UserAuthService.ChangeUserPassword(header.UserId, request.NewPwd, request.OldPwd, request.Phone); err != nil {
		err = protocol.NewCustomMessage(1, err.Error())
		return
	}
	err = transactionContext.CommitTransaction()
	return
}

func UserInfoV2(header *protocol.RequestHeader, request *protocol.UserInfoRequest) (rsp interface{}, err error) {
	var (
		partnerInfo           *domain.PartnerInfo
		transactionContext, _ = factory.CreateTransactionContext(nil)
		CompanyRepository, _  = factory.CreateCompanyRepository(transactionContext)
		PartnerInfoService, _ = factory.CreatePartnerInfoRepositoryIn(transactionContext)
		UsersRepository, _    = factory.CreateUsersRepository(transactionContext)
		company               *domain.Company
		user                  *domain.Users
	)
	if err = transactionContext.StartTransaction(); err != nil {
		return nil, err
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	rsp = &protocol.UserInfoResponse{}
	rspMap := make(map[string]interface{})
	funcPartnerInfo := func() {
		if partnerInfo, err = PartnerInfoService.FindOne(map[string]interface{}{"id": header.UserId}); err != nil {
			err = protocol.NewErrWithMessage(502, err) //账号不存在
			return
		}
		if company, err = CompanyRepository.FindOne(map[string]interface{}{"id": header.CompanyId}); err != nil {
			return
		}
		var miniProgram map[string]interface{}
		if len(company.Applets) > 0 {
			if company.Applets[0].Valid() {
				miniProgram = make(map[string]interface{})
				miniProgram["webpageUrl"] = "www.baidu.com"
				miniProgram["userName"] = company.Applets[0].Id
				miniProgram["path"] = fmt.Sprintf("%v?inviter_id=%v&company_id=%v", company.Applets[0].URL, partnerInfo.Id, partnerInfo.CompanyId)
				miniProgram["hdImageUrl"] = constant.SHARE_SHOP_PREVIEW_IMADGE
				if len(company.Applets[0].ImageUrl) > 0 {
					miniProgram["hdImageUrl"] = company.Applets[0].ImageUrl
				}
				miniProgram["title"] = company.Applets[0].Name
			}
		}
		u := userx.User{
			Id:          partnerInfo.Id,
			PartnerName: partnerInfo.PartnerName,
			Phone:       partnerInfo.Account,
			CooperateCompany: userx.Company{
				Id:            company.Id,
				Name:          company.Name,
				Phone:         company.Phone,
				SerialNo:      partnerInfo.Id,
				CooperateTime: partnerInfo.CooperateTime.Unix() * 1000,
				MiniProgram:   miniProgram,
				District:      map[string]interface{}{"id": partnerInfo.RegionInfo.RegionId, "name": partnerInfo.RegionInfo.RegionName},
			},
		}
		if len(partnerInfo.Salesman) > 0 {
			u.CooperateCompany.Salesman = map[string]interface{}{"uname": partnerInfo.Salesman[0].Name, "phone": partnerInfo.Salesman[0].Telephone}
		} else {
			u.CooperateCompany.Salesman = map[string]interface{}{}
		}
		rspMap["user"] = u
		rsp = rspMap
	}
	funcManagerInfo := func() {
		if user, err = UsersRepository.FindOne(map[string]interface{}{"id": header.UserId}); err != nil {
			err = protocol.NewErrWithMessage(502, err) //账号不存在
			return
		}
		if company, err = CompanyRepository.FindOne(map[string]interface{}{"id": header.CompanyId}); err != nil {
			return
		}
		rspMap["user"] = userx.User{
			Id:          user.Id,
			PartnerName: user.Name,
			Phone:       user.Phone,
			CooperateCompany: userx.Company{
				Id:          company.Id,
				Name:        company.Name,
				Phone:       company.Phone,
				MiniProgram: nil,
			},
		}
		rsp = rspMap
	}
	switch header.AdminType {
	case int(protocolx.AdminTypePartner):
		funcPartnerInfo()
		break
	case int(protocolx.AdminTypeManager):
		funcManagerInfo()
		break
	default:
		funcPartnerInfo()
		break
	}
	err = transactionContext.CommitTransaction()
	return
}

func CreateUserAuthService(adminType int, transactionContext *transaction.TransactionContext) domain_service_i.UserAuthService {
	return domain_service.NewPgAuthService(transactionContext)
	//if adminType == int(protocolx.AdminTypeManager) {
	//	return domain_service.NewPgManagerAuthService(transactionContext)
	//}
	//return domain_service.NewPgPartnerAuthService(transactionContext)
}