package notify

import (
	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
	"github.com/rs/zerolog/log"
	"regexp"
	"strconv"
	"strings"
	"time"
	"watn3y/bloaterbotv3/botIO"
)

func Reminder(update tgbotapi.Update, bot *tgbotapi.BotAPI) {
	log.Debug().Str("args", update.Message.CommandArguments()).Msg("parsing new reminder")
	commandArgs := strings.Fields(update.Message.CommandArguments())

	var timeArg string
	var textArg string

	if len(commandArgs) >= 1 {
		timeArg = strings.ToLower(commandArgs[0])
		textArg = strings.Replace(update.Message.CommandArguments(), timeArg, "", 1)
	} else {
		log.Error().Str("args", update.Message.CommandArguments()).Msg("invalid new reminder")
		message := tgbotapi.MessageConfig{
			BaseChat:              tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID},
			ParseMode:             "html",
			DisableWebPagePreview: false,
			Text:                  "Please specify a valid notify time in this format: 1m, 6h, 2d",
		}
		botIO.SendMessage(message, bot)
		return
	}

	isValidFormat := regexp.MustCompile(`(?m)^\d{1,3}[mhd]$`)

	if !isValidFormat.MatchString(timeArg) {
		log.Error().Str("args", update.Message.CommandArguments()).Msg("invalid new reminder")
		message := tgbotapi.MessageConfig{
			BaseChat:              tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID},
			ParseMode:             "html",
			DisableWebPagePreview: false,
			Text:                  "Please specify a valid notify time in this format: 1m, 6h, 2d",
		}
		botIO.SendMessage(message, bot)
		return
	}

	getChar := regexp.MustCompile(`(?m)[mhd]`)
	getNumbers := regexp.MustCompile(`(?m)\d{1,3}`)

	numberString := getNumbers.FindString(timeArg)
	number, _ := strconv.Atoi(numberString)
	char := getChar.FindString(timeArg)

	var modifyTime time.Duration
	switch char {
	case "m":
		modifyTime = time.Minute
	case "h":
		modifyTime = time.Hour
	case "d":
		modifyTime = time.Hour * 24
	}

	notifyTime := time.Now().UTC().Add(time.Duration(number) * modifyTime)

	reminder := reminderConfig{
		updateID:           update.UpdateID,
		notifyTime:         notifyTime.Unix(),
		chatID:             update.Message.Chat.ID,
		userID:             update.Message.From.ID,
		messageToReplyToID: update.Message.MessageID,
		reminderText:       textArg,
	}

	log.Info().Int("ID", reminder.updateID).Int64("chat", reminder.chatID).Int64("user", reminder.userID).Int64("time", reminder.notifyTime).Msg("adding new reminder")

	sqlAddReminder(reminder)

	message := tgbotapi.MessageConfig{
		BaseChat:              tgbotapi.BaseChat{ChatID: update.Message.Chat.ID, ReplyToMessageID: update.Message.MessageID},
		ParseMode:             "html",
		DisableWebPagePreview: false,
		Text:                  "Set reminder for " + notifyTime.Format("02.01.2006") + " at " + notifyTime.Format("15:04") + " UTC ",
	}
	botIO.SendMessage(message, bot)
	return

}

func NotifyHandler(bot *tgbotapi.BotAPI) {

	for {
		reminders := sqlGetReminders()

		for updateID, reminderTime := range reminders {
			if reminderTime <= time.Now().UTC().Unix() {
				log.Info().Int("ID", updateID).Msg("reminder is due")
				details := sqlGetReminderDetails(updateID)

				message := tgbotapi.MessageConfig{
					BaseChat:              tgbotapi.BaseChat{ChatID: details.chatID, ReplyToMessageID: details.messageToReplyToID},
					ParseMode:             "html",
					DisableWebPagePreview: false,
					Text:                  "Reminder: " + details.reminderText,
				}
				log.Info().Int64("chat", details.chatID).Int64("user", details.userID).Str("text", details.reminderText).Msg("sent reminder")

				botIO.SendMessage(message, bot)

				sqlDeleteReminder(updateID)
			}

		}
		time.Sleep(time.Second * 10)
	}

}