package com.alttd.webinterface.send_message;

import com.alttd.webinterface.bot.DiscordBotInstance;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;

import java.awt.*;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Slf4j
public class DiscordSender {

    private static final DiscordSender INSTANCE = new DiscordSender();

    private final DiscordBotInstance botInstance = new DiscordBotInstance();

    private DiscordSender() {}

    public static DiscordSender getInstance() {
        return INSTANCE;
    }

    private void ensureStarted() {
        if (botInstance.getJda() != null) return;
        String token = Optional.ofNullable(System.getenv("DISCORD_TOKEN"))
                .orElse(System.getProperty("DISCORD_TOKEN"));
        if (token == null || token.isBlank()) {
            log.error("Discord token not found. Set DISCORD_TOKEN as an environment variable or system property.");
            return;
        }
        botInstance.start(token);
    }

    public void sendMessageToChannels(List<Long> channelIds, String message) {
        ensureStarted();
        if (botInstance.getJda() == null) {
            log.error("JDA not initialized; cannot send Discord message.");
            return;
        }
        try {
            if (!botInstance.isReady()) {
                botInstance.getJda().awaitReady();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            log.warn("Error while waiting for JDA ready state", e);
        }

        channelIds.stream()
                .filter(Objects::nonNull)
                .forEach(id -> {
                    TextChannel channel = botInstance.getJda().getChannelById(TextChannel.class, id);
                    if (channel == null) {
                        log.warn("TextChannel with id {} not found", id);
                        return;
                    }
                    channel.sendMessage(message).queue(
                            success -> log.debug("Sent message to channel {}", id),
                            error -> log.error("Failed sending message to channel {}", id, error)
                    );
                });
    }

    public void sendEmbedToChannels(List<Long> channelIds, String title, String description, List<EmbedField> fields,
                                    Integer colorRgb, Instant timestamp, String footer) {
        ensureStarted();
        if (botInstance.getJda() == null) {
            log.error("JDA not initialized; cannot send Discord embed.");
            return;
        }
        try {
            if (!botInstance.isReady()) {
                botInstance.getJda().awaitReady();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (Exception e) {
            log.warn("Error while waiting for JDA ready state", e);
        }

        EmbedBuilder eb = new EmbedBuilder();
        if (title != null && !title.isBlank()) eb.setTitle(title);
        if (description != null && !description.isBlank()) eb.setDescription(description);
        if (colorRgb != null) eb.setColor(new Color(colorRgb)); else eb.setColor(new Color(0xFF8C00)); // default orange
        eb.setTimestamp(timestamp != null ? timestamp : Instant.now());
        if (footer != null && !footer.isBlank()) eb.setFooter(footer);

        if (fields != null) {
            for (EmbedField f : fields) {
                if (f == null) continue;
                String name = f.getName() == null ? "" : f.getName();
                String value = f.getValue() == null ? "" : f.getValue();
                // JDA field value max is 1024; truncate to be safe
                if (value.length() > 1024) value = value.substring(0, 1021) + "...";
                eb.addField(new MessageEmbed.Field(name, value, f.isInline()));
            }
        }

        MessageEmbed embed = eb.build();

        channelIds.stream()
                .filter(Objects::nonNull)
                .forEach(id -> {
                    TextChannel channel = botInstance.getJda().getChannelById(TextChannel.class, id);
                    if (channel == null) {
                        log.warn("TextChannel with id {} not found", id);
                        return;
                    }
                    channel.sendMessageEmbeds(embed).queue(
                            success -> log.debug("Sent embed to channel {}", id),
                            error -> log.error("Failed sending embed to channel {}", id, error)
                    );
                });
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class EmbedField {
        private String name;
        private String value;
        private boolean inline;
    }
}
