// ============================================================
// LSPD — Cognate-Aktensystem & erweiterte Demodaten (fiktiv, GTA-RP)
// ============================================================

// ---- Personenstatus in der Akte ----
const AKTE_STATUS = {
  GESUCHT:    { label: 'Gesucht',        color: '#CC2233' },
  HAFT:       { label: 'In Haft',        color: '#F59E0B' },
  BEWAEHRUNG: { label: 'Bewährung',      color: '#0EA5E9' },
  FREI:       { label: 'Auf freiem Fuß', color: '#22C55E' },
  VERSTORBEN: { label: 'Verstorben',     color: '#8899AA' },
};

// ---- Personenhinweise (Flags) ----
const AKTE_FLAGS = [
  { id: 'bewaffnet', label: 'Bewaffnet & gefährlich', color: '#CC2233', icon: 'TriangleAlert' },
  { id: 'gang',      label: 'Gangzugehörigkeit',      color: '#F59E0B', icon: 'Users' },
  { id: 'flucht',    label: 'Fluchtgefahr',           color: '#A78BFA', icon: 'Footprints' },
];

const LICENSES   = ['Führerschein PKW', 'Motorrad', 'LKW', 'Waffenschein', 'Flugschein', 'Bootsführerschein'];
const EYE_COLORS = ['Blau', 'Braun', 'Grün', 'Grau', 'Haselnuss'];
const HAIR_COLORS= ['Schwarz', 'Braun', 'Blond', 'Rot', 'Grau', 'Rasiert'];
const BLOOD_TYPES= ['', '0+', '0−', 'A+', 'A−', 'B+', 'B−', 'AB+', 'AB−'];

// ---- Straftaten-Katalog (Strafgesetzbuch / Penal Code) ----
const STRAFKATALOG = [
  { para: '§ 242', name: 'Diebstahl',                          fine: 1500,  jail: 10 },
  { para: '§ 249', name: 'Raub',                               fine: 5000,  jail: 30 },
  { para: '§ 250', name: 'Schwerer Raub',                      fine: 8000,  jail: 45 },
  { para: '§ 223', name: 'Körperverletzung',                   fine: 2500,  jail: 15 },
  { para: '§ 224', name: 'Gefährliche Körperverletzung',       fine: 4500,  jail: 28 },
  { para: '§ 211', name: 'Mord',                               fine: 25000, jail: 240 },
  { para: '§ 113', name: 'Widerstand gegen Vollstreckungsb.',  fine: 3000,  jail: 18 },
  { para: '§ 29 BtMG', name: 'Verstoß gegen das BtMG (Drogen)',fine: 2000,  jail: 12 },
  { para: '§ 52 WaffG', name: 'Illegaler Waffenbesitz',        fine: 4000,  jail: 24 },
  { para: '§ 316', name: 'Trunkenheit im Verkehr',             fine: 1000,  jail: 5 },
  { para: '§ 142', name: 'Unerlaubtes Entfernen (Fahrerflucht)',fine: 2500, jail: 12 },
  { para: '§ 315c', name: 'Gefährdung des Straßenverkehrs',    fine: 1800,  jail: 8 },
];

// ---- PD-Vorlagen (vereinfacht · Stammdaten + Abschnitte per Häkchen) ----
const VORLAGE_KUERZEL = {
  einzeltaeter: 'EZ', einsatzbericht: 'EB', stvo: 'ST', festnahme: 'FN', fahndung: 'FH',
  verhoer: 'VH', durchsuchung: 'DS', asservat: 'AS', notiz: 'NT',
};

function todayGerman(d = new Date()) {
  return `${String(d.getDate()).padStart(2, '0')}.${String(d.getMonth() + 1).padStart(2, '0')}.${d.getFullYear()}`;
}
function nowTime() {
  return new Date().toTimeString().slice(0, 5);
}
function buildAktenzeichen(vorlageId, datum) {
  const k = VORLAGE_KUERZEL[vorlageId] || 'PD';
  const d = datum || todayGerman();
  const n = String(Math.floor(Math.random() * 900) + 100);
  return `PD-${d}-${k}${n}`;
}
function staffLabel(s) {
  if (!s) return '—';
  const name = s.name || s.ic_name || s.display_name || '';
  const dn = s.dn || s.employee_number || '';
  return dn ? `${name} · ${dn}` : name;
}
function resolveStaffRef(ref, staffList) {
  if (!ref) return '—';
  const hit = (staffList || []).find(s => String(s.id) === String(ref) || s.name === ref || s.dn === ref);
  return hit ? staffLabel(hit) : String(ref);
}
function entryStammDefaults(vorlageId) {
  const datum = todayGerman();
  return {
    aktenzeichen: buildAktenzeichen(vorlageId, datum),
    datum,
    uhrzeit: nowTime(),
    ort: '',
    bearbeitender: '',
    beteiligte: [],
    aktiv: [],
    abschnitte: {},
  };
}

const VORLAGEN = [
  {
    id: 'einzeltaeter', name: 'Einzeltäter-Akte', icon: 'UserX', color: '#CC2233',
    beschreibung: 'Standard-Personalakte. Stammdaten ausfüllen, Abschnitte per Häkchen aktivieren.',
    straftaten: true,
    abschnitte: [
      { key: 'person', label: 'Person / Beschreibung' },
      { key: 'sachverhalt', label: 'Sachverhalt' },
      { key: 'strafmass', label: 'Strafmaß' },
      { key: 'zeugen', label: 'Zeugen & Beweise' },
      { key: 'massnahmen', label: 'Maßnahmen / Festnahme' },
    ],
  },
  {
    id: 'einsatzbericht', name: 'Einsatzbericht', icon: 'Radio', color: '#3B82F6',
    beschreibung: 'Einsatz dokumentieren — inkl. Einsatzleitung aus dem Dienstplan.',
    abschnitte: [
      { key: 'lage', label: 'Lageschilderung' },
      { key: 'sachverhalt', label: 'Sachverhalt' },
      { key: 'massnahmen', label: 'Getroffene Maßnahmen' },
      { key: 'schaeden', label: 'Schäden / Verletzte' },
      { key: 'fazit', label: 'Fazit & Nachbereitung' },
    ],
    extras: [
      { key: 'einsatzleitung', label: 'Einsatzleitung', type: 'staff' },
      { key: 'einsatzart', label: 'Einsatzart', type: 'select', options: ['Streife', 'Großlage', 'Verkehrskontrolle', 'Festnahme', 'Sonstiges'] },
    ],
  },
  {
    id: 'stvo', name: 'StVO-Verstoß', icon: 'Car', color: '#F59E0B',
    beschreibung: 'Verkehrsordnungswidrigkeit nach StVO.',
    straftaten: true,
    abschnitte: [
      { key: 'delikt', label: 'Verstoß / Delikt' },
      { key: 'fahrzeug', label: 'Fahrzeug & Kennzeichen' },
      { key: 'sachverhalt', label: 'Sachverhalt' },
      { key: 'strafmass', label: 'Bußgeld / Strafmaß' },
    ],
  },
  {
    id: 'festnahme', name: 'Festnahmebericht', icon: 'Fingerprint', color: '#E5384E',
    beschreibung: 'Festnahme inkl. Straftaten aus dem Katalog.',
    straftaten: true,
    abschnitte: [
      { key: 'grund', label: 'Anlass / Festnahmegrund' },
      { key: 'sachverhalt', label: 'Sachverhalt' },
      { key: 'strafmass', label: 'Strafmaß' },
    ],
  },
  {
    id: 'fahndung', name: 'Fahndung (GESUCHT)', icon: 'Siren', color: '#FF4F6C',
    beschreibung: 'Person zur Fahndung ausschreiben — setzt Status GESUCHT.',
    setztGesucht: true,
    abschnitte: [
      { key: 'grund', label: 'Fahndungsgrund' },
      { key: 'gefahr', label: 'Gefährdung & Hinweise' },
    ],
    extras: [
      { key: 'gueltig', label: 'Gültig bis', type: 'text', placeholder: 'TT.MM.JJJJ' },
    ],
  },
  {
    id: 'verhoer', name: 'Verhörprotokoll', icon: 'MessagesSquare', color: '#A78BFA',
    beschreibung: 'Vernehmung protokollieren.',
    abschnitte: [
      { key: 'gegenstand', label: 'Gegenstand der Vernehmung' },
      { key: 'aussage', label: 'Aussage / Protokoll' },
    ],
    extras: [
      { key: 'anwalt', label: 'Anwalt anwesend', type: 'select', options: ['Ja', 'Nein'] },
    ],
  },
  {
    id: 'durchsuchung', name: 'Hausdurchsuchung', icon: 'DoorOpen', color: '#0EA5E9',
    beschreibung: 'Durchsuchungsbeschluss & Ergebnis.',
    abschnitte: [
      { key: 'objekt', label: 'Objekt / Adresse' },
      { key: 'begruendung', label: 'Begründung' },
      { key: 'ergebnis', label: 'Ergebnis / Sichergestelltes' },
    ],
    extras: [
      { key: 'richter', label: 'Anordnender Richter', type: 'text', placeholder: 'RiAG …' },
    ],
  },
  {
    id: 'asservat', name: 'Asservat', icon: 'Archive', color: '#22C55E',
    beschreibung: 'Sichergestellte Gegenstände erfassen.',
    abschnitte: [
      { key: 'gegenstand', label: 'Gegenstand & Menge' },
      { key: 'fundort', label: 'Fundort' },
      { key: 'hinweise', label: 'Hinweise' },
    ],
    extras: [
      { key: 'asservatnr', label: 'Asservatennummer', type: 'text', placeholder: 'ASS-0001' },
    ],
  },
  {
    id: 'notiz', name: 'Allgemeine Notiz', icon: 'StickyNote', color: '#8899AA',
    beschreibung: 'Kurze Notiz ohne festes Schema.',
    abschnitte: [
      { key: 'text', label: 'Notiz' },
    ],
  },
];
const vorlageById = (id) => VORLAGEN.find(v => v.id === id) || VORLAGEN[0];

// ---- Cognate-Akten (Personenakten) ----
const COGNATE_AKTEN = [
  {
    id: 'CG-10428', name: 'Vincent Calloway', geschlecht: 'M', gebdatum: '24.08.1991',
    tel: '555-0143', adresse: 'Forum Drive 21, Davis',
    groesse: 184, augenfarbe: 'Braun', haarfarbe: 'Schwarz', blutgruppe: 'A+',
    status: 'GESUCHT', fahndungsgrund: 'Bewaffneter Raubüberfall auf Fleeca Bank',
    flags: { bewaffnet: true, gang: true, flucht: true },
    lizenzen: ['Führerschein PKW', 'Motorrad'],
    vorstrafen: [
      { datum: '02.05.2026', delikt: 'Bewaffneter Raub', para: '§ 250', strafe: '45 Monate', beamter: 'Det. Cordova' },
      { datum: '11.02.2026', delikt: 'Illegaler Waffenbesitz', para: '§ 52 WaffG', strafe: '24 Monate', beamter: 'Sgt. Banks' },
    ],
    fahrzeuge: [{ kennzeichen: 'VC-1991', modell: 'Bravado Banshee', farbe: 'Schwarz' }],
    waffen: [{ seriennr: 'WF-7741', typ: 'Pistol .50', status: 'Illegal' }],
    notizen: 'Mehrfach gewalttätig aufgefallen. Annäherung nur mit Verstärkung.',
    letzte: '02.06.2026', sachbearbeiter: 'Det. Mia Cordova',
    akteneintraege: [
      { id: 'CGE-2241', vorlage: 'fahndung', ersteller: 'Det. M. Cordova', erstellt: '02.06.2026 14:02', abgeschlossen: false,
        felder: { aktenzeichen: 'PD-02.06.2026-FH318', datum: '02.06.2026', uhrzeit: '14:02', ort: 'Davis', bearbeitender: '8', beteiligte: ['7'], aktiv: ['grund', 'gefahr'], abschnitte: { grund: 'Bewaffneter Raubüberfall Fleeca Bank', gefahr: 'Hoch — zuletzt Davis, vermutlich bewaffnet.' }, gueltig: '02.07.2026' }, straftaten: [] },
      { id: 'CGE-2199', vorlage: 'festnahme', ersteller: 'Sgt. T. Banks', erstellt: '11.02.2026 22:40', abgeschlossen: true,
        felder: { aktenzeichen: 'PD-11.02.2026-FN204', datum: '11.02.2026', uhrzeit: '22:10', ort: 'Strawberry Ave', bearbeitender: '7', beteiligte: ['14'], aktiv: ['grund', 'sachverhalt'], abschnitte: { grund: 'Waffenkontrolle', sachverhalt: 'Illegale Schusswaffe sichergestellt. Festnahme ohne Widerstand.' } },
        straftaten: [{ para: '§ 52 WaffG', name: 'Illegaler Waffenbesitz', fine: 4000, jail: 24 }] },
    ],
  },
  {
    id: 'CG-10391', name: 'Dimitri Sokolov', geschlecht: 'M', gebdatum: '02.11.1988',
    tel: '555-0188', adresse: 'Mirror Park Blvd 7',
    groesse: 178, augenfarbe: 'Grau', haarfarbe: 'Braun', blutgruppe: 'B+',
    status: 'GESUCHT', fahndungsgrund: 'Fahrerflucht nach Verkehrsunfall mit Personenschaden',
    flags: { bewaffnet: false, gang: false, flucht: true },
    lizenzen: ['Führerschein PKW', 'LKW'],
    vorstrafen: [
      { datum: '28.05.2026', delikt: 'Fahrerflucht', para: '§ 142', strafe: '12 Monate', beamter: 'Off. Khan' },
    ],
    fahrzeuge: [{ kennzeichen: 'DS-0042', modell: 'Vapid Dominator', farbe: 'Weiß' }],
    waffen: [],
    notizen: 'Fahrzeug zur Fahndung ausgeschrieben.',
    letzte: '28.05.2026', sachbearbeiter: 'Off. Nadia Khan',
    akteneintraege: [
      { id: 'CGE-2150', vorlage: 'fahndung', ersteller: 'Off. N. Khan', erstellt: '28.05.2026 19:15', abgeschlossen: false,
        felder: { aktenzeichen: 'PD-28.05.2026-FH112', datum: '28.05.2026', uhrzeit: '19:15', ort: 'Mirror Park', bearbeitender: '14', beteiligte: [], aktiv: ['grund', 'gefahr'], abschnitte: { grund: 'Fahrerflucht mit Personenschaden', gefahr: 'Mittel — weißer Vapid Dominator DS-0042.' }, gueltig: '28.06.2026' }, straftaten: [] },
    ],
  },
  {
    id: 'CG-10333', name: 'Eddie Tran', geschlecht: 'M', gebdatum: '30.12.1995',
    tel: '555-0455', adresse: 'Davis Avenue 3',
    groesse: 175, augenfarbe: 'Braun', haarfarbe: 'Schwarz', blutgruppe: '0+',
    status: 'BEWAEHRUNG', fahndungsgrund: '',
    flags: { bewaffnet: false, gang: true, flucht: false },
    lizenzen: ['Führerschein PKW', 'Waffenschein'],
    vorstrafen: [
      { datum: '14.04.2026', delikt: 'Körperverletzung', para: '§ 223', strafe: '15 Monate (Bewährung)', beamter: 'Lt. Brooks' },
    ],
    fahrzeuge: [{ kennzeichen: 'ET-7788', modell: 'Karin Sultan', farbe: 'Grau' }],
    waffen: [{ seriennr: 'WF-2210', typ: 'Combat Pistol', status: 'Legal (Waffenschein)' }],
    notizen: 'Bewährungsauflagen: monatliche Meldung im Mission Row PD.',
    letzte: '20.05.2026', sachbearbeiter: 'Lt. Lena Brooks',
    akteneintraege: [
      { id: 'CGE-2088', vorlage: 'festnahme', ersteller: 'Lt. L. Brooks', erstellt: '14.04.2026 16:20', abgeschlossen: true,
        felder: { aktenzeichen: 'PD-14.04.2026-FN891', datum: '14.04.2026', uhrzeit: '15:40', ort: 'Vespucci Beach', bearbeitender: '6', beteiligte: ['7'], aktiv: ['grund', 'sachverhalt'], abschnitte: { grund: 'Schlägerei', sachverhalt: 'Tätlicher Angriff. Festnahme nach kurzer Verfolgung.' } },
        straftaten: [{ para: '§ 223', name: 'Körperverletzung', fine: 2500, jail: 15 }] },
      { id: 'CGE-2090', vorlage: 'verhoer', ersteller: 'Lt. L. Brooks', erstellt: '14.04.2026 17:05', abgeschlossen: true,
        felder: { aktenzeichen: 'PD-14.04.2026-VH445', datum: '14.04.2026', uhrzeit: '17:05', ort: 'Mission Row PD', bearbeitender: '6', beteiligte: [], aktiv: ['gegenstand', 'aussage'], abschnitte: { gegenstand: 'Tathergang Vespucci Beach', aussage: 'Beschuldigter räumt Streit ein, bestreitet Vorsatz.' }, anwalt: 'Ja' } },
    ],
  },
  {
    id: 'CG-10444', name: 'Nora Whitfield', geschlecht: 'W', gebdatum: '19.05.1979',
    tel: '555-0099', adresse: 'Del Perro Heights 12',
    groesse: 168, augenfarbe: 'Grün', haarfarbe: 'Rot', blutgruppe: 'AB+',
    status: 'GESUCHT', fahndungsgrund: 'Vermisst — mutmaßliche Eigengefährdung',
    flags: { bewaffnet: false, gang: false, flucht: false },
    lizenzen: ['Führerschein PKW'],
    vorstrafen: [],
    fahrzeuge: [{ kennzeichen: 'NW-0501', modell: 'Übermacht Sentinel', farbe: 'Blau' }],
    waffen: [],
    notizen: 'Vermisstenfall. Angehörige informiert. Keine Vorstrafen.',
    letzte: '20.05.2026', sachbearbeiter: 'Det. Mia Cordova',
    akteneintraege: [
      { id: 'CGE-2061', vorlage: 'fahndung', ersteller: 'Det. M. Cordova', erstellt: '20.05.2026 11:20', abgeschlossen: false,
        felder: { grund: 'Vermisstenfall, Eigengefährdung', gefahr: 'Mittel', gueltig: '20.06.2026', hinweise: 'Zuletzt gesehen Del Perro Pier. Bei Sichtung sofort Streife verständigen.' }, straftaten: [] },
    ],
  },
  {
    id: 'CG-10288', name: 'Sophie Lang', geschlecht: 'W', gebdatum: '08.09.2001',
    tel: '555-0301', adresse: 'Vinewood Hills 4',
    groesse: 165, augenfarbe: 'Blau', haarfarbe: 'Blond', blutgruppe: '0−',
    status: 'FREI', fahndungsgrund: '',
    flags: { bewaffnet: false, gang: false, flucht: false },
    lizenzen: ['Führerschein PKW', 'Motorrad', 'Waffenschein'],
    vorstrafen: [],
    fahrzeuge: [],
    waffen: [],
    notizen: 'Anwärterin LSPD — Ausbildungsakte hinterlegt.',
    letzte: '02.06.2026', sachbearbeiter: 'Sgt. Tyrone Banks',
    akteneintraege: [
      { id: 'CGE-2240', vorlage: 'notiz', ersteller: 'Sgt. T. Banks', erstellt: '02.06.2026 10:00', abgeschlossen: true,
        felder: { aktenzeichen: 'PD-02.06.2026-NT501', datum: '02.06.2026', uhrzeit: '10:00', ort: 'Mission Row PD', bearbeitender: '7', beteiligte: ['12'], aktiv: ['text'], abschnitte: { text: 'Cognet-Grundlagen bestanden. Sicherer Umgang mit dem Aktensystem nachgewiesen.' } } },
    ],
  },
];

const ENTRY_DEFAULT = () => ({ id: '', vorlage: 'festnahme', ersteller: 'Off. M. Cordova', erstellt: '', abgeschlossen: false, felder: {}, straftaten: [] });

// ---- Discord-Rollen & Rechte (Admin) ----
const DISCORD_ROLES = [
  { id: 'command',  name: 'Command',    color: '#FF4F6C', members: 4 },
  { id: 'sergeant', name: 'Sergeants',  color: '#F59E0B', members: 5 },
  { id: 'detective',name: 'Detectives', color: '#A78BFA', members: 6 },
  { id: 'officer',  name: 'Officers',   color: '#22C55E', members: 20 },
  { id: 'kadett',   name: 'Kadetten',   color: '#8899AA', members: 6 },
];

const PERMISSION_GROUPS = [
  { group: 'Personal', perms: [
    { id: 'p_view',   label: 'Beamte ansehen' },
    { id: 'p_edit',   label: 'Beamte bearbeiten' },
    { id: 'p_create', label: 'Beamte anlegen' },
    { id: 'p_fire',   label: 'Beamte entlassen' },
  ]},
  { group: 'Cognate-Akten', perms: [
    { id: 'a_view',   label: 'Akten einsehen' },
    { id: 'a_create', label: 'Akten / Einträge anlegen' },
    { id: 'a_edit',   label: 'Akten bearbeiten' },
    { id: 'a_wanted', label: 'Fahndung setzen (GESUCHT)' },
  ]},
  { group: 'Verwaltung', perms: [
    { id: 'v_fahndung', label: 'Fahndungen verwalten' },
    { id: 'v_bonus',    label: 'Bonus auszahlen' },
    { id: 'v_leave',    label: 'Urlaub genehmigen' },
    { id: 'v_admin',    label: 'Admin-Bereich' },
  ]},
];

// Matrix: roleId -> { permId: bool }
const DEFAULT_PERMISSIONS = {
  command:   { p_view:1,p_edit:1,p_create:1,p_fire:1, a_view:1,a_create:1,a_edit:1,a_wanted:1, v_fahndung:1,v_bonus:1,v_leave:1,v_admin:1 },
  sergeant:  { p_view:1,p_edit:1,p_create:1,p_fire:0, a_view:1,a_create:1,a_edit:1,a_wanted:1, v_fahndung:1,v_bonus:1,v_leave:1,v_admin:0 },
  detective: { p_view:1,p_edit:0,p_create:0,p_fire:0, a_view:1,a_create:1,a_edit:1,a_wanted:1, v_fahndung:1,v_bonus:0,v_leave:0,v_admin:0 },
  officer:   { p_view:1,p_edit:0,p_create:0,p_fire:0, a_view:1,a_create:1,a_edit:0,a_wanted:0, v_fahndung:0,v_bonus:0,v_leave:0,v_admin:0 },
  kadett:    { p_view:1,p_edit:0,p_create:0,p_fire:0, a_view:1,a_create:0,a_edit:0,a_wanted:0, v_fahndung:0,v_bonus:0,v_leave:0,v_admin:0 },
};

// ---- Sonderrechte / Schlüssel (Beamte) ----
const SPECIAL_RIGHTS = [
  { id: 'leitstelle', label: 'Leitstellen-Zugang',  icon: 'RadioTower' },
  { id: 'fuhrpark',   label: 'Streifenwagen-Park',   icon: 'KeyRound' },
  { id: 'asservate',  label: 'Asservatenkammer',     icon: 'Archive' },
  { id: 'dnalabor',   label: 'DNA-Labor',            icon: 'TestTube' },
  { id: 'waffen',     label: 'Waffenkammer',         icon: 'Crosshair' },
  { id: 'adminpanel', label: 'Admin-Panel',          icon: 'ShieldAlert' },
  { id: 'aktenedit',  label: 'Cognate bearbeiten',   icon: 'FilePen' },
  { id: 'heli',       label: 'Air Unit (Heli)',      icon: 'Plane' },
];
// default rights per member id
const MEMBER_RIGHTS = {
  1: ['leitstelle','fuhrpark','asservate','dnalabor','waffen','adminpanel','aktenedit','heli'],
  2: ['leitstelle','fuhrpark','asservate','dnalabor','adminpanel','aktenedit','heli'],
  3: ['leitstelle','fuhrpark','waffen','aktenedit','heli'],
  4: ['leitstelle','fuhrpark','aktenedit'],
  6: ['fuhrpark','asservate','aktenedit'],
  7: ['fuhrpark','waffen'],
  8: ['fuhrpark','aktenedit'],
};

// ---- Logbuch ----
const LOGBOOK = [
  { ts: '02.06.2026 14:32', user: 'Det. M. Cordova', action: 'Fahndung gesetzt: V. Calloway (CG-10428) — GESUCHT',  type: 'Cognate' },
  { ts: '02.06.2026 13:58', user: 'Sgt. T. Banks',   action: 'Ausbildungsakte zu S. Lang abgeschlossen',           type: 'Cognate' },
  { ts: '02.06.2026 11:14', user: 'Frank Mercer',    action: 'Rechte der Rolle „Officers" angepasst',              type: 'Admin' },
  { ts: '01.06.2026 22:07', user: 'T. Banks',        action: 'Dienst beendet — 6h 12m',                            type: 'Dienst' },
  { ts: '01.06.2026 16:40', user: 'Lt. L. Brooks',   action: 'Verhörprotokoll zu E. Tran (CG-10333) erfasst',      type: 'Cognate' },
  { ts: '01.06.2026 09:21', user: 'D. Castillo',     action: 'Fahndung FA-2041 (V. Calloway) verlängert',          type: 'Fahndung' },
  { ts: '31.05.2026 18:55', user: 'C. Mendes',       action: 'Bonus i.H.v. $1.200 an T. Brandt ausgezahlt',        type: 'Bonus' },
  { ts: '31.05.2026 12:03', user: 'Frank Mercer',    action: 'Beamter „Sophie Lang" angelegt (LSPD-041)',          type: 'Personal' },
  { ts: '30.05.2026 20:18', user: 'M. Cordova',      action: 'DNA-Abgleich DNA-0042 abgeschlossen',                type: 'DNA' },
];
const LOG_TYPES = { Cognate:'#3B82F6', Admin:'#CC2233', Dienst:'#22C55E', Fahndung:'#0EA5E9', Bonus:'#F59E0B', Personal:'#A78BFA', DNA:'#14B8A6' };

// ---- DNA / Forensik ----
const DNA_TESTS = [
  { id: 'DNA-0042', proband: 'Tatort Fleeca Bank (Davis)',   match: 'Vincent Calloway', conf: 99.2, status: 'Treffer', date: '30.05.2026', by: 'Det. Cordova' },
  { id: 'DNA-0041', proband: 'Blutprobe Sandy Shores',       match: 'Kein Treffer',     conf: 0,    status: 'Offen',   date: '28.05.2026', by: 'Off. Khan' },
  { id: 'DNA-0040', proband: 'Patrone Legion Square',        match: 'Eddie Tran',       conf: 96.4, status: 'Treffer', date: '24.05.2026', by: 'Lt. Brooks' },
  { id: 'DNA-0039', proband: 'Zigarettenstummel Paleto Bay', match: 'In Bearbeitung',   conf: 0,    status: 'Analyse', date: '22.05.2026', by: 'Det. Cordova' },
];

// ---- Wiki / Dienstvorschriften ----
const WIKI = [
  { cat: 'Erste Schritte', icon: 'Flag', articles: ['Onboarding für neue Beamte', 'Funkcodes & 10-Codes', 'Dienstausweis & Ausrüstung', 'Verhalten im Einsatz'] },
  { cat: 'Streifendienst', icon: 'Car', articles: ['Verkehrskontrolle — Ablauf', 'Festnahme korrekt durchführen', 'Eigensicherung', 'Pursuit-Richtlinien (Verfolgung)'] },
  { cat: 'Recht & Gesetz',  icon: 'Scale', articles: ['Strafgesetzbuch (Auszug)', 'Rechte des Beschuldigten', 'Durchsuchung & Beschlagnahme', 'Bußgeldkatalog'] },
  { cat: 'Cognate-System',  icon: 'Database', articles: ['Cognate — Akte anlegen', 'Fahndung (GESUCHT) setzen', 'Vorlagen verwenden', 'Asservate erfassen'] },
];

// ---- Abteilungen / Divisionen ----
const DEPT_DETAIL = [
  { name: 'Streifendienst',        lead: 'Capt. Erika Lindqvist', members: 16, color: '#22C55E', desc: 'Patrouille, Erstreaktion und allgemeine Gefahrenabwehr im Stadtgebiet.' },
  { name: 'Kriminalpolizei (CID)', lead: 'Asst. Chief Castillo',  members: 9,  color: '#A78BFA', desc: 'Ermittlungen, Fahndungen und Aufklärung schwerer Straftaten.' },
  { name: 'SWAT',                  lead: 'Cmdr. Marcus Holt',     members: 6,  color: '#CC2233', desc: 'Spezialeinsätze, Geisellagen und Hochrisiko-Zugriffe.' },
  { name: 'Verkehrspolizei',       lead: 'Capt. Raymond Park',    members: 6,  color: '#F59E0B', desc: 'Verkehrsüberwachung, Unfallaufnahme und Bußgeldwesen.' },
  { name: 'Ausbildung',            lead: 'Sgt. Tyrone Banks',     members: 4,  color: '#0EA5E9', desc: 'Rekrutenschulung, Zertifizierungen und Cognet-Ausbildung.' },
];

// ---- Urlaub / Abwesenheit ----
const LEAVES = [
  { name: 'David Krause',     dn: 'LSPD-029', from: '18.05.2026', to: '08.06.2026', type: 'Urlaub',       status: 'Genehmigt' },
  { name: 'Raymond Park',     dn: 'LSPD-014', from: '02.06.2026', to: '09.06.2026', type: 'Krankheit',    status: 'Genehmigt' },
  { name: 'Mia Cordova',      dn: 'LSPD-025', from: '10.06.2026', to: '17.06.2026', type: 'Urlaub',       status: 'Offen' },
  { name: 'Tim Brandt',       dn: 'LSPD-037', from: '05.06.2026', to: '06.06.2026', type: 'Sonderurlaub', status: 'Offen' },
  { name: 'Carla Mendes',     dn: 'LSPD-033', from: '20.06.2026', to: '04.07.2026', type: 'Urlaub',       status: 'Offen' },
];

// ---- Bonus ----
const BONUSES = [
  { name: 'Tim Brandt',   dn: 'LSPD-037', amount: 1200, reason: 'Vorbildlicher Einsatz Banküberfall', date: '31.05.2026', status: 'Ausgezahlt' },
  { name: 'Tyrone Banks', dn: 'LSPD-022', amount: 800,  reason: 'Überstunden Mai',                    date: '30.05.2026', status: 'Ausgezahlt' },
  { name: 'Nadia Khan',   dn: 'LSPD-044', amount: 500,  reason: 'Bestandene Detective-Prüfung',       date: '02.06.2026', status: 'Offen' },
  { name: 'Carla Mendes', dn: 'LSPD-033', amount: 650,  reason: 'Ausbildung neuer Kadetten',          date: '02.06.2026', status: 'Offen' },
];

// ---- Dienstzeiten (offene Freigaben) ----
const SHIFTS = [
  { name: 'Tyrone Banks', dn: 'LSPD-022', date: '01.06.2026', start: '15:48', end: '22:00', dur: '6h 12m', status: 'Freigabe' },
  { name: 'Mia Cordova',  dn: 'LSPD-025', date: '01.06.2026', start: '14:02', end: '20:30', dur: '6h 28m', status: 'Freigabe' },
  { name: 'Nadia Khan',   dn: 'LSPD-044', date: '31.05.2026', start: '09:10', end: '17:40', dur: '8h 30m', status: 'Bestätigt' },
  { name: 'Tim Brandt',   dn: 'LSPD-037', date: '31.05.2026', start: '18:00', end: '23:15', dur: '5h 15m', status: 'Freigabe' },
];

// ---- Boards & Teams ----
const BOARDS = [
  { name: 'Command Board',     color: '#FF4F6C', count: 4,  desc: 'Strategie, Personalentscheidungen, Budget' },
  { name: 'Einsatzleitung',    color: '#CC2233', count: 8,  desc: 'Schichtplanung & Großlagen' },
  { name: 'Ausbildungsteam',   color: '#22C55E', count: 6,  desc: 'Schulungen, Prüfungen, Zertifikate' },
  { name: 'Interne Ermittlung',color: '#0EA5E9', count: 4,  desc: 'Beschwerden & Disziplinarverfahren' },
];

// ---- Ticketsystem (öffentlich) ----
const TICKET_KATEGORIEN = [
  { id: 'anzeige',    label: 'Anzeige erstatten',  icon: 'FileWarning', color: '#CC2233' },
  { id: 'dokument',   label: 'Dokument anfragen',  icon: 'FileText',    color: '#3B82F6' },
  { id: 'beschwerde', label: 'Beschwerde',         icon: 'MessageSquareWarning', color: '#F59E0B' },
  { id: 'sonstiges',  label: 'Sonstiges Anliegen', icon: 'HelpCircle',  color: '#8899AA' },
];
const TICKETS = [
  { id: 'TK-1041', betreff: 'Diebstahl meines Fahrzeugs',     kat: 'anzeige',    status: 'In Bearbeitung', date: '02.06.2026', bearbeiter: 'Det. Cordova' },
  { id: 'TK-1038', betreff: 'Kopie meines Führungszeugnisses', kat: 'dokument',   status: 'Offen',          date: '01.06.2026', bearbeiter: '—' },
  { id: 'TK-1033', betreff: 'Beschwerde über Verkehrskontrolle',kat: 'beschwerde',status: 'Geschlossen',    date: '29.05.2026', bearbeiter: 'Capt. Park' },
];
const TICKET_STATE_COLOR = { 'Offen':'#F59E0B', 'In Bearbeitung':'#0EA5E9', 'Geschlossen':'#22C55E' };

// ---- Fahrzeugregister (zentral, verknüpft mit Akten über den Halter-Namen) ----
const FAHRZEUG_TYPEN = ['PKW', 'Motorrad', 'SUV', 'Transporter', 'LKW', 'Sportwagen'];
// Quelle = offene Schnittstelle: Behörde (LSPD) oder externe Werkstatt (Bennys)
const FAHRZEUG_QUELLEN = {
  lspd:   { label: 'LSPD-Zulassung',   color: '#2A6FDB', icon: 'ShieldCheck' },
  bennys: { label: 'Bennys Werkstatt', color: '#E0A33A', icon: 'Wrench' },
};
const FAHRZEUG_STATUS = {
  ANGEMELDET: { label: 'Angemeldet',  color: '#22C55E' },
  STILLGELEGT:{ label: 'Stillgelegt', color: '#8899AA' },
  GESUCHT:    { label: 'Zur Fahndung',color: '#E5384E' },
  IMPORT:     { label: 'Import offen',color: '#F59E0B' },
};
const FAHRZEUGE = [
  { kennzeichen: 'VC-1991', modell: 'Bravado Banshee',   typ: 'Sportwagen',   farbe: 'Schwarz', halter: 'Vincent Calloway', quelle: 'lspd',   status: 'GESUCHT',     vin: 'VIN-8841-VC', datum: '02.05.2026' },
  { kennzeichen: 'DS-0042', modell: 'Vapid Dominator',   typ: 'PKW',          farbe: 'Weiß',    halter: 'Dimitri Sokolov',  quelle: 'lspd',   status: 'GESUCHT',     vin: 'VIN-5520-DS', datum: '28.05.2026' },
  { kennzeichen: 'ET-7788', modell: 'Karin Sultan',      typ: 'PKW',          farbe: 'Grau',    halter: 'Eddie Tran',       quelle: 'bennys', status: 'ANGEMELDET',  vin: 'VIN-2210-ET', datum: '14.04.2026' },
  { kennzeichen: 'NW-0501', modell: 'Übermacht Sentinel',typ: 'PKW',          farbe: 'Blau',    halter: 'Nora Whitfield',   quelle: 'lspd',   status: 'ANGEMELDET',  vin: 'VIN-0501-NW', datum: '20.05.2026' },
  { kennzeichen: 'SL-2299', modell: 'Pegassi Bati 801',  typ: 'Motorrad',     farbe: 'Rot',     halter: 'Sophie Lang',      quelle: 'bennys', status: 'ANGEMELDET',  vin: 'VIN-2299-SL', datum: '01.06.2026' },
  { kennzeichen: 'KO-3344', modell: 'Declasse Granger',  typ: 'SUV',          farbe: 'Schwarz', halter: 'Kingsley Obi',     quelle: 'lspd',   status: 'STILLGELEGT', vin: 'VIN-3344-KO', datum: '12.03.2026' },
  { kennzeichen: 'BW-0077', modell: 'Vapid Sadler',      typ: 'Transporter',  farbe: 'Weiß',    halter: 'Bennys Werkstatt', quelle: 'bennys', status: 'IMPORT',      vin: 'VIN-0077-BW', datum: '05.06.2026' },
];
// Zentraler, veränderbarer Store (damit Registrierung & Akten synchron bleiben)
const vehicleStore = {
  list: FAHRZEUGE.slice(),
  subs: new Set(),
  getAll() { return this.list; },
  add(v) { this.list = [v, ...this.list]; this._emit(); },
  update(kennzeichen, patch) { this.list = this.list.map(x => x.kennzeichen === kennzeichen ? { ...x, ...patch } : x); this._emit(); },
  remove(kennzeichen) { this.list = this.list.filter(x => x.kennzeichen !== kennzeichen); this._emit(); },
  subscribe(fn) { this.subs.add(fn); return () => this.subs.delete(fn); },
  _emit() { this.subs.forEach(fn => fn()); },
};
// Verknüpfung: alle Fahrzeuge, deren Halter-Name (normalisiert) dem Akten-Namen entspricht
function fahrzeugeFuerHalter(name) {
  if (!name) return [];
  const norm = s => (s || '').toLowerCase().replace(/\s+/g, ' ').trim();
  return vehicleStore.getAll().filter(f => norm(f.halter) === norm(name));
}

Object.assign(window, {
  AKTE_STATUS, AKTE_FLAGS, LICENSES, EYE_COLORS, HAIR_COLORS, BLOOD_TYPES,
  STRAFKATALOG, VORLAGEN, VORLAGE_KUERZEL, vorlageById, buildAktenzeichen, entryStammDefaults,
  todayGerman, staffLabel, resolveStaffRef, COGNATE_AKTEN, ENTRY_DEFAULT,
  DISCORD_ROLES, PERMISSION_GROUPS, DEFAULT_PERMISSIONS, SPECIAL_RIGHTS, MEMBER_RIGHTS,
  LOGBOOK, LOG_TYPES, DNA_TESTS, WIKI, DEPT_DETAIL, LEAVES, BONUSES, SHIFTS, BOARDS,
  TICKET_KATEGORIEN, TICKETS, TICKET_STATE_COLOR,
  FAHRZEUG_TYPEN, FAHRZEUG_QUELLEN, FAHRZEUG_STATUS, FAHRZEUGE, fahrzeugeFuerHalter, vehicleStore,
});
