2024-12-18 11:08:21 -04:00

192 lines
4.9 KiB
Go

package message
import (
"bytes"
"context"
"fmt"
"log/slog"
"strconv"
"strings"
"sync"
"git.maximotejeda.com/maximo/cedulados-bot/internal/adapter/helper"
"git.maximotejeda.com/maximo/cedulados-bot/internal/application/domain"
"git.maximotejeda.com/maximo/cedulados-bot/internal/ports"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)
var ChatPool *sync.Pool
type Message struct {
bot *tgbotapi.BotAPI
update *tgbotapi.Update
msg *tgbotapi.MessageConfig
log *slog.Logger
ce ports.CeduladosService
user ports.UserService
}
// NewMessage
// Factory for message handler
func NewMessage(bot *tgbotapi.BotAPI, update *tgbotapi.Update, cSVC ports.CeduladosService, user ports.UserService) *Message {
if ChatPool == nil {
ChatPool = &sync.Pool{
New: func() any { return &Message{} },
}
for i := 0; i < 20; i++ {
ChatPool.Put(ChatPool.New())
}
}
log := slog.Default()
log = log.With("function", "message", "chat", update.Message.Chat.ID, "userid", update.Message.From.ID, "username", update.Message.From.UserName)
message := ChatPool.Get().(*Message)
message.update = update
message.bot = bot
message.log = log
message.ce = cSVC
message.user = user
return message
}
// Empty
// Returns pointer to pool
func (m *Message) Empty() {
m.update = nil
m.msg = nil
m.log = nil
m.ce = nil
m.user = nil
ChatPool.Put(m)
}
// Send
// Process message sending to bot
func (m *Message) Send() {
defer m.Empty()
m.bot.Send(m.msg)
}
func (m *Message) Handler(){
msg := tgbotapi.NewMessage(m.update.Message.Chat.ID, "")
m.msg = &msg
text := helper.RemoveAccent(m.update.Message.Text)
textList := strings.Split(text, " ")
if len(textList) >= 1 && helper.MessageChecker(text) == "digit" {
// in case of message match a cedula
ced, err := helper.NewCedula(context.Background(), text)
if err != nil {
msg.Text = "cedula no reconocida " + err.Error()
} else {
msg, photoMsg := ProcessByCedula(context.Background(), m.ce, m.user, ced)
msg.ChatID = m.update.Message.Chat.ID
if photoMsg != nil {
photoMsg.ChatID = m.update.Message.Chat.ID
m.bot.Send(photoMsg)
}
m.bot.Send(msg)
return
}
} else if len(textList) >= 2 && helper.MessageChecker(text) == "word" {
msg := ProcessByName(context.Background(), m.ce, m.user, textList)
msg.ChatID = m.update.Message.Chat.ID
m.bot.Send(msg)
}
msg.ReplyToMessageID = m.update.Message.MessageID
m.bot.Send(msg)
}
// ProcessByCedula
//
// When a text arrives the chat if it match a cedula try to query db
func ProcessByCedula(ctx context.Context, cSVC ports.CeduladosService, uSVC ports.UserService, ced *domain.Cedula) (message *tgbotapi.MessageConfig, fotoMsg *tgbotapi.PhotoConfig) {
msg := tgbotapi.NewMessage(0, "")
message = &msg
info , err := cSVC.CeduladoByCedula(context.Background(), ced)
if err != nil {
fmt.Println("error on query ", err)
}
fmt.Println("!!!!success on query", info)
if info != nil {
msg.Text = fmt.Sprintf(`
Nombres: %s
Apellidos: %s %s
Cedula: %s
Direccion: %s
Telefono: %s
`,
strings.ToLower(info.Nombres), strings.ToLower(info.Apellido1), strings.ToLower(info.Apellido2),
info.MunCed+info.SeqCed+info.VerCed, helper.RemoveSpaces(info.Direccion), info.Telefono)
}
foto, err := cSVC.QueryFotoByCedula(ctx, ced)
if err != nil {
fmt.Println("Photo not found", err.Error())
return
}
if foto != nil {
rq := tgbotapi.FileReader{Name: fmt.Sprintf("%s-%s-%s", ced.MunCed, ced.SeqCed, ced.VerCed), Reader: bytes.NewReader(foto.Imagen)}
fotost := tgbotapi.NewPhoto(msg.ChatID, rq)
fotoMsg = &fotost
}
return
}
func ProcessByName(ctx context.Context, cSVC ports.CeduladosService, uSVC ports.UserService, nameList []string) (message *tgbotapi.MessageConfig) {
var err error
page := int64(0)
// look for if the last part of the list is a number
lastItem := nameList[len(nameList)-1]
if helper.MessageChecker(lastItem) == "digit" && !strings.HasPrefix(lastItem, "0") {
pageInt, err := strconv.ParseInt(lastItem, 10, 64)
if err != nil {
fmt.Println(err)
}
nameList = nameList[:len(nameList)-1]
if pageInt < 20 {
page = pageInt
}
}
rows := &domain.MultipleResults{}
message = &tgbotapi.MessageConfig{}
text := strings.Join(nameList, " ")
res, err := cSVC.CeduladoByFTS(ctx, text, 0)
if err != nil {
fmt.Println("error oon fts", err)
}
fmt.Println("sucess", res)
rows, err = cSVC.CeduladoByFTS(ctx, text, page)
if err != nil {
message.Text = "no hubo resultados para la busqueda"
return
}
textToSend := fmt.Sprintf(`
Busqueda:
Texto: %s
Pagina: %d
resultados desde: %d A %d
De un total de: %d
`,
text,
(rows.Page),
(rows.Page*10)-9, (rows.Page)*10,
rows.Total)
for _, v := range rows.Data {
textToSend = textToSend + fmt.Sprintf("\n %s %s %s \n %s-%s-%s\n", strings.ToLower(v.Nombres), strings.ToLower(v.Apellido1), strings.ToLower(v.Apellido2), v.MunCed, v.SeqCed, v.VerCed)
}
message.Text = textToSend
return
}