window.timelineEngine = {
  config: null,
  template: null,
  csvOverride: false,
  cssOverride: false,

  async autoLoadDefaultProject() {
    // Versuche zuerst Binect-Projekt, sonst Example
    const candidates = ["binect/project.json", "example/project.json"];
    for (const path of candidates) {
      try {
        const res = await fetch(path);
        if (!res.ok) continue;
        const cfg = await res.json();
        await this.loadProjectConfigObject(cfg);
        return;
      } catch (e) {
        continue;
      }
    }
  },

  async loadProjectConfigObject(cfg) {
    this.config = cfg;
    const name = cfg.name || "Timeline";
    document.getElementById("projectName").innerText = name;
    document.getElementById("projectSubtitle").innerText =
      cfg.description || "Projektkonfiguration geladen.";

    // Stylesheet
    if (cfg.stylesheet && !this.cssOverride) {
      document.getElementById("dynamicCss").href = cfg.stylesheet;
    }

    // SVG template
    if (cfg.svgTemplate) {
      try {
        this.template = await fetch(cfg.svgTemplate).then(r => r.text());
      } catch (e) {
        console.warn("SVG template could not be loaded:", e);
      }
    }

    // CSV data
    if (cfg.dataSource && !this.csvOverride) {
      try {
        const csvText = await fetch(cfg.dataSource).then(r => r.text());
        this.processCsv(csvText);
      } catch (e) {
        console.warn("CSV could not be loaded:", e);
      }
    }
  },

  processCsv(text) {
    if (!this.config || !this.config.fieldMapping) {
      console.error("No config or fieldMapping found.");
      return;
    }
    const m = this.config.fieldMapping;

    Papa.parse(text, {
      header: true,
      skipEmptyLines: true,
      complete: (res) => {
        const rows = res.data;
        const items = rows.map((r) => {
          const dueField = (m.due || []).find(f => r[f]);
          return {
            id: m.id ? r[m.id] : (r["ID"] || ""),
            title: m.title ? r[m.title] : (r["Title"] || ""),
            lane: m.lane ? (r[m.lane] || "Ohne Epic") : (r["Lane"] || "Default"),
            due: this.parseDate(dueField ? r[dueField] : null)
          };
        }).filter(i => i.title && i.due);

        if (!items.length) {
          document.getElementById("viewer").innerHTML =
            "<em style='color:#999;'>Keine gültigen Items gefunden.</em>";
          return;
        }

        const svg = window.timelineGenerator.generate(items, this.config, this.template);
        document.getElementById("viewer").innerHTML = svg;
        const dlBtn = document.getElementById("downloadSvg");
        dlBtn.disabled = false;
        dlBtn.style.opacity = 1;
      }
    });
  },

  parseDate(str) {
    if (!str) return null;
    str = String(str).trim();
    let d = null;

    // YYYY/MM/DD oder YYYY-MM-DD
    let m = str.match(/^(\d{4})[\/-](\d{1,2})[\/-](\d{1,2})$/);
    if (m) {
      const [_, yy, mm, dd] = m;
      d = new Date(Number(yy), Number(mm) - 1, Number(dd));
      return isNaN(d.getTime()) ? null : d;
    }

    // DD.MM.YYYY
    m = str.match(/^(\d{1,2})\.(\d{1,2})\.(\d{4})$/);
    if (m) {
      const [_, dd, mm, yy] = m;
      d = new Date(Number(yy), Number(mm) - 1, Number(dd));
      return isNaN(d.getTime()) ? null : d;
    }

    // Fallback
    d = new Date(str);
    return isNaN(d.getTime()) ? null : d;
  }
};

// --------- UI event handlers ---------

document.getElementById("projectInput").addEventListener("change", async (ev) => {
  const file = ev.target.files[0];
  if (!file) return;
  const text = await file.text();
  const cfg = JSON.parse(text);
  await window.timelineEngine.loadProjectConfigObject(cfg);
});

document.getElementById("csvInput").addEventListener("change", async (ev) => {
  const file = ev.target.files[0];
  if (!file) return;
  const text = await file.text();
  window.timelineEngine.csvOverride = true;
  window.timelineEngine.processCsv(text);
});

document.getElementById("cssInput").addEventListener("change", async (ev) => {
  const file = ev.target.files[0];
  if (!file) return;
  const cssText = await file.text();
  window.timelineEngine.cssOverride = true;
  const blob = new Blob([cssText], { type: "text/css" });
  document.getElementById("dynamicCss").href = URL.createObjectURL(blob);
});

document.getElementById("svgInput").addEventListener("change", async (ev) => {
  const file = ev.target.files[0];
  if (!file) return;
  window.timelineEngine.template = await file.text();
});

document.getElementById("downloadSvg").addEventListener("click", () => {
  const svg = document.querySelector("#viewer svg");
  if (!svg) return;

  // Always external view for export: IDs ausblenden
  svg.querySelectorAll(".item-id").forEach(el => el.style.display = "none");

  const now = new Date();
  const ts = String(now.getFullYear()).slice(2)
            + String(now.getMonth() + 1).padStart(2, "0")
            + String(now.getDate()).padStart(2, "0")
            + "T"
            + String(now.getHours()).padStart(2, "0")
            + String(now.getMinutes()).padStart(2, "0");

  const blob = new Blob([svg.outerHTML], { type: "image/svg+xml" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `${ts}-timeline.svg`;
  a.click();
  URL.revokeObjectURL(url);
});

