export const readTextFile = (file: File): Promise<string> =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(String(reader.result || ""));
    reader.onerror = () => reject(reader.error || new Error("文件读取失败"));
    reader.readAsText(file, "utf-8");
  });

export const downloadCsvTemplate = (fileName: string, headers: string[], sampleRows: string[][] = []) => {
  downloadCsvRows(fileName, [headers, ...sampleRows]);
};

export const downloadCsvRows = (fileName: string, rows: string[][]) => {
  const csv = toCsv(rows);
  const blob = new Blob([`\uFEFF${csv}`], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement("a");
  anchor.href = url;
  anchor.download = fileName;
  anchor.click();
  URL.revokeObjectURL(url);
};

export const parseDelimitedText = (text: string): string[][] => {
  const normalized = String(text || "").replace(/^\uFEFF/, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
  if (!normalized.trim()) {
    return [];
  }
  const firstLine = normalized.split("\n").find((line) => line.trim().length > 0) || "";
  const delimiter = firstLine.includes("\t") ? "\t" : ",";
  return parseWithDelimiter(normalized, delimiter)
    .map((row) => row.map((cell) => cell.trim()))
    .filter((row) => row.some((cell) => cell.length > 0));
};

export const findMissingHeaders = (headerRow: string[], requiredHeaders: string[]): string[] => {
  const existing = new Set(headerRow.map((item) => String(item || "").trim()));
  return requiredHeaders.filter((header) => !existing.has(header));
};

const toCsv = (rows: string[][]): string =>
  rows
    .map((row) => row.map(escapeCell).join(","))
    .join("\r\n");

const escapeCell = (value: string): string => {
  const text = String(value ?? "");
  if (/[",\r\n]/.test(text)) {
    return `"${text.replace(/"/g, "\"\"")}"`;
  }
  return text;
};

const parseWithDelimiter = (text: string, delimiter: string): string[][] => {
  const rows: string[][] = [];
  let currentRow: string[] = [];
  let currentCell = "";
  let insideQuotes = false;

  for (let i = 0; i < text.length; i += 1) {
    const char = text[i];
    const next = text[i + 1];

    if (char === "\"") {
      if (insideQuotes && next === "\"") {
        currentCell += "\"";
        i += 1;
      } else {
        insideQuotes = !insideQuotes;
      }
      continue;
    }

    if (!insideQuotes && char === delimiter) {
      currentRow.push(currentCell);
      currentCell = "";
      continue;
    }

    if (!insideQuotes && char === "\n") {
      currentRow.push(currentCell);
      rows.push(currentRow);
      currentRow = [];
      currentCell = "";
      continue;
    }

    currentCell += char;
  }

  currentRow.push(currentCell);
  rows.push(currentRow);
  return rows;
};
