package com.pablotj.ai.chat.domain.model;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

/**
 * Value Object containing metadata for messages.
 */
public final class MessageMetadata {

    private final Map<String, Object> properties;

    private MessageMetadata(Map<String, Object> properties) {
        this.properties = Collections.unmodifiableMap(new HashMap<>(properties));
    }

    public static MessageMetadata empty() {
        return new MessageMetadata(Collections.emptyMap());
    }

    public static MessageMetadata of(Map<String, Object> properties) {
        return new MessageMetadata(properties != null ? properties : Collections.emptyMap());
    }

    public static Builder builder() {
        return new Builder();
    }

    public Optional<Object> getProperty(String key) {
        return Optional.ofNullable(properties.get(key));
    }

    @SuppressWarnings("unchecked")
    public <T> Optional<T> getProperty(String key, Class<T> type) {
        return getProperty(key)
                .filter(type::isInstance)
                .map(value -> (T) value);
    }

    public Map<String, Object> getAllProperties() {
        return properties;
    }

    public boolean isEmpty() {
        return properties.isEmpty();
    }

    public MessageMetadata withProperty(String key, Object value) {
        Map<String, Object> newProperties = new HashMap<>(properties);
        newProperties.put(key, value);
        return new MessageMetadata(newProperties);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        MessageMetadata that = (MessageMetadata) obj;
        return Objects.equals(properties, that.properties);
    }

    @Override
    public int hashCode() {
        return Objects.hash(properties);
    }

    public static final class Builder {
        private final Map<String, Object> properties = new HashMap<>();

        private Builder() {
        }

        public Builder property(String key, Object value) {
            if (key != null && value != null) {
                properties.put(key, value);
            }
            return this;
        }

        public Builder properties(Map<String, Object> properties) {
            if (properties != null) {
                this.properties.putAll(properties);
            }
            return this;
        }

        public MessageMetadata build() {
            return new MessageMetadata(properties);
        }
    }
}
