package controllers

import (
	"intent-system/pkg/itypes"
	"intent-system/pkg/middleware"
	"intent-system/pkg/privilege"
	"intent-system/pkg/proto"
	"intent-system/pkg/sessions"

	"github.com/civet148/log"
	"github.com/gin-gonic/gin"
)

// 客户列表(需权限检查)
func (m *Controller) CustomerList(c *gin.Context) {
	var req proto.CustomerListReq
	if err := m.bindJSON(c, &req); err != nil {
		log.Errorf("%s", err)
		return
	}
	ctx, ok := m.ContextPlatformPrivilege(c, privilege.CustomerAccess)
	if !ok {
		log.Errorf("user authentication context is nil or privilege check failed")
		return
	}
	resp, total, code := m.CustomerCore.CustomerList(ctx, &req)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	m.OK(c, resp, len(resp.List), total)
}

func (m *Controller) CustomerRegister(c *gin.Context) {
	var req proto.CustomerRegisterReq
	if err := m.bindJSON(c, &req); err != nil {
		log.Errorf("%s", err)
		return
	}
	resp, code := m.CustomerCore.UserRegister(&req)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	m.OK(c, resp, 1, 1)
}

func (m *Controller) CustomerURegister(c *gin.Context) {
	var req proto.CustomerURegisterReq
	if err := m.bindJSON(c, &req); err != nil {
		log.Errorf("%s", err)
		return
	}
	resp, code := m.CustomerCore.UserNameRegister(&req)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	m.OK(c, resp, 1, 1)
}

func (m *Controller) CustomerLogin(c *gin.Context) {
	var err error
	var req proto.CustomerLoginReq
	if err = m.bindJSON(c, &req); err != nil {
		log.Errorf("%s", err)
		return
	}
	strIP := m.GetClientIP(c)
	do, code := m.CustomerCore.CustomerLogin(&req, strIP)
	if !code.Ok() {
		m.Error(c, code)
		return
	}

	sub, code := m.CustomerCore.CustomerSubscriber(do.Email)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	s := &itypes.Session{
		UserId:      do.GetId(),
		UserName:    do.GetUserName(),
		Alias:       do.GetUserAlias(),
		PhoneNumber: do.GetPhoneNumber(),
		Email:       do.GetEmail(),
		IsAdmin:     false,
		IsCustomer:  true,
		LoginIP:     strIP,
	}

	if s.AuthToken, err = middleware.GenerateToken(s); err != nil {
		err = log.Errorf("generate token error [%s]", err.Error())
		m.Error(c, itypes.NewBizCode(itypes.CODE_INVALID_PARAMS, err.Error()))
		return
	}

	_ = sessions.NewContext(s) // create and save user context
	log.Debugf("customer [%v] login successful, customer id [%v] token [%s]", s.UserName, s.UserId, s.AuthToken)
	var resp = proto.CustomerLoginResp{
		Id:           do.Id,
		Version:      m.cfg.Version,
		UserName:     do.UserName,
		AuthToken:    s.AuthToken,
		LoginTime:    do.LoginTime,
		LoginIp:      do.LoginIp,
		FirstName:    do.FirstName,
		LastName:     do.LastName,
		Title:        do.Title,
		Company:      do.Company,
		IsSubscribed: do.IsSubscribed,
		SubTags:      sub.Tags,
		Privileges:   make([]string, 0),
	}
	m.OK(c, &resp, 1, 1)
}

func (m *Controller) CustomerEdit(c *gin.Context) {
	var err error
	var req proto.CustomerEditReq
	if err = m.bindJSON(c, &req); err != nil {
		log.Errorf("%s", err)
		return
	}
	ctx := sessions.GetContext(c)
	resp, code := m.CustomerCore.CustomerEdit(ctx, &req)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	m.OK(c, resp, 1, 1)
}

func (m *Controller) CustomerLogout(c *gin.Context) {
	resp, code := m.CustomerCore.CustomerLogout(c)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	m.OK(c, resp, 1, 1)
}

func (m *Controller) CustomerSubInfo(c *gin.Context) {
	var err error
	var req proto.CustomerSubInfoReq
	if err = m.bindJSON(c, &req); err != nil {
		log.Errorf("%s", err)
		return
	}
	ctx := sessions.GetContext(c)
	resp, code := m.CustomerCore.CustomerSubInfo(ctx, &req)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	m.OK(c, resp, 1, 1)
}

func (m *Controller) CustomerSubscribe(c *gin.Context) {
	var err error
	var req proto.CustomerSubscribeReq
	if err = m.bindJSON(c, &req); err != nil {
		log.Errorf("%s", err)
		return
	}
	ctx := sessions.GetContext(c)
	resp, code := m.CustomerCore.CustomerSubscribe(ctx, &req)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	m.OK(c, resp, 1, 1)
}

func (m *Controller) CustomerUnsubscribe(c *gin.Context) {
	var err error
	var req proto.CustomerUnsubscribeReq
	if err = m.bindJSON(c, &req); err != nil {
		log.Errorf("%s", err)
		return
	}
	ctx := sessions.GetContext(c)
	resp, code := m.CustomerCore.CustomerUnsubscribe(ctx, &req)
	if !code.Ok() {
		m.Error(c, code)
		return
	}
	m.OK(c, resp, 1, 1)
}
