package com.yhy.module.core.dal.dataobject.workbench;

import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.yhy.module.core.dal.typehandler.PostgreSQLBigintArrayTypeHandler;
import com.yhy.module.core.dal.typehandler.PostgreSQLJsonbTypeHandler;
import com.yhy.module.core.dal.typehandler.PostgreSQLTextArrayTypeHandler;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * 工作台项目管理树 DO
 * 节点类型：directory-目录, project-项目
 * 目录节点只需要名称，项目节点包含完整业务字段
 *
 * @author yhy
 */
@TableName(value = "yhy_wb_project_tree", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WbProjectTreeDO extends BaseDO {

    /**
     * 主键ID
     */
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 租户ID
     */
    private Long tenantId;

    /**
     * 父节点ID
     */
    private Long parentId;

    /**
     * 节点类型：directory-目录, project-项目
     */
    private String nodeType;

    /**
     * 名称（目录名称或项目名称）
     */
    private String name;

    /**
     * 项目编号（仅项目节点，手动录入）
     */
    private String projectCode;

    /**
     * 行业-省市（仅项目节点）
     */
    private Long industryProvinceId;

    /**
     * 行业（仅项目节点）
     */
    private Long industryId;

    /**
     * 信息价专业叶子节点ID（仅项目节点）
     */
    private Long infoPriceProfessionId;

    /**
     * 信息价专业完整路径（仅项目节点）
     */
    @TableField(typeHandler = PostgreSQLBigintArrayTypeHandler.class)
    private Long[] infoPriceProfessionPath;

    /**
     * 信息价地区叶子节点ID（仅项目节点）
     */
    private Long infoPriceRegionId;

    /**
     * 信息价地区完整路径（仅项目节点）
     */
    @TableField(typeHandler = PostgreSQLBigintArrayTypeHandler.class)
    private Long[] infoPriceRegionPath;

    /**
     * 信息价册ID（仅项目节点）
     */
    private Long infoPriceBookId;

    /**
     * 工作内容（仅项目节点，字典：wb_work_content）
     */
    private String workContent;

    /**
     * 文件类型（仅项目节点，字典：wb_file_type）
     */
    private String fileType;

    /**
     * 参与人员ID数组（仅项目节点）
     */
    @TableField(typeHandler = PostgreSQLBigintArrayTypeHandler.class)
    private Long[] memberIds;

    /**
     * 项目状态（仅项目节点）：draft-草稿, active-进行中, archived-已归档
     */
    private String status;

    /**
     * 备注
     */
    private String remark;

    /**
     * 是否已保存至历史库
     */
    private Boolean inHistoryLibrary;

    /**
     * 排序号
     */
    private Integer sortOrder;

    /**
     * 层级路径（ID数组）
     */
    @TableField(typeHandler = PostgreSQLTextArrayTypeHandler.class)
    private String[] path;

    /**
     * 快照数据（仅项目节点，创建时的引用数据快照）
     */
    @TableField(typeHandler = PostgreSQLJsonbTypeHandler.class)
    private Map<String, Object> snapshotJson;

    /**
     * 扩展属性（JSONB）
     */
    @TableField(typeHandler = PostgreSQLJsonbTypeHandler.class)
    private Map<String, Object> attributes;

    // 节点类型常量
    public static final String NODE_TYPE_DIRECTORY = "directory";
    public static final String NODE_TYPE_PROJECT = "project";

    // 状态常量
    public static final String STATUS_DRAFT = "draft";
    public static final String STATUS_ACTIVE = "active";
    public static final String STATUS_ARCHIVED = "archived";

    // attributes 中的 key 常量
    public static final String ATTR_RATE_MODE_BINDINGS = "rateModeBindings";
    public static final String ATTR_LAST_SELECTED_QUOTA_SPECIALTY = "lastSelectedQuotaSpecialty";

    /**
     * 获取费率模式绑定Map
     * 格式: { "定额专业ID": { "rateModeId": 123, "rateModeName": "xxx", "quotaSpecialtyName": "xxx" } }
     */
    @SuppressWarnings("unchecked")
    public Map<String, Map<String, Object>> getRateModeBindings() {
        if (attributes == null) {
            return new java.util.HashMap<>();
        }
        Object bindings = attributes.get(ATTR_RATE_MODE_BINDINGS);
        if (bindings instanceof Map) {
            return (Map<String, Map<String, Object>>) bindings;
        }
        return new java.util.HashMap<>();
    }

    /**
     * 设置费率模式绑定Map
     */
    public void setRateModeBindings(Map<String, Map<String, Object>> rateModeBindings) {
        if (attributes == null) {
            attributes = new java.util.HashMap<>();
        }
        attributes.put(ATTR_RATE_MODE_BINDINGS, rateModeBindings);
    }

    /**
     * 获取指定定额专业的费率模式ID
     * @param quotaCatalogItemId 定额专业ID
     * @return 费率模式ID，如果未绑定返回null
     */
    public Long getRateModeIdByQuotaSpecialty(Long quotaCatalogItemId) {
        Map<String, Map<String, Object>> bindings = getRateModeBindings();
        Map<String, Object> binding = bindings.get(String.valueOf(quotaCatalogItemId));
        if (binding != null && binding.get("rateModeId") != null) {
            Object rateModeId = binding.get("rateModeId");
            if (rateModeId instanceof Number) {
                return ((Number) rateModeId).longValue();
            }
            if (rateModeId instanceof String) {
                return Long.parseLong((String) rateModeId);
            }
        }
        return null;
    }

    /**
     * 绑定定额专业的费率模式
     * @param quotaCatalogItemId 定额专业ID
     * @param rateModeId 费率模式ID
     * @param rateModeName 费率模式名称（快照用）
     * @param quotaSpecialtyName 定额专业名称（快照用）
     */
    public void bindRateMode(Long quotaCatalogItemId, Long rateModeId, String rateModeName, String quotaSpecialtyName) {
        Map<String, Map<String, Object>> bindings = getRateModeBindings();
        Map<String, Object> binding = bindings.getOrDefault(String.valueOf(quotaCatalogItemId), new java.util.HashMap<>());
        // 使用字符串存储大整数ID，避免JavaScript精度丢失
        binding.put("rateModeId", String.valueOf(rateModeId));
        binding.put("rateModeName", rateModeName);
        binding.put("quotaSpecialtyName", quotaSpecialtyName);
        binding.put("bindTime", java.time.LocalDateTime.now().toString());
        bindings.put(String.valueOf(quotaCatalogItemId), binding);
        setRateModeBindings(bindings);
    }

    /**
     * 绑定定额专业的费率模式并锁定
     * @param quotaCatalogItemId 定额专业ID
     * @param rateModeId 费率模式ID
     * @param rateModeName 费率模式名称（快照用）
     * @param quotaSpecialtyName 定额专业名称（快照用）
     * @param lockedByUnitId 锁定时的单位工程ID
     */
    public void bindAndLockRateMode(Long quotaCatalogItemId, Long rateModeId, String rateModeName, 
                                     String quotaSpecialtyName, Long lockedByUnitId) {
        Map<String, Map<String, Object>> bindings = getRateModeBindings();
        Map<String, Object> binding = bindings.getOrDefault(String.valueOf(quotaCatalogItemId), new java.util.HashMap<>());
        // 使用字符串存储大整数ID，避免JavaScript精度丢失
        binding.put("rateModeId", String.valueOf(rateModeId));
        binding.put("rateModeName", rateModeName);
        binding.put("quotaSpecialtyName", quotaSpecialtyName);
        binding.put("bindTime", java.time.LocalDateTime.now().toString());
        binding.put("isLocked", true);
        binding.put("lockedByUnitId", lockedByUnitId != null ? String.valueOf(lockedByUnitId) : null);
        bindings.put(String.valueOf(quotaCatalogItemId), binding);
        setRateModeBindings(bindings);
    }

    /**
     * 检查指定定额专业是否已锁定
     * @param quotaCatalogItemId 定额专业ID
     * @return 是否已锁定
     */
    public boolean isRateModeLocked(Long quotaCatalogItemId) {
        Map<String, Map<String, Object>> bindings = getRateModeBindings();
        Map<String, Object> binding = bindings.get(String.valueOf(quotaCatalogItemId));
        if (binding != null) {
            Object isLocked = binding.get("isLocked");
            return Boolean.TRUE.equals(isLocked);
        }
        return false;
    }

    /**
     * 获取指定定额专业的完整绑定信息
     * @param quotaCatalogItemId 定额专业ID
     * @return 绑定信息Map，如果未绑定返回null
     */
    public Map<String, Object> getRateModeBinding(Long quotaCatalogItemId) {
        Map<String, Map<String, Object>> bindings = getRateModeBindings();
        return bindings.get(String.valueOf(quotaCatalogItemId));
    }

    /**
     * 保存费率覆写值
     * @param quotaCatalogItemId 定额专业ID
     * @param rateSettings 费率覆写值 { "rateItemId": { "fieldIndex": "value" } }
     */
    @SuppressWarnings("unchecked")
    public void saveRateSettings(Long quotaCatalogItemId, Map<String, Object> rateSettings) {
        Map<String, Map<String, Object>> bindings = getRateModeBindings();
        Map<String, Object> binding = bindings.getOrDefault(String.valueOf(quotaCatalogItemId), new java.util.HashMap<>());
        binding.put("rateSettings", rateSettings);
        bindings.put(String.valueOf(quotaCatalogItemId), binding);
        setRateModeBindings(bindings);
    }

    /**
     * 保存取费覆写值
     * @param quotaCatalogItemId 定额专业ID
     * @param feeSettings 取费覆写值 { "feeItemId": { "name": "xxx", ... } }
     */
    @SuppressWarnings("unchecked")
    public void saveFeeSettings(Long quotaCatalogItemId, Map<String, Object> feeSettings) {
        Map<String, Map<String, Object>> bindings = getRateModeBindings();
        Map<String, Object> binding = bindings.getOrDefault(String.valueOf(quotaCatalogItemId), new java.util.HashMap<>());
        binding.put("feeSettings", feeSettings);
        bindings.put(String.valueOf(quotaCatalogItemId), binding);
        setRateModeBindings(bindings);
    }

    /**
     * 获取费率覆写值
     * @param quotaCatalogItemId 定额专业ID
     * @return 费率覆写值Map
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> getRateSettings(Long quotaCatalogItemId) {
        Map<String, Object> binding = getRateModeBinding(quotaCatalogItemId);
        if (binding != null && binding.get("rateSettings") instanceof Map) {
            return (Map<String, Object>) binding.get("rateSettings");
        }
        return new java.util.HashMap<>();
    }

    /**
     * 获取取费覆写值
     * @param quotaCatalogItemId 定额专业ID
     * @return 取费覆写值Map
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> getFeeSettings(Long quotaCatalogItemId) {
        Map<String, Object> binding = getRateModeBinding(quotaCatalogItemId);
        if (binding != null && binding.get("feeSettings") instanceof Map) {
            return (Map<String, Object>) binding.get("feeSettings");
        }
        return new java.util.HashMap<>();
    }

    /**
     * 获取用户上次选择的定额专业ID
     * @return 定额专业ID，如果未设置返回null
     */
    public Long getLastSelectedQuotaSpecialty() {
        if (attributes == null) {
            return null;
        }
        Object value = attributes.get(ATTR_LAST_SELECTED_QUOTA_SPECIALTY);
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        if (value instanceof String) {
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 设置用户上次选择的定额专业ID
     * @param quotaCatalogItemId 定额专业ID
     */
    public void setLastSelectedQuotaSpecialty(Long quotaCatalogItemId) {
        if (attributes == null) {
            attributes = new java.util.HashMap<>();
        }
        // 使用字符串存储，避免大整数精度丢失
        attributes.put(ATTR_LAST_SELECTED_QUOTA_SPECIALTY, quotaCatalogItemId != null ? String.valueOf(quotaCatalogItemId) : null);
    }
}
