package com.wutiarn.flibustabot.service;

import com.pengrad.telegrambot.model.Chat;
import com.pengrad.telegrambot.model.Message;
import com.pengrad.telegrambot.model.Update;
import com.pengrad.telegrambot.model.request.ParseMode;
import com.pengrad.telegrambot.request.BaseRequest;
import com.pengrad.telegrambot.request.SendMessage;
import com.pengrad.telegrambot.response.BaseResponse;
import com.wutiarn.flibustabot.model.opds.BookSearchResult;
import com.wutiarn.flibustabot.telegram.commands.TelegramCommandHandler;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;

@Service
public class TelegramEventsRouterService {
    private Logger logger = LoggerFactory.getLogger(TelegramEventsRouterService.class);

    final FlibustaService flibustaService;

    private Configuration freemarkerConfiguration;

    private List<TelegramCommandHandler> commandHandlers;

    @Autowired
    public TelegramEventsRouterService(FlibustaService flibustaService, Configuration freemarkerConfiguration, List<TelegramCommandHandler> commandHandlers) {
        this.flibustaService = flibustaService;
        this.freemarkerConfiguration = freemarkerConfiguration;
        this.commandHandlers = commandHandlers;
    }

    public BaseRequest<? extends BaseRequest, ? extends BaseResponse> processUpdate(Update update) {
        Message message = update.message();
        if (message == null || message.chat().type() != Chat.Type.Private) {
            return null;
        }

        String messageText = message.text();
        if (messageText != null) {
            if (messageText.startsWith("/")) {
                return handleCommand(message);
            } else {
                return handleSearchRequest(message);
            }
        }
        return null;
    }

    private BaseRequest<? extends BaseRequest, ? extends BaseResponse> handleSearchRequest(Message message) {
        String query = message.text();
        BookSearchResult searchResults = flibustaService.search(query, FlibustaService.SearchType.BOOKS);

        var data = new HashMap<String, Object>();
        data.put("results", searchResults);

        String renderedResult;

        try {
            Template template = freemarkerConfiguration.getTemplate("searchResults.ftl");

            ByteArrayOutputStream resultStream = new ByteArrayOutputStream();
            OutputStreamWriter writer = new OutputStreamWriter(resultStream);
            template.process(data, writer);

            writer.close();
            renderedResult = resultStream.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return new SendMessage(message.chat().id(), renderedResult).parseMode(ParseMode.HTML);
    }

    private BaseRequest<? extends BaseRequest, ? extends BaseResponse> handleCommand(Message message) {
        String messageText = message.text();

        if (messageText.startsWith("/")) {
            for (var handler : commandHandlers) {
                Matcher matcher = handler.getMessagePattern().matcher(messageText);
                if (matcher.matches()) {
                    return handler.handleMessage(message, matcher);
                }
            }
            return new SendMessage(message.chat().id(), "Unsupported command");
        }

        return null;
    }

    BaseRequest<? extends BaseRequest, ? extends BaseResponse> handleBookDownload(Message message, String format, String id) {
        return null;
    }
}

@@ -1960,36 +1960,372 @@
     
-return handleCommand(message
+for (var handler : commandHandlers) %7B%0A                    Matcher matcher = handler.getMessagePattern().matcher(messageText);%0A                    if (matcher.matches()) %7B%0A                        return handler.handleMessage(message, matcher);%0A                    %7D%0A                %7D%0A                return new SendMessage(message.chat().id(), %22Unsupported command%22
 );%0A 
@@ -3410,749 +3410,7 @@
    %7D
-%0A%0A    private BaseRequest%3C? extends BaseRequest, ? extends BaseResponse%3E handleCommand(Message message) %7B%0A        String messageText = message.text();%0A%0A        if (messageText.startsWith(%22/%22)) %7B%0A            for (var handler : commandHandlers) %7B%0A                Matcher matcher = handler.getMessagePattern().matcher(messageText);%0A                if (matcher.matches()) %7B%0A                    return handler.handleMessage(message, matcher);%0A                %7D%0A            %7D%0A            return new SendMessage(message.chat().id(), %22Unsupported command%22);%0A        %7D%0A%0A        return null;%0A    %7D%0A%0A    BaseRequest%3C? extends BaseRequest, ? extends BaseResponse%3E handleBookDownload(Message message, String format, String id) %7B%0A        return null;%0A    %7D
 %0A%7D%0A

Handle commands