package service

import (
	"center-api/api/apierr"
	"center-api/internal/pkg/helper"
	"context"
	"fmt"
	http2 "net/http"
	"strconv"

	"github.com/duke-git/lancet/v2/convertor"
	"github.com/go-kratos/kratos/v2/transport/http"
	"github.com/pkg/errors"
)

// BaseService service 公共方法
type BaseService struct {
}

// LoginUser 登录用户信息
type LoginUser struct {
	Id          int
	Phone       string
	UserName    string
	RealName    string
	AccountType int
	GroupCodes  string
	DingUserId  string
}

type BaseResponse struct {
	Code  int         `json:"code"`
	Data  interface{} `json:"data"`
	Error string      `json:"error"`
}

const AdministratorUserID = 1 // 管理员id

// GetLoginClaim 获取登录用户信息
func (b *BaseService) GetLoginClaim(ctx context.Context) (*LoginUser, error) {
	rq, ok := http.RequestFromServerContext(ctx)
	if !ok {
		return nil, errors.New("无法获取 header 数据")
	}
	userId, _ := convertor.ToInt(rq.Header.Get("User-Id"))
	if userId <= 0 {
		return nil, apierr.ErrorNotLogin("未登录")
	}
	accountType, _ := convertor.ToInt(rq.Header.Get("Account-Type"))
	user := &LoginUser{
		Id:          int(userId),
		Phone:       rq.Header.Get("User-Phone"),
		UserName:    rq.Header.Get("User-Name"),
		RealName:    rq.Header.Get("Real-Name"),
		AccountType: int(accountType),
		GroupCodes:  rq.Header.Get("Group-Codes"),
		DingUserId:  rq.Header.Get("Ding-User-Id"),
	}
	return user, nil
}

// GetLoginUserPhone 获取
func (b *BaseService) GetLoginUserPhone(ctx context.Context) string {
	user, err := b.GetLoginClaim(ctx)
	if err != nil {
		panic(err)
	}
	return user.Phone
}

// GetUserName 获取用户名
func (b *BaseService) GetUserName(ctx context.Context) string {
	user, err := b.GetLoginClaim(ctx)
	if err != nil {
		return "系统用户"
	}
	if user.RealName != "" {
		return user.RealName
	}
	if user.UserName != "" {
		return user.UserName
	}
	return strconv.Itoa(user.Id)
}

// GetRequestUrl 获取请求url
func (b *BaseService) GetRequestUrl(ctx context.Context) string {
	request, ok := http.RequestFromServerContext(ctx)
	if !ok {
		return ""
	}
	return request.URL.Path
}

// GetRequestIPLong 获取请求ip
func (b *BaseService) GetRequestIPLong(ctx context.Context) uint {
	rq, ok := http.RequestFromServerContext(ctx)
	if !ok {
		return 0
	}
	clientIP := helper.GetClientIP(rq)
	return helper.IPString2Long(clientIP)
}

// ResponseOK 返回 json 成功
func (b *BaseService) ResponseOK(ctx http.Context, data interface{}) error {
	return ctx.JSON(http2.StatusOK, &BaseResponse{
		Code:  200,
		Data:  data,
		Error: "",
	})
}

// Response 返回 json
func (b *BaseService) Response(ctx http.Context, code int, data interface{}, error string) error {
	return ctx.JSON(http2.StatusOK, &BaseResponse{
		Code:  code,
		Data:  data,
		Error: error,
	})
}

// ResponseError 返回 json 错误
func (b *BaseService) ResponseError(ctx http.Context, error string) error {
	return ctx.JSON(http2.StatusOK, &BaseResponse{
		Code:  600,
		Error: error,
	})
}

// ExportExcel 导出 excel 头设置
func (b *BaseService) ExportExcel(ctx http.Context, encodedFilename string) http.ResponseWriter {
	disposition := fmt.Sprintf("attachment; filename=%s", encodedFilename)
	ctx.Response().Header().Set("Content-Type", "application/vnd.openxmlformats; charset=utf-8")
	ctx.Response().Header().Set("Content-Disposition", disposition)
	ctx.Response().Header().Set("Access-Control-Expose-Headers", "Content-Disposition")
	return ctx.Response()
}
