package log

import (
	"context"
	"encoding/json"

	"github.com/perfect-panel/server/internal/svc"
	"github.com/perfect-panel/server/internal/types"
	"github.com/perfect-panel/server/pkg/logger"
	"github.com/perfect-panel/server/pkg/xerr"
	"github.com/pkg/errors"
)

type GetLogMessageRawLogic struct {
	logger.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetLogMessageRawLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLogMessageRawLogic {
	return &GetLogMessageRawLogic{Logger: logger.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
}

func (l *GetLogMessageRawLogic) GetLogMessageRaw(req *types.GetLogMessageRawRequest) (resp *types.GetLogMessageRawResponse, err error) {
	row, err := l.svcCtx.LogMessageModel.FindOne(l.ctx, req.Id)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "FindOne log_message id=%d: %v", req.Id, err)
	}

	var contextJSON json.RawMessage
	if row.Context != "" {
		if json.Valid([]byte(row.Context)) {
			contextJSON = json.RawMessage(row.Context)
		} else {
			b, _ := json.Marshal(row.Context)
			contextJSON = b
		}
	}

	var occurredAt int64
	if row.OccurredAt != nil {
		occurredAt = row.OccurredAt.UnixMilli()
	}

	return &types.GetLogMessageRawResponse{
		Id:         row.Id,
		Platform:   row.Platform,
		AppVersion: row.AppVersion,
		OsName:     row.OsName,
		OsVersion:  row.OsVersion,
		DeviceId:   row.DeviceId,
		UserId:     row.UserId,
		SessionId:  row.SessionId,
		Level:      row.Level,
		ErrorCode:  row.ErrorCode,
		Message:    row.Message,
		Stack:      row.Stack,
		Context:    contextJSON,
		ClientIP:   row.ClientIP,
		UserAgent:  row.UserAgent,
		Locale:     row.Locale,
		Digest:     row.Digest,
		OccurredAt: occurredAt,
		CreatedAt:  row.CreatedAt.UnixMilli(),
	}, nil
}
