// 使用Intl.Segmenter对中文文本进行分词
function segmentText(text) {
  const segmenter = new Intl.Segmenter('zh-Hans', {
    granularity: 'word',
  }); // 使用中文简体语言
  const segments = [];
  for (let segment of segmenter.segment(text.toLowerCase())) {
    // 转为小写后进行分词
    segments.push(segment.segment);
  }
  return segments;
}

// 语气 停用次
const stopWords = [
  '的',
  '了',
  '啊',
  '哦',
  '/',
  '、',
  ' ',
  '',
  '-',
  '（',
  '）',
  '(',
  ')',
  '+',
  '=',
  '~',
  '!',
  '<',
  '>',
  '?',
  '[',
  ']',
  '{',
  '}',
];

function cleanKeywords(arr) {
  return arr.filter((word) => word && !stopWords.includes(word));
}

function calculateMatchScore(source, target) {
  const sourceSet = new Set(cleanKeywords(source));
  const targetSet = new Set(cleanKeywords(target));
  let matchCount = 0;
  for (let word of sourceSet) {
    if (targetSet.has(word)) {
      matchCount++;
    }
  }

  // 匹配度 = source中匹配到的词 / source总词数
  return matchCount / sourceSet.size;
}

class CsimilarityJobs {
  config = {
    thresholdVal: 0.69,
    titleSimilarityWeight: 0.4,
    salaryMatchWeight: 0.2,
    areaMatchWeight: 0.2,
    educationMatchWeight: 0.2,
    experiencenMatchWeight: 0.1,
  };
  userTitle = ['Java', 'C', '全栈工程师'];
  userSalaryMin = 10000;
  userSalaryMax = 15000;
  userArea = 0; // 用户指定的区域（例如：市南区）
  userEducation = 4; // 用户学历（假设4为本科）
  userExperience = 2; // 用户工作经验

  jobTitle = '';
  jobMinSalary = 10000;
  jobMaxSalary = 15000;
  jobLocationAreaCode = 0;
  jobEducation = 4;
  jobExperience = 2;
  jobCategory = '';
  // 系统
  log = false;

  constructor() {}

  setUserInfo(resume) {
    this.userTitle = resume.jobTitle;
    this.userSalaryMax = Number(resume.salaryMax);
    this.userSalaryMin = Number(resume.salaryMin);
    this.userArea = Number(resume.area);
    this.userEducation = resume.education;
    this.userExperience = this.getUserExperience(Number(resume.age));
  }

  setJobInfo(jobInfo) {
    this.jobTitle = jobInfo.jobTitle;
    this.jobMinSalary = jobInfo.minSalary;
    this.jobMaxSalary = jobInfo.maxSalary;
    this.jobLocationAreaCode = jobInfo.jobLocationAreaCode;
    this.jobEducation = jobInfo.education;
    this.jobExperience = jobInfo.experience;
    this.jobCategory = jobInfo.jobCategory;
  }

  calculationMatchingDegreeJob(resume) {
    // 计算职位标题相似度
    // const titleSimilarity = stringSimilarity.compareTwoStrings(this.userTitle, job.jobTitle);
    let jobT = null;
    if (this.jobCategory) {
      jobT = this.calculateBestJobCategoryMatch(
        resume.jobTitle || resume.jobTitleString || [],
        this.jobCategory,
      );
    } else {
      jobT = this.calculateBestJobMatch(
        resume.jobTitle || resume.jobTitleString || [],
        this.jobTitle,
      );
    }
    const { bestMatchJobTitle, maxSimilarity } = jobT;

    // 计算薪资匹配度
    const salaryMatch = this.calculateSalaryMatch(
      Number(resume.salaryMin),
      Number(resume.salaryMax),
      this.jobMinSalary,
      this.jobMaxSalary,
    );

    // 计算区域匹配度
    const areaMatch = this.calculateAreaMatch(Number(resume.area), this.jobLocationAreaCode);

    // 计算学历匹配度
    const educationMatch = this.calculateEducationMatch(resume.education, this.jobEducation);

    // 计算工作经验匹配度
    // const experiencenMatch = this.calculateExperienceMatch2(this.userExperience, job.experience);

    // 综合匹配度 = 0.4 * 职位相似度 + 0.2 * 薪资匹配度 + 0.1 * 区域匹配度 + 0.2 * 学历匹配度 + 0.1 * 工作经验匹配度
    const overallMatch =
      this.config.titleSimilarityWeight * maxSimilarity +
      this.config.salaryMatchWeight * salaryMatch +
      this.config.areaMatchWeight * areaMatch +
      this.config.educationMatchWeight * educationMatch;
    // console.log(`Job ${job.jobTitle}工作经验匹配度: ${experiencenMatch}`);
    if (this.log) {
      console.log(
        `Job ${job.jobTitle} 标题相似度 ${maxSimilarity} 薪资匹配度: ${salaryMatch}学历匹配度: ${educationMatch} 区域匹配度: ${areaMatch} 综合匹配度: ${overallMatch.toFixed(2)}`,
      );
    }

    // 设置阈值进行岗位匹配判断
    const threshold = this.config.thresholdVal;
    return {
      overallMatch: overallMatch.toFixed(2) * 100 + '%',
      data: resume,
      maxSimilarity,
      salaryMatch,
      educationMatch,
      areaMatch,
    };
  }

  calculationMatchingDegree(job) {
    // 计算职位标题相似度
    // console.log(this.userTitle, job.jobTitle)
    // const titleSimilarity = stringSimilarity.compareTwoStrings(this.userTitle, job.jobTitle);
    let jobT = null;
    if (job.jobCategory) {
      jobT = this.calculateBestJobCategoryMatch(this.userTitle, job.jobCategory);
    } else {
      jobT = this.calculateBestJobMatch(this.userTitle, job.jobTitle);
    }
    const { bestMatchJobTitle, maxSimilarity } = jobT;
    // 计算薪资匹配度
    const salaryMatch = this.calculateSalaryMatch(
      this.userSalaryMin,
      this.userSalaryMax,
      job.minSalary,
      job.maxSalary,
    );

    // 计算区域匹配度
    const areaMatch = this.calculateAreaMatch(this.userArea, job.jobLocationAreaCode);

    // 计算学历匹配度
    const educationMatch = this.calculateEducationMatch(this.userEducation, job.education);

    // 计算工作经验匹配度
    // const experiencenMatch = this.calculateExperienceMatch2(this.userExperience, job.experience);

    // 综合匹配度 = 0.4 * 职位相似度 + 0.2 * 薪资匹配度 + 0.1 * 区域匹配度 + 0.2 * 学历匹配度 + 0.1 * 工作经验匹配度
    const overallMatch =
      this.config.titleSimilarityWeight * maxSimilarity +
      this.config.salaryMatchWeight * salaryMatch +
      this.config.areaMatchWeight * areaMatch +
      this.config.educationMatchWeight * educationMatch;
    // console.log(`Job ${job.jobTitle}工作经验匹配度: ${experiencenMatch}`);
    if (this.log) {
      console.log(
        `Job ${job.jobTitle} 标题相似度 ${maxSimilarity} 薪资匹配度: ${salaryMatch}学历匹配度: ${educationMatch} 区域匹配度: ${areaMatch} 综合匹配度: ${overallMatch.toFixed(2)}`,
      );
    }

    // 设置阈值进行岗位匹配判断
    const threshold = this.config.thresholdVal;
    if (overallMatch > threshold) {
      return {
        overallMatch: overallMatch.toFixed(2) * 100 + '%',
        data: job,
        maxSimilarity,
        salaryMatch,
        educationMatch,
        areaMatch,
      };
    }
  }

  // 根据用户年龄推算工作经验年限区间
  getUserExperience(age) {
    if ((age = 0)) {
      // 30以下
      return {
        min: 0,
        max: 5,
      };
    } else if (age <= 1) {
      // 40以下
      return {
        min: 5,
        max: 10,
      };
    } else if (age <= 2) {
      // 50以下
      return {
        min: 10,
        max: 20,
      };
    } else {
      // 50以上
      return {
        min: 20,
        max: 40,
      };
    }
  }

  // 计算经验匹配度
  calculateExperienceMatch2(userExperience, jobExperience) {
    const jobExperienceRange = this.mapJobExperience(jobExperience);

    if (
      userExperience.min <= jobExperienceRange.max &&
      userExperience.max >= jobExperienceRange.min
    ) {
      return 1;
    }

    if (
      (userExperience.min <= jobExperienceRange.max &&
        userExperience.max > jobExperienceRange.min) ||
      (userExperience.max >= jobExperienceRange.min && userExperience.min < jobExperienceRange.max)
    ) {
      return 0.5; // 部分匹配
    }
    return 0; // 不匹配
  }

  // 映射岗位经验要求到工作经验年限区间
  mapJobExperience(jobExperience) {
    const experienceMapping = {
      1: {
        min: 0,
        max: 0,
      },
      2: {
        min: 0,
        max: 1,
      },
      3: {
        min: 0,
        max: 1,
      },
      4: {
        min: 1,
        max: 3,
      },
      5: {
        min: 3,
        max: 5,
      },
      6: {
        min: 5,
        max: 10,
      },
      7: {
        min: 10,
        max: 20,
      },
      8: {
        min: 0,
        max: 40,
      },
    };
    return experienceMapping[jobExperience];
  }

  // 计算工作经验匹配度
  calculateExperiencenMatch(userExperience, jobExperience) {
    if (userExperience === jobExperience) {
      return 1;
    } else if (userExperience > jobExperience) {
      return 0.75;
    } else {
      return 0;
    }
  }

  calculateSalaryMatch(userMin, userMax, jobMin, jobMax) {
    const isMinMatch = userMin >= jobMin && userMin <= jobMax;
    const isMaxMatch = userMax >= jobMin && userMax <= jobMax;

    if (isMinMatch || isMaxMatch) {
      return 1;
    }

    const minDifference = Math.abs(userMin - jobMin);
    const maxDifference = Math.abs(userMax - jobMax);

    if (minDifference > 3000 && maxDifference > 3000) {
      return 0;
    }

    return 0.5; // 部分匹配
  }

  // 计算区域匹配度
  calculateAreaMatch(userArea, jobArea) {
    return userArea === jobArea ? 1 : 0.5;
  }

  calculateBestJobCategoryMatch(userJobTitles, jobTitle) {
    let maxSimilarity = 0;
    let bestMatchJobTitle = '';
    for (let i = 0; i < userJobTitles.length; i++) {
      let userTitle = userJobTitles[i];
      if (userTitle === jobTitle) {
        maxSimilarity = 1;
        bestMatchJobTitle = userTitle;
        break;
      }
    }
    return {
      bestMatchJobTitle,
      maxSimilarity,
    };
  }

  // 计算职位匹配度
  calculateBestJobMatch(userJobTitles, jobTitle) {
    let maxSimilarity = 0;
    let bestMatchJobTitle = '';

    userJobTitles.forEach((userTitle) => {
      const userSegments = segmentText(userTitle);
      const jobSegments = segmentText(jobTitle);
      // 比较分词的交集，计算匹配度
      // const intersection = userSegments.filter(segment => jobSegments.includes(segment));
      // const similarity = intersection.length / userSegments.length; // 计算匹配度
      // 计算匹配度
      const similarity = calculateMatchScore(userSegments, jobSegments);
      // 记录匹配度最高的职位
      if (similarity > maxSimilarity) {
        maxSimilarity = similarity;
        bestMatchJobTitle = userTitle;
      }
    });

    return {
      bestMatchJobTitle,
      maxSimilarity,
    };
  }

  // 计算学历匹配度
  calculateEducationMatch(userEducation, jobEducation) {
    if (userEducation === jobEducation) {
      return 1;
    } else if (userEducation > jobEducation) {
      return 1;
    } else {
      return 0;
    }
  }
}

const similarityJobs = new CsimilarityJobs();

export default similarityJobs;
