package tg

import (
	"fmt"
	"strconv"
	"strings"

	tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
	"stud.l9labs.ru/bot/modules/database"
	"stud.l9labs.ru/bot/modules/ssauparser"
)

// –ü—Ä–æ–≤–µ—Ä–∏—Ç—å, –µ—Å—Ç–∏ –ª–∏ —É –ø–æ–ª—å–∑–æ–≤–∞—Ç–µ–ª—è —É–∂–µ –ø–æ–¥–∫–ª—é—á–µ–Ω–Ω–æ–µ —Ä–∞—Å–ø–∏—Å–∞–Ω–∏–µ
func (bot *Bot) IsThereUserShedule(user *database.TgUser) bool {
	options := database.ShedulesInUser{
		L9Id: user.L9Id,
	}
	if _, err := bot.DB.Get(&options); err != nil {
		bot.Debug.Println(err)
	}

	return options.UID != 0
}

// Inline-–∫–Ω–æ–ø–∫–∞ –æ—Ç–º–µ–Ω—ã
func CancelKey() tgbotapi.InlineKeyboardMarkup {
	markup := [][]tgbotapi.InlineKeyboardButton{
		{tgbotapi.NewInlineKeyboardButtonData("–û—Ç–º–µ–Ω–∞", "cancel")},
	}

	return tgbotapi.InlineKeyboardMarkup{InlineKeyboard: markup}
}

// –°–æ–∑–¥–∞–Ω–∏–µ —Ä—è–¥–∞ –∫–Ω–æ–ø–æ–∫ –∏–∑ —Å–ø–∏—Å–∫–∞ –≥—Ä—É–ø–ø
func GenerateGroupsArray(groups []database.Group) []tgbotapi.InlineKeyboardButton {
	var grKeys []tgbotapi.InlineKeyboardButton
	for _, gr := range groups {
		grKeys = append(grKeys, tgbotapi.NewInlineKeyboardButtonData(
			gr.GroupName,
			fmt.Sprintf("false_group_%d", gr.GroupId),
		))
	}

	return grKeys
}

// –°–æ–∑–¥–∞—Ç—å –∏–º—è –ø—Ä–µ–ø–æ–¥–∞–≤–∞—Ç–µ–ª—è —Ñ–æ—Ä–º–∞—Ç–∞ –§–∞–º–∏–ª–∏—è –ò.–û.
func GenerateName(t database.Teacher) string {
	var initials string
	for _, n := range strings.Split(t.FirstName, " ") {
		initials += fmt.Sprintf("%s.", n[:2])
	}
	name := fmt.Sprintf("%s %s", t.LastName, initials)

	return name
}

// –°–æ–∑–¥–∞–Ω–∏–µ —Ä—è–¥–∞ –∫–Ω–æ–ø–æ–∫ –∏–∑ —Å–ø–∏—Å–∫–∞ –ø—Ä–µ–ø–æ–¥–∞–≤–∞—Ç–µ–ª–µ–π
func GenerateTeachersArray(teachers []database.Teacher) []tgbotapi.InlineKeyboardButton {
	var teacherKeys []tgbotapi.InlineKeyboardButton
	for _, t := range teachers {
		name := fmt.Sprintf("%s %s", t.FirstName, t.ShortName)
		teacherKeys = append(teacherKeys, tgbotapi.NewInlineKeyboardButtonData(
			name,
			fmt.Sprintf("false_staff_%d", t.TeacherId),
		))
	}

	return teacherKeys
}

// –°–æ–∑–¥–∞–Ω–∏–µ –ø–æ–ª–Ω–æ—Ü–µ–Ω–Ω–æ–π –∫–ª–∞–≤–∏–∞—Ç—É—Ä—ã –≤—ã–±–æ—Ä–∞
func GenerateKeyboard(array []tgbotapi.InlineKeyboardButton) tgbotapi.InlineKeyboardMarkup {
	var keys []tgbotapi.InlineKeyboardButton
	var markup [][]tgbotapi.InlineKeyboardButton
	// –†–∞–∑–±–∏–≤–∞–µ–º —Å–ø–∏—Å–æ–∫ –∫–Ω–æ–ø–æ–∫ –≤ —Ä—è–¥—ã –ø–æ 3 –∫–Ω–æ–ø–∫–∏
	for _, key := range array {
		keys = append(keys, key)
		if len(keys) >= 3 {
			markup = append(markup, keys)
			keys = []tgbotapi.InlineKeyboardButton{}
		}
	}
	markup = append(markup, keys)
	noOne := tgbotapi.NewInlineKeyboardButtonData("–û—Ç–º–µ–Ω–∞", "cancel")
	markup = append(markup, []tgbotapi.InlineKeyboardButton{noOne})

	return tgbotapi.InlineKeyboardMarkup{InlineKeyboard: markup}
}

type SummaryType string

const (
	SummaryPrefix string      = "sh_"
	Day           SummaryType = "day"
	Week          SummaryType = "week"
	ICS           SummaryType = "ics"
	Connect       SummaryType = "connect"
	Session       SummaryType = "session"
)

// Inline-–∫–ª–∞–≤–∏–∞—Ç—É—Ä–∞ –∫–∞—Ä—Ç–æ—á–∫–∏ —Å —Ä–∞—Å–ø–∏—Å–∞–Ω–∏–µ–º
func SummaryKeyboard(
	clickedButton SummaryType,
	schedule database.Schedule,
	dt int,
	connectButton bool,
) tgbotapi.InlineKeyboardMarkup {
	var sheduleID int64
	if schedule.IsPersonal {
		sheduleID = 0
	} else {
		sheduleID = schedule.ScheduleID
	}
	tail := GenerateButtonTail(sheduleID, 0, schedule.IsGroup)

	day := []tgbotapi.InlineKeyboardButton{
		tgbotapi.NewInlineKeyboardButtonData(
			"–î–µ–Ω—å",
			SummaryPrefix+string(Day)+tail,
		),
	}
	week := []tgbotapi.InlineKeyboardButton{
		tgbotapi.NewInlineKeyboardButtonData(
			"–ù–µ–¥–µ–ª—è",
			SummaryPrefix+string(Week)+tail,
		),
	}

	var update string
	if clickedButton == Week {
		update = GenerateButtonTail(sheduleID, 0, schedule.IsGroup)
	} else {
		update = GenerateButtonTail(sheduleID, dt, schedule.IsGroup)
	}

	ics := []tgbotapi.InlineKeyboardButton{
		tgbotapi.NewInlineKeyboardButtonData(
			"üóì –£—Å—Ç–∞–Ω–æ–≤–∏—Ç—å .ics –≤ —Å–≤–æ–π –ö–∞–ª–µ–Ω–¥–∞—Ä—å",
			SummaryPrefix+string(ICS)+
				GenerateButtonTail(sheduleID, dt, schedule.IsGroup),
		),
	}

	session := []tgbotapi.InlineKeyboardButton{
		tgbotapi.NewInlineKeyboardButtonData(
			"–†–∞—Å–ø–∏—Å–∞–Ω–∏–µ —Å–µ—Å—Å–∏–∏",
			SummaryPrefix+string(Session)+
				GenerateButtonTail(sheduleID, dt, schedule.IsGroup),
		),
	}

	var arrows []tgbotapi.InlineKeyboardButton
	if clickedButton == Day || clickedButton == Week {
		prevArrow := GenerateButtonTail(sheduleID, dt-1, schedule.IsGroup)
		nextArrow := GenerateButtonTail(sheduleID, dt+1, schedule.IsGroup)
		arrows = []tgbotapi.InlineKeyboardButton{
			tgbotapi.NewInlineKeyboardButtonData("‚èÆ", SummaryPrefix+string(clickedButton)+prevArrow),
			tgbotapi.NewInlineKeyboardButtonData("üîÑ", SummaryPrefix+string(clickedButton)+update),
			tgbotapi.NewInlineKeyboardButtonData("‚è≠", SummaryPrefix+string(clickedButton)+nextArrow),
		}
	} else {
		arrows = []tgbotapi.InlineKeyboardButton{
			tgbotapi.NewInlineKeyboardButtonData("üîÑ", SummaryPrefix+string(clickedButton)+update),
		}
	}

	var markup [][]tgbotapi.InlineKeyboardButton
	switch clickedButton {
	case Day:
		markup = [][]tgbotapi.InlineKeyboardButton{
			arrows, week, session,
		}
	case Week:
		markup = [][]tgbotapi.InlineKeyboardButton{
			arrows, ics, day, session,
		}
	default:
		markup = [][]tgbotapi.InlineKeyboardButton{
			arrows, day, week,
		}
	}
	if connectButton && schedule.IsGroup {
		markup = append(markup, []tgbotapi.InlineKeyboardButton{
			tgbotapi.NewInlineKeyboardButtonData("üîî –ü–æ–¥–∫–ª—é—á–∏—Ç—å —É–≤–µ–¥–æ–º–ª–µ–Ω–∏—è", SummaryPrefix+string(Connect)+update),
		})
	}

	return tgbotapi.InlineKeyboardMarkup{InlineKeyboard: markup}
}

func GenerateButtonTail(sheduleID int64, dt int, isGroup bool) string {
	var tail string
	if sheduleID == 0 {
		tail = fmt.Sprintf("_personal_%d_0", dt)
	} else if !isGroup {
		tail = fmt.Sprintf("_teacher_%d_%d", dt, sheduleID)
	} else {
		tail = fmt.Sprintf("_group_%d_%d", dt, sheduleID)
	}

	return tail
}

// –û—Ç–ø—Ä–∞–≤–∫–∞ —Å–æ–æ–±—â–µ–Ω–∏—è –∏–ª–∏ –µ–≥–æ —Ä–µ–¥–∞–∫—Ç–∏—Ä–æ–≤–∞–Ω–∏–µ, –µ—Å–ª–∏ –≤ editMsg —É–∫–∞–∑–∞–Ω–æ —Å–æ–æ–±—â–µ–Ω–∏–µ
// TODO: –û–±—Ä–∞–±–∞—Ç—ã–≤–∞—Ç—å —Å—Ç–∞—Ä—ã–µ —Å–æ–æ–±—â–µ–Ω–∏—è, –∫–æ—Ç–æ—Ä—ã–µ —É–∂–µ –Ω–µ–ª—å–∑—è —Ä–µ–¥–∞–∫—Ç–∏—Ä–æ–≤–∞—Ç—å (message can't be deleted for everyone)
func (bot *Bot) EditOrSend(
	id int64,
	str string,
	imageID string,
	markup tgbotapi.InlineKeyboardMarkup,
	editMsg ...tgbotapi.Message,
) (
	tgbotapi.Message,
	error,
) {

	if len(editMsg) > 0 {
		// –†–µ–¥–∞–∫—Ç–∏—Ä—É–µ–º
		if imageID != "" {
			// –û–±–Ω–æ–≤–ª—è–µ–º —Ñ–æ—Ç–æ, –µ—Å–ª–∏ –µ—Å—Ç—å
			// TODO: —Ä–µ–∞–ª–∏–∑–æ–≤–∞—Ç—å –Ω–æ—Ä–º–∞–ª—å–Ω–æ–µ –æ–±–Ω–æ–≤–ª–µ–Ω–∏–µ —Ñ–æ—Ç–æ, –∫–æ–≥–¥–∞ –Ω—É–∂–Ω—ã–π –º–µ—Ç–æ–¥ –ø–æ—è–≤–∏—Ç—Å—è –≤ tgbotapi
			del := tgbotapi.NewDeleteMessage(
				editMsg[0].Chat.ID,
				editMsg[0].MessageID,
			)
			if _, err := bot.TG.Request(del); err != nil {
				return nilMsg, err
			}
			newMsg := tgbotapi.NewPhoto(
				editMsg[0].Chat.ID,
				tgbotapi.FileID(imageID),
			)
			newMsg.Caption = str
			newMsg.ParseMode = tgbotapi.ModeHTML
			if len(markup.InlineKeyboard) != 0 {
				newMsg.ReplyMarkup = &markup
			}

			return bot.TG.Send(newMsg)
		} else if len(editMsg[0].Photo) == 0 {
			// –§–æ—Ç–æ –Ω–µ—Ç –∏ –Ω–µ –±—ã–ª–æ, —Ç–æ–ª—å–∫–æ —Ç–µ–∫—Å—Ç
			msg := tgbotapi.NewEditMessageText(
				editMsg[0].Chat.ID,
				editMsg[0].MessageID,
				str,
			)
			if len(markup.InlineKeyboard) != 0 {
				msg.ReplyMarkup = &markup
			}
			msg.ParseMode = tgbotapi.ModeHTML
			if _, err := bot.TG.Request(msg); err != nil {
				return nilMsg, err
			}

			return nilMsg, nil
		}
		// –§–æ—Ç–æ –±—ã–ª–æ, –Ω–æ —Ç–µ–ø–µ—Ä—å –µ–≥–æ –Ω–µ –±—É–¥–µ—Ç
		del := tgbotapi.NewDeleteMessage(
			editMsg[0].Chat.ID,
			editMsg[0].MessageID,
		)
		if _, err := bot.TG.Request(del); err != nil {
			return nilMsg, err
		}

		msg := tgbotapi.NewMessage(id, str)
		if len(markup.InlineKeyboard) != 0 {
			msg.ReplyMarkup = &markup
		}
		msg.ParseMode = tgbotapi.ModeHTML

		return bot.TG.Send(msg)
	}
	// –û–±–Ω–æ–≤–ª–µ–Ω–∏–π –Ω–µ—Ç, –Ω–æ–≤–æ–µ —Å–æ–æ–±—â–µ–Ω–∏–µ
	if imageID != "" {
		// –° —Ñ–æ—Ç–æ
		newMsg := tgbotapi.NewPhoto(
			id,
			tgbotapi.FileID(imageID),
		)
		newMsg.Caption = str
		newMsg.ParseMode = tgbotapi.ModeHTML
		if len(markup.InlineKeyboard) != 0 {
			newMsg.ReplyMarkup = &markup
		}

		return bot.TG.Send(newMsg)
	}
	// –¢–æ–ª—å–∫–æ —Ç–µ–∫—Å—Ç
	msg := tgbotapi.NewMessage(id, str)
	if len(markup.InlineKeyboard) != 0 {
		msg.ReplyMarkup = &markup
	}
	msg.ParseMode = tgbotapi.ModeHTML

	return bot.TG.Send(msg)
}

// –†–∞—Å—à–∏—Ñ—Ä–æ–≤—ã–≤–∞—Ç—å —Å–æ–¥–µ—Ä–∂–∏–º–æ–µ –∫–Ω–æ–ø–∫–∏ –∏–∑ –∫–∞—Ä—Ç–æ—á–∫–∏ —Å —Ä–∞—Å–ø–∏—Å–∞–Ω–∏–µ–º
func ParseQuery(data []string) (SummaryType, database.Schedule, int, error) {
	var shedule database.Schedule
	sheduleID, err := strconv.ParseInt(data[4], 0, 64)
	if err != nil {
		return Day, shedule, 0, err
	}
	shedule.IsGroup = data[2] == "group"
	shedule.IsPersonal = data[2] == "personal"
	shedule.ScheduleID = sheduleID
	dt, err := strconv.ParseInt(data[3], 0, 0)
	if err != nil {
		return Day, shedule, 0, err
	}
	var sumType SummaryType
	switch data[1] {
	case "day":
		sumType = Day
	case "week":
		sumType = Week
	case "ics":
		sumType = ICS
	case "connect":
		sumType = Connect
	case "session":
		sumType = Session
	default:
		sumType = Day
	}

	return sumType, shedule, int(dt), nil
}

// –ü—Ä–æ–≤–µ—Ä–∏—Ç—å —Å—Ç—Ä–æ–∫—É –Ω–∞ –Ω–∞–ª–∏—á–∏–µ –æ–¥–Ω–æ–≥–æ –∏–∑ –∫–ª—é—á–µ–≤—ã—Ö —Å–ª–æ–≤
func KeywordContains(str string, keywords []string) bool {
	for _, key := range keywords {
		if strings.Contains(str, key) {
			return true
		}
	}

	return false
}

// –ú–µ–Ω—è–µ–º —à–∏–ª–æ –Ω–∞ –º—ã–ª–æ
func Swap(sh ssauparser.WeekShedule) database.ShedulesInUser {
	return database.ShedulesInUser{
		IsGroup:   sh.IsGroup,
		SheduleId: sh.SheduleID,
	}
}

var Month = []string{
	"—è–Ω–≤–∞—Ä—è",
	"—Ñ–µ–≤—Ä–∞–ª—è",
	"–º–∞—Ä—Ç–∞",
	"–∞–ø—Ä–µ–ª—è",
	"–º–∞—è",
	"–∏—é–Ω—è",
	"–∏—é–ª—è",
	"–∞–≤–≥—É—Å—Ç–∞",
	"—Å–µ–Ω—Ç—è–±—Ä—è",
	"–æ–∫—Ç—è–±—Ä—è",
	"–Ω–æ—è–±—Ä—è",
	"–¥–µ–∫–∞–±—Ä—è",
}
var weekdays = []string{
	"–≤–æ—Å–∫—Ä–µ—Å–µ–Ω—å–µ",
	"–ø–æ–Ω–µ–¥–µ–ª—å–Ω–∏–∫",
	"–≤—Ç–æ—Ä–Ω–∏–∫",
	"—Å—Ä–µ–¥—É",
	"—á–µ—Ç–≤–µ—Ä–≥",
	"–ø—è—Ç–Ω–∏—Ü—É",
	"—Å—É–±–±–æ—Ç—É",
}
var weekdaysNom = []string{
	"–≤–æ—Å–∫—Ä–µ—Å–µ–Ω—å–µ",
	"–ø–æ–Ω–µ–¥–µ–ª—å–Ω–∏–∫",
	"–≤—Ç–æ—Ä–Ω–∏–∫",
	"—Å—Ä–µ–¥–∞",
	"—á–µ—Ç–≤–µ—Ä–≥",
	"–ø—è—Ç–Ω–∏—Ü–∞",
	"—Å—É–±–±–æ—Ç–∞",
}
