import * as XLSX from 'xlsx';
import type { DataRecord, ParsedData } from './templateTypes';

function sheetRowsToRecords(rows: unknown[][]): DataRecord[] {
  if (rows.length < 2) return [];
  const headers = rows[0].map((h) => String(h ?? '').trim());
  const records: DataRecord[] = [];
  for (let i = 1; i < rows.length; i++) {
    const row = rows[i];
    const rec: DataRecord = {};
    let empty = true;
    headers.forEach((key, j) => {
      if (!key) return;
      const cell = row[j];
      const v = cell == null ? '' : cell;
      if (v !== '' && v != null) empty = false;
      rec[key] = typeof v === 'number' || typeof v === 'boolean' ? v : String(v);
    });
    if (!empty) records.push(rec);
  }
  return records;
}

function parseCsv(text: string): DataRecord[] {
  const lines = text.split(/\r?\n/).filter((l) => l.trim().length > 0);
  if (lines.length < 2) return [];
  const split = (line: string) => {
    const out: string[] = [];
    let cur = '';
    let q = false;
    for (let i = 0; i < line.length; i++) {
      const c = line[i];
      if (c === '"') {
        q = !q;
      } else if ((c === ',' && !q) || (c === ';' && !q)) {
        out.push(cur.trim());
        cur = '';
      } else {
        cur += c;
      }
    }
    out.push(cur.trim());
    return out;
  };
  const headers = split(lines[0]);
  const records: DataRecord[] = [];
  for (let i = 1; i < lines.length; i++) {
    const cells = split(lines[i]);
    const rec: DataRecord = {};
    headers.forEach((h, j) => {
      if (h) rec[h] = cells[j] ?? '';
    });
    records.push(rec);
  }
  return records;
}

export async function parseDataFile(file: File): Promise<ParsedData> {
  const name = file.name.toLowerCase();
  if (name.endsWith('.json')) {
    const text = await file.text();
    const parsed = JSON.parse(text) as unknown;
    const records = Array.isArray(parsed) ? (parsed as DataRecord[]) : [parsed as DataRecord];
    return { format: 'json', records };
  }
  if (name.endsWith('.csv')) {
    const text = await file.text();
    return { format: 'csv', records: parseCsv(text) };
  }
  if (name.endsWith('.xlsx') || name.endsWith('.xls')) {
    const buf = await file.arrayBuffer();
    const wb = XLSX.read(buf, { type: 'array' });
    const sheetName = wb.SheetNames[0];
    const sheet = wb.Sheets[sheetName];
    const rows = XLSX.utils.sheet_to_json<unknown[]>(sheet, { header: 1, raw: true }) as unknown[][];
    return { format: 'xlsx', records: sheetRowsToRecords(rows) };
  }
  throw new Error('Unsupported data format (use .json, .csv, .xlsx)');
}
