package com.aegis.resource.expert.domain;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import com.aegis.common.exception.ServiceException;

/**
 * 专家联系方式值对象
 * 
 * @author aegis
 */
public class ExpertContact {
    
    private static final int MAX_LENGTH = 1000;
    
    private final List<ContactItem> items;
    
    private ExpertContact(List<ContactItem> items) {
        if (items == null) {
            items = new ArrayList<>();
        }
        // 业务规则：每个联系方式项不能为空
        for (ContactItem item : items) {
            if (item == null) {
                throw new ServiceException("联系方式项不能为空");
            }
            if (StringUtils.isBlank(item.getType())) {
                throw new ServiceException("联系方式类型不能为空");
            }
            if (StringUtils.isBlank(item.getValue())) {
                throw new ServiceException("联系方式值不能为空");
            }
        }
        this.items = Collections.unmodifiableList(new ArrayList<>(items));
    }
    
    /**
     * 创建专家联系方式值对象（允许空）
     */
    public static ExpertContact of(List<ContactItem> items) {
        if (items == null || items.isEmpty()) {
            return empty();
        }
        return new ExpertContact(items);
    }
    
    /**
     * 创建空的联系方式
     */
    public static ExpertContact empty() {
        return new ExpertContact(new ArrayList<>());
    }
    
    /**
     * 从存储格式创建（应用服务层使用）
     */
    public static ExpertContact fromStorage(String storageFormat) {
        if (StringUtils.isBlank(storageFormat)) {
            return empty();
        }
        // 解析存储格式（JSON）
        List<ContactItem> items = parseStorageFormat(storageFormat);
        return items.isEmpty() ? empty() : new ExpertContact(items);
    }
    
    /**
     * 转换为存储格式（供基础设施层使用）
     */
    public String toStorageFormat() {
        if (items.isEmpty()) {
            return null;
        }
        try {
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            String json = mapper.writeValueAsString(items);
            if (json.length() > MAX_LENGTH) {
                throw new ServiceException("联系方式长度不能超过" + MAX_LENGTH + "个字符");
            }
            return json;
        } catch (Exception e) {
            throw new ServiceException("联系方式序列化失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取联系方式项列表（不可变）
     */
    public List<ContactItem> getItems() {
        return items;
    }
    
    /**
     * 是否为空
     */
    public boolean isEmpty() {
        return items.isEmpty();
    }
    
    /**
     * 数量
     */
    public int size() {
        return items.size();
    }
    
    private static List<ContactItem> parseStorageFormat(String storageFormat) {
        try {
            com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
            return mapper.readValue(storageFormat, new com.fasterxml.jackson.core.type.TypeReference<List<ContactItem>>() {});
        } catch (Exception e) {
            throw new ServiceException("联系方式格式错误: " + e.getMessage());
        }
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ExpertContact that = (ExpertContact) o;
        return Objects.equals(items, that.items);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(items);
    }
    
    @Override
    public String toString() {
        return "ExpertContact" + items;
    }
    
    /**
     * 联系方式项
     */
    public static class ContactItem {
        private String type;
        private String label;
        private String value;
        
        public ContactItem() {
        }
        
        public ContactItem(String type, String label, String value) {
            this.type = type;
            this.label = label;
            this.value = value;
        }
        
        public String getType() {
            return type;
        }
        
        public void setType(String type) {
            this.type = type;
        }
        
        public String getLabel() {
            return label;
        }
        
        public void setLabel(String label) {
            this.label = label;
        }
        
        public String getValue() {
            return value;
        }
        
        public void setValue(String value) {
            this.value = value;
        }
        
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            ContactItem that = (ContactItem) o;
            return Objects.equals(type, that.type) &&
                   Objects.equals(label, that.label) &&
                   Objects.equals(value, that.value);
        }
        
        @Override
        public int hashCode() {
            return Objects.hash(type, label, value);
        }
        
        @Override
        public String toString() {
            return "ContactItem{type='" + type + "', label='" + label + "', value='" + value + "'}";
        }
    }
}