Files
TelegaBot/src/main/java/ru/cathub/telegabot/service/impl/BookCreationServiceImpl.java
T
2025-02-17 20:18:04 +03:00

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, "📚 Спасибо за добавление книги!");
}
}
}