// ===== Absatzprognose — Beispiel-Rohdaten (6 Artikel, 2 Jahre Kundenabrufe) =====
// Erzeugt deterministisch (seeded RNG) realistische Abruf-Historien mit unterschiedlichen
// Mustern: regelmäßig, saisonal, erratisch, wachsend, fallend, hochvolumig.

function mulberry32(seed) {
  return function () {
    seed |= 0; seed = (seed + 0x6D2B79F5) | 0;
    let t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}
const dayMs = 86400000;
const iso = (d) => d.toISOString().slice(0, 10);
function addDays(d, n) { return new Date(d.getTime() + n * dayMs); }

// Heute = Planungsbezug (12.06.2026). Historie: 2 Jahre rückwärts.
const FC_TODAY = new Date('2026-06-12T00:00:00Z');
const HIST_START = addDays(FC_TODAY, -730);

// Artikelstamm mit Bestellverhalten
const FC_ARTICLES = [
  { id: 'DP-100', name: 'Dichtungsprofil DP-100', kunde: 'Vossberg Antriebstechnik', mat: 'EPDM', einheit: 'Stk',
    pattern: 'regelmäßig', intervalMean: 21, intervalCv: 0.12, qtyMean: 3200, qtyCv: 0.10, trend: 0.0, season: 0.05, seed: 11 },
  { id: 'KS-22', name: 'Kühlerschlauch KS-22', kunde: 'Nordmann Aerospace', mat: 'Silikon', einheit: 'Stk',
    pattern: 'saisonal', intervalMean: 28, intervalCv: 0.18, qtyMean: 1800, qtyCv: 0.15, trend: 0.0, season: 0.45, seasonPeak: 5, seed: 23 },
  { id: 'HK-7', name: 'Halteklammer HK-7', kunde: 'Hellwig Hydraulik', mat: 'Federstahl', einheit: 'Stk',
    pattern: 'erratisch', intervalMean: 24, intervalCv: 0.55, qtyMean: 2600, qtyCv: 0.62, trend: 0.0, season: 0.1, seed: 37 },
  { id: 'SG-3', name: 'Sensorgehäuse SG-3', kunde: 'Kästner Maschinenbau', mat: 'PA6-GF30', einheit: 'Stk',
    pattern: 'wachsend', intervalMean: 18, intervalCv: 0.15, qtyMean: 1400, qtyCv: 0.12, trend: 0.55, season: 0.08, seed: 53 },
  { id: 'AT-9', name: 'Abdeckkappe AT-9', kunde: 'Pröll Feinwerktechnik', mat: 'POM', einheit: 'Stk',
    pattern: 'fallend', intervalMean: 26, intervalCv: 0.2, qtyMean: 5200, qtyCv: 0.14, trend: -0.4, season: 0.06, seed: 71 },
  { id: 'ST-440', name: 'Stanzteil ST-440', kunde: 'Barchitec Komponenten', mat: 'Alu 5754', einheit: 'Stk',
    pattern: 'hochvolumig', intervalMean: 14, intervalCv: 0.16, qtyMean: 7600, qtyCv: 0.13, trend: 0.1, season: 0.12, seasonPeak: 9, seed: 97 },
];

// Saisonfaktor (1 ± season) abhängig vom Monat, Peak im Monat seasonPeak
function seasonFactor(a, date) {
  if (!a.season) return 1;
  const m = date.getUTCMonth() + 1;
  const peak = a.seasonPeak || 6;
  const phase = Math.cos(((m - peak) / 12) * 2 * Math.PI);
  return 1 + a.season * phase;
}

function genHistory(a) {
  const rng = mulberry32(a.seed);
  const gauss = () => (rng() + rng() + rng() + rng() - 2) / 1.5; // ~N(0,1)
  const rows = [];
  let cursor = addDays(HIST_START, Math.floor(rng() * 10));
  const totalDays = 730;
  while (true) {
    const ageFrac = (cursor.getTime() - HIST_START.getTime()) / (totalDays * dayMs);
    // Intervall mit Streuung
    let iv = a.intervalMean * (1 + a.intervalCv * gauss());
    if (a.pattern === 'erratisch' && rng() < 0.22) iv *= (rng() < 0.5 ? 0.35 : 2.4); // Ausreißer
    iv = Math.max(4, Math.round(iv));
    cursor = addDays(cursor, iv);
    if (cursor >= FC_TODAY) break;
    // Menge: Mittel × Saison × Trend × Streuung
    const trendFactor = 1 + a.trend * ageFrac;
    let qty = a.qtyMean * trendFactor * seasonFactor(a, cursor) * (1 + a.qtyCv * gauss());
    if (a.pattern === 'erratisch' && rng() < 0.18) qty *= (rng() < 0.5 ? 0.4 : 2.1);
    qty = Math.min(10000, Math.max(500, Math.round(qty / 50) * 50));
    rows.push({ datum: iso(cursor), menge: qty });
  }
  return rows;
}

const FC_RAW = {};
FC_ARTICLES.forEach(a => { FC_RAW[a.id] = genHistory(a); });

// Manueller Abrufplan (Kunde) für die Zukunft — vorbefüllt mit ein paar Beispielen
function defaultAbrufplan(a) {
  const rows = FC_RAW[a.id];
  if (!rows.length) return [];
  const last = new Date(rows[rows.length - 1].datum + 'T00:00:00Z');
  const out = [];
  let cur = last;
  for (let i = 0; i < 4; i++) {
    cur = addDays(cur, a.intervalMean);
    // Kunde ruft „komisch" ab: bei erratisch/saisonal bewusst abweichend
    let q = a.qtyMean;
    if (a.id === 'HK-7') q = i === 1 ? a.qtyMean * 2.3 : a.qtyMean * 0.6;       // Sprünge
    else if (a.id === 'KS-22') q = a.qtyMean * 1.1;                              // ignoriert Saison
    else if (a.id === 'AT-9') q = a.qtyMean;                                     // ignoriert fallenden Trend
    else q = a.qtyMean * (0.95 + 0.1 * (i % 2));
    out.push({ datum: iso(cur), menge: Math.round(q / 50) * 50, id: a.id + '-cust-' + i });
  }
  return out;
}

const FC_ABRUFPLAN = {};
FC_ARTICLES.forEach(a => { FC_ABRUFPLAN[a.id] = defaultAbrufplan(a); });

Object.assign(window, { FC_ARTICLES, FC_RAW, FC_ABRUFPLAN, FC_TODAY, HIST_START, fcAddDays: addDays, fcIso: iso, fcSeasonFactor: seasonFactor });

// ===== Arbeitspläne der Prognose-Artikel auf die Feinplanungs-Maschinen =====
// Einzelzeit (h/100 Stk) je Schritt → Vorgangsdauer = Menge/100 × Einzelzeit + Rüsten.
const FC_ROUTING = {
  'DP-100': [ { wsId: 'WS-SG-01', name: 'Profil ablängen', ez: 0.05 }, { wsId: 'WS-FR-11', name: 'Konturfräsen', ez: 0.11 }, { wsId: 'WS-EN-01', name: 'Entgraten', ez: 0.04 }, { wsId: 'WS-MR-01', name: 'Endprüfung', ez: 0.03 } ],
  'KS-22':  [ { wsId: 'WS-SG-01', name: 'Schlauch ablängen', ez: 0.06 }, { wsId: 'WS-DZ-02', name: 'Anschluss drehen', ez: 0.14 }, { wsId: 'WS-MR-01', name: 'Dichtprüfung', ez: 0.05 } ],
  'HK-7':   [ { wsId: 'WS-SG-01', name: 'Bandstahl schneiden', ez: 0.04 }, { wsId: 'WS-FR-11', name: 'Biegen/Fräsen', ez: 0.09 }, { wsId: 'WS-EN-01', name: 'Entgraten', ez: 0.03 } ],
  'SG-3':   [ { wsId: 'WS-DZ-04', name: 'Gehäuse drehen', ez: 0.18 }, { wsId: 'WS-FR-11', name: 'Taschen fräsen', ez: 0.12 }, { wsId: 'WS-EN-01', name: 'Entgraten', ez: 0.05 }, { wsId: 'WS-MR-01', name: 'Messraum', ez: 0.04 } ],
  'AT-9':   [ { wsId: 'WS-DZ-04', name: 'Kappe drehen', ez: 0.07 }, { wsId: 'WS-EN-01', name: 'Gleitschleifen', ez: 0.03 }, { wsId: 'WS-MR-01', name: 'Sichtprüfung', ez: 0.02 } ],
  'ST-440': [ { wsId: 'WS-SG-01', name: 'Platine schneiden', ez: 0.03 }, { wsId: 'WS-FR-11', name: 'Stanzen/Fräsen', ez: 0.08 }, { wsId: 'WS-MR-01', name: 'Endprüfung', ez: 0.02 } ],
};
// Werkstoff-Mapping Prognose-Artikel → Feinplanungs-Werkstoffe (für Rüstmatrix/Farben)
const FC_MAT = { EPDM: 'MS58', Silikon: 'AL60', Federstahl: 'ST42', 'PA6-GF30': 'C45', POM: 'AL70', 'Alu 5754': 'V2A' };

let PA_SEQ = 9000;
// Planauftrag aus einer Abrufzeile erzeugen — landet in der Feinplanung (bestand 'planauftrag')
function makePlanauftrag(article, datum, menge) {
  const nr = 'PA-' + (++PA_SEQ);
  const mat = FC_MAT[article.mat] || 'ST42';
  const steps = (FC_ROUTING[article.id] || [{ wsId: 'WS-DZ-04', name: 'Bearbeitung', ez: 0.1 }]);
  const planStartH = Math.max(0, Math.round((new Date(datum + 'T00:00:00Z') - FC_TODAY) / 3600000));
  const arbeitsplan = steps.map((s, i) => ({
    key: 'pa' + i, avo: String((i + 1) * 10).padStart(4, '0'), name: s.name, wsId: s.wsId,
    wsLabel: (window.WORK_SYSTEMS.find(w => w.id === s.wsId) || {}).name || s.wsId,
    dauerH: Math.max(0.3, Math.round((menge / 100) * s.ez * 10) / 10), status: 'offen',
  }));
  const totalH = arbeitsplan.reduce((a, s) => a + s.dauerH, 0);
  return {
    nr, kunde: article.kunde, mat, menge, kurz: article.name, wert: 0,
    dauerH: arbeitsplan[0].dauerH, restH: totalH, restGesamtH: totalH,
    planStart: planStartH, planEnde: planStartH + Math.round(totalH),
    bestand: 'planauftrag', released: false, avo: '0020',
    arbeitsplan, currentStepName: arbeitsplan[0].name, currentStepWs: arbeitsplan[0].wsLabel,
    jahresbedarf: menge * 12, drehWs: 'WS-DZ-04', source: 'prognose', _row: article._row, _artikel: article.id, _datum: datum,
  };
}
// Tasks eines Planauftrags je System (analog TASKS_BY_SYSTEM)
function planauftragTasks(o) {
  return o.arbeitsplan.filter(s => s.wsId).map(st => ({ ...o, avo: st.avo, dauerH: st.dauerH, stepKey: st.key, _wsId: st.wsId, bestand: 'planauftrag', released: false }));
}

Object.assign(window, { FC_ROUTING, FC_MAT, makePlanauftrag, planauftragTasks });
