import { randomUUID } from 'crypto';
import fs from 'fs';
import path from 'path';
import { DatabaseSync } from 'node:sqlite';
import { fileURLToPath } from 'url';
import XLSX from 'xlsx';
import dotenv from 'dotenv';

dotenv.config();

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.join(__dirname, '..');
const xlsxPath = path.join(root, 'Anlagenliste ITT.xlsx');
const dbPath = process.env.SQLITE_PATH || path.join(root, 'data', 'crm.db');

/** Zeile 9 (1-basiert): Spaltenbeschriftung / Feldnamen */
const ZEILE_BESCHREIBUNG = 9;
/** Zeile 7: Gruppierung / übergeordnete Rubrik pro Spalte (z. B. „Kunde“) */
const ZEILE_GRUPPE = 7;
/** Nur Spalten 1–99 importieren; Spalten 100–180 entfallen */
const MAX_SPALTEN = 99;

if (!fs.existsSync(xlsxPath)) {
  console.error('Datei nicht gefunden:', xlsxPath);
  process.exit(1);
}

function dedupeHeaders(raw) {
  const count = {};
  return raw.map((h) => {
    const base = String(h ?? '').trim() || 'Spalte';
    count[base] = (count[base] || 0) + 1;
    return count[base] === 1 ? base : `${base}_${count[base]}`;
  });
}

function padRow(arr, width) {
  const a = Array.isArray(arr) ? [...arr] : [];
  while (a.length < width) a.push('');
  return a.slice(0, width);
}

const wb = XLSX.readFile(xlsxPath);
const sheet =
  wb.Sheets.Anlagen ||
  wb.Sheets[wb.SheetNames.find((n) => /anlagen/i.test(n))] ||
  wb.Sheets[wb.SheetNames[0]];

const aoa = XLSX.utils.sheet_to_json(sheet, { header: 1, defval: '' });
const beschreibIdx = ZEILE_BESCHREIBUNG - 1;
const gruppeIdx = ZEILE_GRUPPE - 1;

let width = 0;
for (const r of [beschreibIdx, gruppeIdx]) {
  if (aoa[r] && aoa[r].length > width) width = aoa[r].length;
}
if (sheet['!ref']) {
  const range = XLSX.utils.decode_range(sheet['!ref']);
  width = Math.max(width, range.e.c + 1);
}

width = Math.min(width, MAX_SPALTEN);

const rawRow9 = padRow(aoa[beschreibIdx] || [], width).map((h) =>
  String(h ?? '').trim(),
);
const rawRow7 = padRow(aoa[gruppeIdx] || [], width).map((h) =>
  String(h ?? '').trim(),
);
const headers = dedupeHeaders(rawRow9);

fs.mkdirSync(path.dirname(dbPath), { recursive: true });
const db = new DatabaseSync(dbPath);
db.exec('PRAGMA foreign_keys = ON');

const cols = db.prepare('PRAGMA table_info(machines)').all();
if (!cols.some((c) => c.name === 'extras')) {
  db.exec('ALTER TABLE machines ADD COLUMN extras TEXT');
}

const replaceAll = process.argv.includes('--replace');
if (replaceAll) {
  db.exec('DELETE FROM events');
  db.exec('DELETE FROM tickets');
  db.exec('DELETE FROM machines');
  console.log('Bestehende Maschinen/Tickets/Events gelöscht.');
}

const insertMachine = db.prepare(
  `INSERT INTO machines (id, name, typ, seriennummer, standort, list_status, extras, updated_at)
   VALUES (?, ?, ?, ?, ?, '', ?, datetime('now'))`,
);

let imported = 0;
let skipped = 0;

db.exec('BEGIN');
try {
  for (let i = beschreibIdx + 1; i < aoa.length; i++) {
    const row = aoa[i];
    if (!row || !row.length) continue;
    const padded = padRow(row, width);
    const sn = String(padded[0] ?? '').trim();
    if (!/^ITT#/i.test(sn)) continue;

    const dup = db
      .prepare('SELECT id FROM machines WHERE seriennummer = ?')
      .get(sn);
    if (dup) {
      skipped += 1;
      continue;
    }

    const rowObj = {};
    headers.forEach((h, j) => {
      const v = padded[j];
      rowObj[h] =
        v === '' || v === undefined || v === null ? '' : String(v).trim();
    });

    const typ = rowObj.Typ || '—';
    const standort =
      [rowObj.Stadt, rowObj.Land].filter(Boolean).join(', ') || '—';

    const werteAlsListe = padded.map((v) =>
      v === '' || v === undefined || v === null ? '' : String(v).trim(),
    );

    const extrasObj = {
      _beschriftungZeile9: rawRow9,
      _gruppeZeile7: rawRow7,
      _werteAlsListe: werteAlsListe,
      ...rowObj,
    };

    const extrasJson = JSON.stringify(extrasObj);
    const id = randomUUID();

    insertMachine.run(id, sn, typ, sn, standort, extrasJson);
    imported += 1;
  }
  db.exec('COMMIT');
} catch (e) {
  db.exec('ROLLBACK');
  throw e;
}

db.close();
console.log(
  `Anlagenliste: ${imported} Maschinen importiert, ${skipped} übersprungen (Seriennr. schon vorhanden).`,
);
if (!replaceAll && skipped > 0 && imported === 0) {
  console.log(
    'Hinweis: Für Neuimport: npm run import:anlagen -- --replace',
  );
}
