186 lines
9.2 KiB
Java
186 lines
9.2 KiB
Java
package ru.cathub.telegabot.service.impl;
|
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import ru.cathub.telegabot.model.Book;
|
|
import ru.cathub.telegabot.model.BookCreationCache;
|
|
import ru.cathub.telegabot.model.BotUser;
|
|
import ru.cathub.telegabot.model.TextRole;
|
|
import ru.cathub.telegabot.repository.BookRepository;
|
|
import ru.cathub.telegabot.repository.UserRepository;
|
|
import ru.cathub.telegabot.service.*;
|
|
import ru.cathub.telegabot.utils.Constants;
|
|
|
|
import java.sql.Date;
|
|
import java.text.ParseException;
|
|
import java.text.SimpleDateFormat;
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDateTime;
|
|
import java.time.temporal.ChronoUnit;
|
|
|
|
import static ru.cathub.telegabot.utils.BookFormatUtils.*;
|
|
import static ru.cathub.telegabot.utils.Constants.ADD_BOOK;
|
|
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class BookCreationServiceImpl implements BookCreationService {
|
|
|
|
private final BookCacheService bookCacheService;
|
|
private final TelegramClientService telegramClientService;
|
|
private final BookRepository bookRepository;
|
|
private final BookCommonService bookCommonService;
|
|
private final OpenRouterService openRouterService;
|
|
private final UserRepository userRepository;
|
|
|
|
@Override
|
|
public void handleNewAddRequest(BotUser user, String text) {
|
|
if (ADD_BOOK.equals(text)) {
|
|
BookCreationCache newCache = new BookCreationCache();
|
|
newCache.setCreationState(BookCreationCache.CreationState.ADDING_TITLE);
|
|
bookCacheService.updateCache(user.getId(), newCache);
|
|
|
|
telegramClientService.sendMessageWithMarkdown(user, "*Введите название книги: \uD83D\uDCDA*", null);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@Transactional
|
|
public void handleExistingAddCache(BotUser user, String text) {
|
|
BookCreationCache cache = bookCacheService.getCache(user.getId());
|
|
|
|
if (cache == null) {
|
|
log.warn("No creation cache found for user {}", user.getId());
|
|
telegramClientService.sendMessage(user, "❌ Ошибка: не найдены данные для создания книги");
|
|
return;
|
|
}
|
|
|
|
try {
|
|
switch (cache.getCreationState()) {
|
|
case ADDING_TITLE -> {
|
|
log.info("Processing ADDING_TITLE state...");
|
|
cache.setTitle(text.trim());
|
|
cache.setCreationState(BookCreationCache.CreationState.ADDING_AUTHOR);
|
|
bookCacheService.updateCache(user.getId(), cache);
|
|
telegramClientService.sendMessage(user, "✍️ Введите автора книги:");
|
|
}
|
|
|
|
case ADDING_AUTHOR -> {
|
|
log.info("Processing ADDING_AUTHOR state...");
|
|
cache.setAuthor(text.trim());
|
|
cache.setCreationState(BookCreationCache.CreationState.ADDING_RATING);
|
|
bookCacheService.updateCache(user.getId(), cache);
|
|
telegramClientService.sendMessage(user, "⭐ Введите рейтинг книги (от 0 до 10):");
|
|
}
|
|
|
|
case ADDING_RATING -> {
|
|
int rating = validateAndParseRating(text);
|
|
cache.setRating(rating);
|
|
cache.setCreationState(BookCreationCache.CreationState.ADDING_DATE);
|
|
bookCacheService.updateCache(user.getId(), cache);
|
|
telegramClientService.sendMessage(user, "📅 Введите дату прочтения (в формате ДД.ММ.ГГГГ): \n" +
|
|
"✅ Для указания текущей даты введите букву \"т\"");
|
|
}
|
|
|
|
case ADDING_DATE -> {
|
|
Date readDate = parseDate(text.trim());
|
|
cache.setReadDate(readDate);
|
|
bookCacheService.updateCache(user.getId(), cache);
|
|
|
|
createAndSaveBookFromCache(user, cache);
|
|
}
|
|
|
|
default -> {
|
|
log.warn("Invalid creation state for user {}", user.getId());
|
|
telegramClientService.sendMessage(user, "❌ Ошибка: неверное состояние создания книги");
|
|
}
|
|
}
|
|
} catch (NumberFormatException e) {
|
|
log.error("Invalid rating format for user {}", user.getId(), e);
|
|
telegramClientService.sendMessage(user, "❌ Ошибка: рейтинг должен быть числом от 0 до 10");
|
|
} catch (ParseException e) {
|
|
log.error("Invalid date format for user {}", user.getId(), e);
|
|
telegramClientService.sendMessage(user, "❌ Ошибка: дата должна быть в формате ДД.ММ.ГГГГ");
|
|
} catch (Exception e) {
|
|
log.error("Error creating book for user {}", user.getId(), e);
|
|
telegramClientService.sendMessage(user, "❌ Ошибка при создании книги");
|
|
bookCacheService.clearCache(user.getId());
|
|
}
|
|
}
|
|
|
|
private int validateAndParseRating(String text) throws NumberFormatException {
|
|
int rating = Integer.parseInt(text);
|
|
if (rating < Constants.MIN_RATING || rating > Constants.MAX_RATING) {
|
|
throw new NumberFormatException("Rating out of bounds");
|
|
}
|
|
return rating;
|
|
}
|
|
|
|
private Date parseDate(String text) throws ParseException {
|
|
if (text.matches("^([tTтТ])$")) {
|
|
return new Date(System.currentTimeMillis());
|
|
}
|
|
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy");
|
|
format.setLenient(false);
|
|
return new Date(format.parse(text).getTime());
|
|
}
|
|
|
|
private Book createBookFromCache(BookCreationCache cache, BotUser user) {
|
|
return Book.builder().title(cache.getTitle()).author(cache.getAuthor()).rating(cache.getRating()).readDate(cache.getReadDate()).botUser(user).build();
|
|
}
|
|
|
|
private void createAndSaveBookFromCache(BotUser user, BookCreationCache cache) {
|
|
Book book = createBookFromCache(cache, user);
|
|
bookCacheService.clearCache(user.getId());
|
|
|
|
String message = String.format("✅ Книга успешно добавлена\\!\n\n%s", bookCommonService.formatBookDetails(book));
|
|
|
|
LocalDate today = LocalDate.now();
|
|
LocalDate endOfYear = LocalDate.of(today.getYear(), 12, 31);
|
|
int weeksLeft = Math.toIntExact(ChronoUnit.WEEKS.between(today, endOfYear));
|
|
|
|
BotUser freshUser = userRepository.findById(user.getId()).orElseThrow();
|
|
if (freshUser.getBooksToRead() != null) {
|
|
int target = freshUser.getBooksToRead();
|
|
int read = freshUser.getBooks() != null ? freshUser.getBooks().size() : 0;
|
|
int left = target - read;
|
|
|
|
String stats;
|
|
if (left < 0) {
|
|
stats = formatBookMoreStats(weeksLeft, read);
|
|
} else if (left == 0) {
|
|
stats = "";
|
|
try {
|
|
String prompt = String.format("Придумай креативное поздравление с тем, что пользователь выполнил большое достижение по прочтению цель по проятению %d книг за год", freshUser.getBooksToRead());
|
|
String congrat = openRouterService.getChatResponse(prompt, TextRole.DEFAULT);
|
|
log.info("Congratulation target generated: {}", congrat);
|
|
telegramClientService.sendMessageWithMarkdown(user, "🎉 *Поздравляю с прочтением\\!*\n\n" + escapeNonMarkdown(congrat));
|
|
} catch (Exception e) {
|
|
log.error("Error generating congratulation for user {}", user.getId(), e);
|
|
telegramClientService.sendMessage(user, "📚 Спасибо за добавление книги\\!");
|
|
}
|
|
} else {
|
|
stats = formatBookLeftStats(weeksLeft, target, read, left);
|
|
}
|
|
telegramClientService.sendMessageWithMarkdown(user, message + stats);
|
|
}
|
|
bookRepository.save(book);
|
|
|
|
user.setLastReadDate(new Date(System.currentTimeMillis()));
|
|
user.setLastNotificationDate(null);
|
|
userRepository.save(user);
|
|
|
|
try {
|
|
String prompt = String.format("Придумай креативное поздравление с прочтением книги \"%s\" от автора \"%s\". Учитывай что пользователь поставил оценку %d/10. ", cache.getTitle(), cache.getAuthor(), cache.getRating());
|
|
String congrat = openRouterService.getChatResponse(prompt, TextRole.DEFAULT);
|
|
log.info("Congratulation generated: {}", congrat);
|
|
telegramClientService.sendMessageWithMarkdown(user, "🎉 *Поздравляю с прочтением\\!*\n\n" + escapeNonMarkdown(congrat));
|
|
} catch (Exception e) {
|
|
log.error("Error generating congratulation for user {}", user.getId(), e);
|
|
telegramClientService.sendMessage(user, "📚 Спасибо за добавление книги!");
|
|
}
|
|
}
|
|
}
|