package com.ruoyi.ibs.list.service;

import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.ibs.list.domain.FamilyMember;
import com.ruoyi.ibs.list.domain.RelationPath;
import com.ruoyi.ibs.list.mapper.FamilyMemberMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author he
 * @date 2025-03-03 22:46
 */
@Service
public class FamilyPathService {
  @Autowired
  private FamilyMemberMapper memberMapper;
  @Resource
  RedisCache redisCache;


  public Map<String, RelationPath> findAllPaths(String rootId) {
    Map<String, RelationPath> pathMap = new HashMap<>();
    Queue<String> queue = new LinkedList<>();

    // 初始化根节点
    //FamilyMember root = memberMapper.getMemberByIdCard(rootId);
    RelationPath rootPath = new RelationPath();
    rootPath.addStep(rootId, "自己");
    pathMap.put(rootId, rootPath);
    queue.add(rootId);
    Map<String,String> relationShipMap = getRelationShipMap();

    while (!queue.isEmpty()) {
      String currentId = queue.poll();
      FamilyMember current = memberMapper.getMemberByIdCard(currentId);

      // 获取所有关联成员ID
      Set<String> relatedIds = getRelatedIds(current);

      for (String relatedId : relatedIds) {
        if (!pathMap.containsKey(relatedId)) {
          FamilyMember related = memberMapper.getMemberByIdCard(relatedId);
          RelationPath newPath = clonePath(pathMap.get(currentId));

          // 计算关系称呼
          String title = getRelationTitle(current, related);
          newPath.addStep(relatedId, title);
          String titleFinal = titleConversion(newPath.getTitleChain(),relationShipMap);
          newPath.setTitleFinal(titleFinal);
          pathMap.put(relatedId, newPath);
          queue.add(relatedId);
        }
      }
    }
    return pathMap;
  }

  private Set<String> getRelatedIds(FamilyMember member) {
    Set<String> ids = new HashSet<>();
    if (member==null){
      return ids;
    }

    // 添加配偶
    if (StringUtils.isNotBlank(member.getSpouseCard())){
      ids.add(member.getSpouseCard());
    }

    // 添加父母
    if (StringUtils.isNotBlank(member.getFatherCard())) {
      ids.add(member.getFatherCard());
    }
    if (StringUtils.isNotBlank(member.getMotherCard())){
      ids.add(member.getMotherCard());
    }

    // 添加子女
    ids.addAll(memberMapper.selectChildrenIds(member.getIdCard()));

    // 添加兄弟姐妹
    ids.addAll(memberMapper.selectSiblingIds(
         member.getFatherCard(), member.getMotherCard(),member.getIdCard(),member.getBsId()));

    return ids;
  }

  private RelationPath clonePath(RelationPath original) {
    RelationPath newPath = new RelationPath();
    newPath.getMemberChain().addAll(original.getMemberChain());
    newPath.getTitleChain().addAll(original.getTitleChain());
    return newPath;
  }

  public   String getRelationTitle(FamilyMember from, FamilyMember to) {
    // 配偶关系
    if (from==null||to==null){
      return "未知亲属";
    }
    if (from.getSpouseCard()!=null&&to.getIdCard().equals(from.getSpouseCard())) {
      if ("M".equals(from.getGender())){
        return "妻子";
      }
      return "丈夫";
    }

    // 父母关系
    if (to.getIdCard().equals(from.getFatherCard())) return "父亲";
    if (to.getIdCard().equals(from.getMotherCard())) return "母亲";

    // 子女关系
    if (isChild(to, from)) {
      return "M".equals(to.getGender()) ? "儿子" : "女儿";
    }

    // 兄弟姐妹
    if (isSibling(from, to)) {
      return compareSiblingAge(from, to);
    }

    // 祖孙关系（递归判断）
    if (isGrandparent(from, to)) return to.getGender().equals("M") ? "祖父" : "祖母";
    if (isGrandchild(from, to)) return to.getGender().equals("M") ? "孙子" : "孙女";

    return "未知亲属";
  }

  public String titleConversion(List<String> titleChain,Map<String,String> relationshipMap){
    String call = "";
    for (int i = 1; i < titleChain.size(); i++) {
      if (titleChain.get(i).equals("父亲")){
        call = call+","+"f";
      } else if (titleChain.get(i).equals("母亲")) {
        call = call+","+"m";
      } else if (titleChain.get(i).equals("儿子")) {
        call = call+","+"s";
      } else if (titleChain.get(i).equals("女儿")) {
        call = call+","+"d";
      } else if (titleChain.get(i).equals("哥哥")) {
        call = call+","+"bb";
      } else if (titleChain.get(i).equals("姐姐")) {
        call = call+","+"bs";
      } else if (titleChain.get(i).equals("弟弟")) {
        call = call+","+"sb";
      } else if (titleChain.get(i).equals("妹妹")) {
        call = call+","+"ss";
      } else if (titleChain.get(i).equals("妻子")) {
        call = call+","+"w";
      } else if (titleChain.get(i).equals("丈夫")) {
        call = call+","+"h";
      }

    }
    if (call.startsWith(",")){
      call = call.substring(1);
    }

    return  relationshipMap.get(call);
  }

  public Map<String, String> getRelationShipMap() {

    Map<String,String> params = new HashMap<>();
    ArrayList<SysDictData> sysDictTypeArrayList = new ArrayList<SysDictData>(redisCache.getCacheObject("sys_dict:family_relation"));
    sysDictTypeArrayList.forEach(sdt -> {
      params.put(sdt.getDictValue(), sdt.getDictLabel());
    });
    return params;
  }



  private static boolean isChild(FamilyMember child, FamilyMember parent) {
    return parent.getIdCard().equals(child.getFatherCard()) ||
        parent.getIdCard().equals(child.getMotherCard());
  }

  private static boolean isSibling(FamilyMember a, FamilyMember b) {
    return (a.getMotherCard() != null && a.getMotherCard().equals(b.getMotherCard())) ||
        (a.getFatherCard() != null && a.getFatherCard().equals(b.getFatherCard())||(a.getBsId()!=null&&b.getBsId()!=null&&a.getBsId().equals(b.getBsId())));
  }

  private static String compareSiblingAge(FamilyMember a, FamilyMember b) {
    if (a.getAge()<b.getAge()) {
      return b.getGender().equals("M") ? "哥哥" : "姐姐";
    }
    return b.getGender().equals("M") ? "弟弟" : "妹妹";
  }

  private  boolean isGrandparent(FamilyMember descendant, FamilyMember ancestor) {
    // 实现递归查询父辈关系
    FamilyMember parent = getParent(descendant);
    if (parent == null) return false;
    return parent.getIdCard().equals(ancestor.getIdCard()) ||
        isGrandparent(parent, ancestor);
  }

  private  FamilyMember getParent(FamilyMember member) {
    if (member.getFatherCard() != null) {
      return memberMapper.getMemberByIdCard(member.getFatherCard());
    }
    return memberMapper.getMemberByIdCard(member.getMotherCard());
  }

  // 判断孙辈关系（递归查询子辈）
  private  boolean isGrandchild(FamilyMember a, FamilyMember b) {
    List<FamilyMember> children = memberMapper.getChildrenByAnyParent(a.getIdCard());
    for (FamilyMember child : children) {
      List<FamilyMember> grandchildren = memberMapper.getChildrenByAnyParent(child.getIdCard());
      if (grandchildren.stream().anyMatch(gc -> gc.getIdCard().equals(b.getIdCard()))) {
        return true;
      }
    }
    return false;
  }
}
