import axios from "axios";
import { getRandomOffset } from "@/utils/others/quillutils";
const xml2js = require("xml2js");

// 定义文章详细信息的 TypeScript 接口

// 定义PubMed文章ID为字符串类型
type PubMedID = string;

// 定义idList为PubMedID数组
type IDList = PubMedID[];

async function getPubMedPapers(
  query: string,
  year: number,
  offset = -1,
  limit = 2
) {
  try {
    const baseURL =
      "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi";
    const db = "pubmed"; // 设定搜索的数据库为PubMed
    const retMax = limit; // 检索的最大记录数
    const maxOffset = 20 - limit; // 假设总记录数为 20
    if (offset === -1) offset = getRandomOffset(maxOffset);
    const url = `${baseURL}?db=${db}&term=${query}[Title/Abstract]+AND+${year}:3000[Date - Publication]&retMax=${retMax}&retStart=${offset}&api_key=${process.env.NEXT_PUBLIC_PUBMED_API_KEY}`;
    const response = await axios.get(url, { responseType: "text" });
    console.log(response.data);
    // 解析XML数据
    const parser = new xml2js.Parser({ explicitArray: false });
    const result = await parser.parseStringPromise(response.data);

    // 提取PubMed文章ID
    const idList = result.eSearchResult.IdList.Id;
    console.log(idList);
    // 可以进一步使用这些ID来获取文章详情，例如使用esummary或efetch
    // 这里只返回了ID列表，你可能需要根据实际需要进行调整
    return idList;
  } catch (error) {
    console.error("Error fetching data from PubMed API:", error);
    return null; // 或根据需要处理错误
  }
}

// 根据文章ID列表获取详细信息
async function getPubMedPaperDetails(idList: IDList) {
  try {
    const ids = idList.join(","); // 将ID列表转换为逗号分隔的字符串
    // const baseURL = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi";
    const baseURL = process.env.NEXT_PUBLIC_PAPER_URL; //通过API接口进行转发
    const url = `${baseURL}?db=pubmed&id=${ids}&rettype=abstract&retmode=xml`;
    console.log(url);
    const response = await fetch(url, {
      headers: {
        "Upstream-Url":
          "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi",
        "Accept-Encoding": "identity",
      },
    });

    if (!response.ok) {
      throw new Error(`${response.text()}`);
    }

    const data = await response.text(); // 获取响应文本
    // 解析XML数据
    const parser = new xml2js.Parser({
      explicitArray: false,
      ignoreAttrs: false, // 忽略XML属性
      charkey: "text", // 字符数据的键
      trim: true, // 去除文本前后空格
    });
    let result = await parser.parseStringPromise(data);

    // console.log(result);
    // 提取并处理文章详细信息
    const articles = result.PubmedArticleSet.PubmedArticle.map((article) => {
      const medlineCitation = article.MedlineCitation;
      const articleDetails = medlineCitation.Article;
      // console.log("atricledetails", articleDetails);
      const abstractTexts = articleDetails.Abstract.AbstractText;

      let abstract;
      // 检查 abstractTexts 是否是一个数组
      if (Array.isArray(abstractTexts)) {
        // 如果是数组，遍历数组并连接每个元素的文本
        abstract = abstractTexts
          .map((text) => (typeof text === "object" ? text.text : text))
          .join(" ");
      } else if (typeof abstractTexts === "string") {
        // 如果 abstractTexts 直接就是字符串
        abstract = abstractTexts;
      } else if (typeof abstractTexts === "object") {
        // 将对象中的文本内容连接起来
        abstract = Object.values(abstractTexts).reduce((acc, val) => {
          return (
            acc + (typeof val === "object" && val.text ? val.text : val) + " "
          );
        }, "");
      } else {
        // 如果 abstractTexts 既不是数组也不是字符串，可能设置为默认值或进行错误处理
        abstract = ""; // 或者根据需要设置一个默认的提示文本
      }

      const authors =
        articleDetails.AuthorList &&
        Array.isArray(articleDetails.AuthorList.Author)
          ? articleDetails.AuthorList.Author.map((author) => {
              const names = [];
              if (author.ForeName) names.push(author.ForeName);
              if (author.LastName) names.push(author.LastName);
              return names.join(" ");
            })
          : ["Unknown Author"];

      let publishedDate = "No date available";
      // 尝试从 ArticleDate 获取发表日期
      if (articleDetails.ArticleDate) {
        publishedDate = `${articleDetails.ArticleDate.Year}`;
      }
      // 如果 ArticleDate 不存在，尝试从 JournalIssue/PubDate 获取
      else if (articleDetails.Journal.JournalIssue.PubDate) {
        publishedDate = `${articleDetails.Journal.JournalIssue.PubDate.Year}
        }`;
      }

      let journalTitle = articleDetails.Journal.Title; // 提取出版者信息（杂志标题）
      journalTitle += `, ${publishedDate}`;
      if (articleDetails.Journal.JournalIssue.Volume) {
        journalTitle += `, ${articleDetails.Journal.JournalIssue.Volume}`;
      }
      if (articleDetails.Pagination) {
        journalTitle += `: ${articleDetails.Pagination.StartPage}-${articleDetails.Pagination.EndPage}`;
      }
      // 构建文章的 PubMed URL
      const articleUrl = `https://pubmed.ncbi.nlm.nih.gov/${medlineCitation.PMID.text}/`;
      // console.log("medlineCitation", medlineCitation);
      console.log("\n,journalTitle", journalTitle);
      let title = articleDetails.ArticleTitle;
      // 检查并去除字符串最后的句点
      if (title.endsWith(".")) {
        title = title.slice(0, -1);
      }
      // 提取DOI
      let doi = null;
      if (
        article.PubmedData &&
        article.PubmedData.ArticleIdList &&
        Array.isArray(article.PubmedData.ArticleIdList.ArticleId)
      ) {
        const doiObject = article.PubmedData.ArticleIdList.ArticleId.find(
          (idObj) => idObj.$.IdType === "doi"
        );
        if (doiObject) {
          doi = doiObject.text; // 获取DOI值
        }
      }
      console.log("doi", doi);
      console.log(
        "链接",
        medlineCitation.PMID.text,
        "属性",
        typeof medlineCitation.PMID.text
      );
      return {
        id: Number(medlineCitation.PMID.text),
        title: title,
        abstract: abstract,
        authors: authors,
        url: articleUrl,
        year: publishedDate,
        journal: journalTitle,
        doi: doi,
        // 其他需要的字段可以继续添加
      };
    });

    return articles;
  } catch (error) {
    throw new Error(`Error fetching paper details from PubMed:", ${error}`);
  }
}

// 示例：使用这些函数
async function fetchPubMedData(
  query: string,
  year: number,
  offset: number,
  limit: number
) {
  try {
    const idList = await getPubMedPapers(query, year, offset, limit);
    if (idList && idList.length > 0) {
      const paperDetails = await getPubMedPaperDetails(idList);
      console.log("fetchPubMedData", paperDetails); // 处理或显示文章详情
      return paperDetails;
    }
  } catch (error) {
    //这里无法起作用因为pubmed不会返回400系错误
    throw new Error(`pubmed: ${error}`);
  }
}

export { fetchPubMedData, getPubMedPapers, getPubMedPaperDetails };
