package com.alttd.altitudeweb.controllers.chat;

import com.alttd.altitudeweb.database.chat.ChatLogDao;
import com.alttd.altitudeweb.model.ChatMessageDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.experimental.UtilityClass;

import java.util.UUID;

@UtilityClass
public class ChatMessageMapper {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .registerModule(new JavaTimeModule())
            .enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);

    public static ChatMessage fromDto(ChatMessageDto dto) {
        return ChatMessage.builder()
                .uuid(dto.getUuid())
                .timestamp(dto.getTimestamp().toInstant())
                .server(dto.getServer())
                .type(fromDto(dto.getType()))
                .channel(dto.getChannel())
                .receiver(dto.getReceiver())
                .messageJson(dto.getMessage())
                .notBlocked(!dto.getBlocked())
                .build();
    }

    private static ChatMessageType fromDto(ChatMessageDto.TypeEnum type) {
        return switch (type) {
            case PUBLIC -> ChatMessageType.PUBLIC;
            case GLOBAL -> ChatMessageType.GLOBAL;
            case PARTY -> ChatMessageType.PARTY;
            case GAC -> ChatMessageType.GAC;
            case MSG -> ChatMessageType.MSG;
            case CUSTOM -> ChatMessageType.CUSTOM;
            case UNKNOWN_DEFAULT_OPEN_API -> throw new IllegalArgumentException("Unknown chat message type");
        };
    }

    public static ChatMessage fromDao(ChatLogDao dao) {
        return ChatMessage.builder()
                .uuid(UUID.fromString(dao.getUuid()))
                .timestamp(dao.getTimeStamp().toInstant())
                .server(dao.getServer())
                .type(fromString(dao.getType()))
                .channel(dao.getChannel())
                .receiver(dao.getReceiver())
                .messageJson(dao.getMiniMessage())
                .notBlocked(!dao.isBlocked())
                .build();
    }

    private static ChatMessageType fromString(String type) {
        return switch (type) {
            case "public" -> ChatMessageType.PUBLIC;
            case "global" -> ChatMessageType.GLOBAL;
            case "party" -> ChatMessageType.PARTY;
            case "gac" -> ChatMessageType.GAC;
            case "msg" -> ChatMessageType.MSG;
            case "custom" -> ChatMessageType.CUSTOM;
            default -> throw new IllegalArgumentException("Unknown chat message type");
        };
    }

    public static String toJson(ChatMessage chatMessage) {
        try {
            return OBJECT_MAPPER.writeValueAsString(chatMessage);
        } catch (JsonProcessingException e) {
            throw new IllegalStateException("Failed to serialize ChatMessage to JSON: " + chatMessage.getUuid(), e);
        }
    }
}
