package com.aegis.resource.supplier.domain;

import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import com.aegis.common.core.domain.BaseEntity;
import com.aegis.common.exception.ServiceException;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * 供应商实体类 resource_supplier
 * 
 * @author aegis
 */
@Getter
@Setter
@ToString(callSuper = true)
public class Supplier extends BaseEntity {
    
    private static final long serialVersionUID = 1L;

    /** 供应商ID */
    private Long id;

    /** 供应商编码 */
    private String supplierCode;

    /** 供应商名称 */
    private String supplierName;

    /** 统一社会信用代码 */
    private String creditCode;

    /** 供应商分类 */
    private String category;

    /** 所在区域 */
    private String area;

    /** 联系人 */
    private String contactPerson;

    /** 联系电话 */
    private String contactPhone;

    /** 邮箱 */
    private String email;

    /** 地址 */
    private String address;

    /** 状态：active-启用，inactive-停用，blacklisted-黑名单 */
    private String status;

    /** 评分（1-5星） */
    private Integer rating;

    /** 删除标志（0代表存在 2代表删除） */
    private String delFlag;

    /**
     * 初始化默认值
     * 
     * @param operator 操作人
     */
    public void initializeDefaults(String operator) {
        if (StringUtils.isBlank(this.status)) {
            this.status = SupplierStatus.ACTIVE.getCode();
        }
        if (this.rating == null) {
            this.rating = 5;
        }
    }

    /**
     * 启用供应商
     * 
     * @param operator 操作人
     */
    public void activate(String operator) {
        this.ensureNotDeleted();
        SupplierStatus current = this.getStatusEnum();
        if (current == SupplierStatus.ACTIVE) {
            return; // 已启用，无需重复操作
        }
        if (current == SupplierStatus.INACTIVE || current == SupplierStatus.BLACKLISTED) {
            this.setStatusEnum(SupplierStatus.ACTIVE);
            this.touch(operator);
            return;
        }
        throw new ServiceException("当前状态无法启用: " + current);
    }

    /**
     * 停用供应商
     * 
     * @param operator 操作人
     */
    public void deactivate(String operator) {
        this.ensureNotDeleted();
        SupplierStatus current = this.getStatusEnum();
        if (current == SupplierStatus.INACTIVE) {
            return; // 已停用，无需重复操作
        }
        if (current == SupplierStatus.ACTIVE) {
            this.setStatusEnum(SupplierStatus.INACTIVE);
            this.touch(operator);
            return;
        }
        throw new ServiceException("当前状态无法停用: " + current);
    }

    /**
     * 加入黑名单
     * 
     * @param operator 操作人
     */
    public void blacklist(String operator) {
        this.ensureNotDeleted();
        SupplierStatus current = this.getStatusEnum();
        if (current == SupplierStatus.BLACKLISTED) {
            return; // 已在黑名单，无需重复操作
        }
        if (current == SupplierStatus.ACTIVE || current == SupplierStatus.INACTIVE) {
            this.setStatusEnum(SupplierStatus.BLACKLISTED);
            this.touch(operator);
            return;
        }
        throw new ServiceException("当前状态无法加入黑名单: " + current);
    }

    /**
     * 更新评分
     * 
     * @param rating 评分（1-5）
     * @param operator 操作人
     */
    public void updateRating(Integer rating, String operator) {
        this.ensureNotDeleted();
        if (rating == null || rating < 1 || rating > 5) {
            throw new ServiceException("评分必须在1-5之间");
        }
        this.rating = rating;
        this.touch(operator);
    }

    /**
     * 标记为已删除
     * 
     * @param operator 操作人
     */
    public void markDeleted(String operator) {
        if (this.isDeleted()) {
            return;
        }
        this.delFlag = DEL_FLAG_DELETED;
        this.touch(operator);
    }

    /**
     * 恢复（取消删除）
     * 
     * @param operator 操作人
     */
    public void restore(String operator) {
        if (this.isDeleted()) {
            this.delFlag = DEL_FLAG_NORMAL;
            this.touch(operator);
        }
    }

    /**
     * 修改供应商名称
     * 
     * @param newName 新名称
     * @param operator 操作人
     */
    public void rename(String newName, String operator) {
        if (StringUtils.isBlank(newName)) {
            throw new ServiceException("供应商名称不能为空");
        }
        if (newName.length() > 200) {
            throw new ServiceException("供应商名称长度不能超过200个字符");
        }
        this.supplierName = newName;
        this.touch(operator);
    }

    /**
     * 修改供应商编码
     * 
     * @param newCode 新编码
     * @param operator 操作人
     */
    public void changeCode(String newCode, String operator) {
        if (StringUtils.isBlank(newCode)) {
            throw new ServiceException("供应商编码不能为空");
        }
        if (newCode.length() > 50) {
            throw new ServiceException("供应商编码长度不能超过50个字符");
        }
        this.supplierCode = newCode;
        this.touch(operator);
    }

    /**
     * 修改供应商分类
     * 
     * @param category 分类
     * @param operator 操作人
     */
    public void changeCategory(String category, String operator) {
        if (StringUtils.isNotBlank(category) && category.length() > 64) {
            throw new ServiceException("供应商分类长度不能超过64个字符");
        }
        this.category = category;
        this.touch(operator);
    }

    /**
     * 修改所在区域
     * 
     * @param area 区域
     * @param operator 操作人
     */
    public void changeArea(String area, String operator) {
        if (StringUtils.isNotBlank(area) && area.length() > 100) {
            throw new ServiceException("所在区域长度不能超过100个字符");
        }
        this.area = area;
        this.touch(operator);
    }

    /**
     * 修改联系信息
     * 
     * @param person 联系人
     * @param phone 联系电话
     * @param email 邮箱
     * @param operator 操作人
     */
    public void changeContact(String person, String phone, String email, String operator) {
        if (StringUtils.isNotBlank(person) && person.length() > 64) {
            throw new ServiceException("联系人长度不能超过64个字符");
        }
        if (StringUtils.isNotBlank(phone) && phone.length() > 20) {
            throw new ServiceException("联系电话长度不能超过20个字符");
        }
        if (StringUtils.isNotBlank(email) && email.length() > 100) {
            throw new ServiceException("邮箱长度不能超过100个字符");
        }
        this.contactPerson = person;
        this.contactPhone = phone;
        this.email = email;
        this.touch(operator);
    }

    /**
     * 修改地址
     * 
     * @param address 地址
     * @param operator 操作人
     */
    public void changeAddress(String address, String operator) {
        if (StringUtils.isNotBlank(address) && address.length() > 500) {
            throw new ServiceException("地址长度不能超过500个字符");
        }
        this.address = address;
        this.touch(operator);
    }

    /**
     * 修改备注
     * 
     * @param remark 备注
     * @param operator 操作人
     */
    public void changeRemark(String remark, String operator) {
        if (StringUtils.isNotBlank(remark) && remark.length() > 500) {
            throw new ServiceException("备注长度不能超过500个字符");
        }
        this.setRemark(remark);
        this.touch(operator);
    }

    /**
     * 确保供应商未被删除
     */
    public void ensureNotDeleted() {
        if (this.isDeleted()) {
            throw new ServiceException("已删除的供应商不允许该操作");
        }
    }

    /**
     * 确保供应商不在黑名单
     */
    public void ensureNotBlacklisted() {
        SupplierStatus current = this.getStatusEnum();
        if (current == SupplierStatus.BLACKLISTED) {
            throw new ServiceException("黑名单供应商不允许该操作");
        }
    }

    /**
     * 检查是否已删除
     * 
     * @return 是否已删除
     */
    private boolean isDeleted() {
        return DEL_FLAG_DELETED.equals(delFlag);
    }

    /**
     * 获取状态枚举
     * 
     * @return 状态枚举
     */
    public SupplierStatus getStatusEnum() {
        return SupplierStatus.fromCode(status);
    }

    /**
     * 设置状态枚举
     * 
     * @param supplierStatus 状态枚举
     */
    private void setStatusEnum(SupplierStatus supplierStatus) {
        this.status = supplierStatus.getCode();
    }

    /**
     * 更新操作信息
     * 
     * @param operator 操作人
     */
    private void touch(String operator) {
        this.setUpdateBy(operator);
        this.setUpdateTime(new Date());
    }

    private static final String DEL_FLAG_NORMAL = "0";
    private static final String DEL_FLAG_DELETED = "2";

    /**
     * 供应商状态枚举
     */
    public enum SupplierStatus {
        ACTIVE("active", "启用"),
        INACTIVE("inactive", "停用"),
        BLACKLISTED("blacklisted", "黑名单");

        private final String code;
        private final String label;

        SupplierStatus(String code, String label) {
            this.code = code;
            this.label = label;
        }

        public String getCode() {
            return code;
        }

        public String getLabel() {
            return label;
        }

        public static SupplierStatus fromCode(String code) {
            if (StringUtils.isBlank(code)) {
                return ACTIVE;
            }
            for (SupplierStatus value : values()) {
                if (value.code.equals(code)) {
                    return value;
                }
            }
            return ACTIVE;
        }
    }
}