// Package tgbot — Telegram-адаптер: приём magnet/пересланных сообщений
// торрент-бота, подтверждение раскладки кнопками и исходящие пинги.
package tgbot

import (
	"regexp"
	"strings"
)

var (
	magnetRe = regexp.MustCompile(`magnet:\?[^\s]+`)
	// parenURL — markdown-хвост " (https://…)" в строках сообщения бота.
	parenURL = regexp.MustCompile(`\s*\(https?://[^)]+\)`)
)

// magnetTrailingPunct — хвостовая пунктуация, которую жадный magnetRe (`[^\s]+`)
// приклеивает к ссылке, когда magnet стоит в конце предложения или в скобках
// («…magnet:?xt=…).»). Такой хвост сдвигает последний xt и ломает разбор
// (длина btih становится 41 → отказ). TrimRight трактует cutset как множество
// рун, поэтому многобайтовая «»» отсекается корректно.
const magnetTrailingPunct = ".,;:)]}>»"

// noisePrefixes — начала строк UI торрент-бота, которые в контекст не несём.
var noisePrefixes = []string{
	"Открыть magnet", "или получить .torrent", "Оценить", "Следить",
	"В закладки", "Добавить в закладки", "cправка", "справка",
	"[список файлов]", "[список файлов]", "⚡", "сохранённая копия",
}

// ParseMessage извлекает из текста magnet-ссылку и человекочитаемый контекст
// (заголовок релиза без ссылок, команд и UI-мусора бота). ok=false, если
// magnet не найден. Текст может быть как «сырым» magnet, так и пересланным
// сообщением торрент-бота (формат — см. tmp/examples.md).
func ParseMessage(text string) (source, context string, ok bool) {
	m := magnetRe.FindString(text)
	if m == "" {
		return "", "", false
	}
	// Срезаем хвостовую пунктуацию, приклеенную жадным матчем (см. константу).
	m = strings.TrimRight(m, magnetTrailingPunct)
	return m, cleanContext(text, m), true
}

// cleanContext оставляет содержательные строки (заголовок, метаданные),
// выкидывая ссылки, команды (/...) и UI-строки бота.
func cleanContext(text, magnet string) string {
	var keep []string
	for _, line := range strings.Split(text, "\n") {
		line = strings.TrimSpace(line)
		if line == "" || strings.Contains(line, magnet) {
			continue
		}
		if isNoise(line) {
			continue
		}
		line = strings.TrimSpace(parenURL.ReplaceAllString(line, ""))
		if line != "" {
			keep = append(keep, line)
		}
	}
	return strings.Join(keep, "\n")
}

func isNoise(line string) bool {
	if strings.HasPrefix(line, "/") {
		return true
	}
	// Строки-ссылки и строки рейтинга/команд бота (содержат /g_ /r_ /us_ …).
	if strings.Contains(line, "hashurl.ru") || strings.Contains(line, "exfreedomist.com") {
		return true
	}
	for _, p := range noisePrefixes {
		if strings.HasPrefix(line, p) {
			return true
		}
	}
	// Строки вида "👍: /g_ad035f или 👎🏿: /r_ad035f".
	if strings.Contains(line, ": /") {
		return true
	}
	return false
}
