const { getDatabase } = require('../config/database');

class OnboardingProcess {
    // ── Migration ────────────────────────────────────────────────────────────

    static migrate() {
        const db = getDatabase();

        // Detect old schema (IT / HR / Buchhaltung as dept names) → reset
        try {
            const depts = db.prepare('SELECT name FROM onboarding_departments ORDER BY id LIMIT 5').all();
            const oldNames = ['IT', 'HR / Personal', 'Buchhaltung'];
            if (depts.length > 0 && depts.some(d => oldNames.includes(d.name))) {
                console.log('🔄 Migriere Onboarding-Abteilungen auf neues Schema...');
                db.prepare('DROP TABLE IF EXISTS onboarding_processes').run();
                db.prepare('DROP TABLE IF EXISTS onboarding_departments').run();
            }
        } catch (_) { /* tables don't exist yet */ }

        db.exec(`
            CREATE TABLE IF NOT EXISTS onboarding_departments (
                id         INTEGER PRIMARY KEY AUTOINCREMENT,
                name       TEXT    NOT NULL UNIQUE,
                icon       TEXT    NOT NULL DEFAULT '🏢',
                sort_order INTEGER NOT NULL DEFAULT 0,
                created_at TEXT    NOT NULL DEFAULT (datetime('now'))
            );

            CREATE TABLE IF NOT EXISTS onboarding_processes (
                id               INTEGER PRIMARY KEY AUTOINCREMENT,
                department_id    INTEGER NOT NULL REFERENCES onboarding_departments(id) ON DELETE CASCADE,
                responsible_team TEXT    NOT NULL DEFAULT 'it'
                                          CHECK(responsible_team IN ('it','hr','buchhaltung')),
                title            TEXT    NOT NULL,
                description      TEXT,
                applies_to       TEXT    NOT NULL DEFAULT 'both'
                                          CHECK(applies_to IN ('onboarding','offboarding','both')),
                tag              TEXT    NOT NULL DEFAULT 'normal'
                                          CHECK(tag IN ('normal','important','critical')),
                sort_order       INTEGER NOT NULL DEFAULT 0,
                created_at       TEXT    NOT NULL DEFAULT (datetime('now'))
            );
        `);

        // Add responsible_team if missing (in case of partial migration)
        try {
            db.prepare("ALTER TABLE onboarding_processes ADD COLUMN responsible_team TEXT NOT NULL DEFAULT 'it'").run();
        } catch (_) { /* already exists */ }

        const deptCount = db.prepare('SELECT COUNT(*) as n FROM onboarding_departments').get().n;
        if (deptCount === 0) {
            this._seedDefaults(db);
        }
    }

    static _seedDefaults(db) {
        const insertDept = db.prepare(
            'INSERT INTO onboarding_departments (name, icon, sort_order) VALUES (?, ?, ?)'
        );
        const insertProc = db.prepare(
            'INSERT INTO onboarding_processes (department_id, responsible_team, title, description, applies_to, tag, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?)'
        );

        // Standard-Prozesse (gleich für alle Firmenabteilungen)
        const itOn = [
            ['AD-Account erstellen', 'Benutzername nach Konvention · Temp-Passwort · Gruppe/Abteilung', 'onboarding', 'critical', 1],
            ['E-Mail-Adresse einrichten', 'Postfach anlegen · Signatur · Verteiler aufnehmen', 'onboarding', 'critical', 2],
            ['Hardware prüfen / bestellen', 'Verfügbaren Laptop prüfen · ggf. Neubestellung', 'onboarding', 'critical', 3],
            ['Hardware aufsetzen', 'OS-Image · Updates · Antivirus · Asset erfassen', 'onboarding', 'important', 4],
            ['Software installieren', 'Office 365 · VPN · Teams · abteilungsspez. Tools', 'onboarding', 'critical', 5],
            ['Telefon / Durchwahl einrichten', 'IP-Telefon oder Softphone · Durchwahl zuweisen', 'onboarding', 'important', 6],
            ['Hardware-Übergabe mit Protokoll', 'Laptop + Zubehör übergeben · Protokoll unterschreiben', 'onboarding', 'critical', 7],
            ['Ersten Login begleiten', 'Passwort ändern · MFA einrichten · VPN + Teams testen', 'onboarding', 'critical', 8],
        ];
        const itOff = [
            ['Benutzerkonten deaktivieren', 'AD-Account · E-Mail · alle Systeme deaktivieren', 'offboarding', 'critical', 1],
            ['Zugriffsrechte entziehen', 'VPN · Cloud-Dienste · Remote-Zugriff widerrufen', 'offboarding', 'critical', 2],
            ['Hardware zurücknehmen', 'Laptop, Handy, Token · Zustand prüfen · Asset aktualisieren', 'offboarding', 'critical', 3],
            ['E-Mail-Weiterleitung einrichten', 'Eingehende Mails an Vorgesetzten weiterleiten (mind. 3 Mon.)', 'offboarding', 'important', 4],
        ];
        const hrOn = [
            ['Personalakte anlegen', 'Digitale Akte · Vertragskopie · Eintrittsdatum', 'onboarding', 'critical', 1],
            ['Alle Abteilungen informieren', 'IT, Buchhaltung: Name, Position, Startdatum', 'onboarding', 'critical', 2],
            ['Willkommens-E-Mail senden', 'Startzeit · Ansprechpartner · Parkplatz · Dresscode', 'onboarding', 'important', 3],
            ['Formulare vorbereiten', 'Datenschutz · IT-Nutzungsordnung · Betriebsordnung', 'onboarding', 'normal', 4],
            ['Pflichtunterweisungen planen', 'Arbeitssicherheit · Brandschutz · Datenschutz (KW 1)', 'onboarding', 'important', 5],
            ['Empfang & Begrüßung', 'MA am Empfang abholen · Rundgang · Schlüssel/Badge', 'onboarding', 'critical', 6],
            ['Alle Formulare unterzeichnen', 'Betriebsordnung · Datenschutz · IT-Nutzungsordnung', 'onboarding', 'critical', 7],
        ];
        const hrOff = [
            ['Abschlussgespräch führen', 'Exit-Interview · Feedback einholen', 'offboarding', 'important', 1],
            ['Arbeitszeugnis erstellen', 'Entwurf · vom Vorgesetzten prüfen lassen · ausstellen', 'offboarding', 'important', 2],
            ['Personalakte abschließen', 'Löschfristen prüfen · DSGVO-konform archivieren', 'offboarding', 'normal', 3],
            ['Sozialversicherung abmelden', 'SV-Abmeldung bei Krankenkasse einreichen', 'offboarding', 'normal', 4],
        ];
        const bkOn = [
            ['Mitarbeiter in DATEV anlegen', 'Stammdaten · Eintrittsdatum · Kostenstelle', 'onboarding', 'critical', 1],
            ['Bankdaten & Steuerklasse anfordern', 'IBAN-Formular · Steuerklasse · SV-Nummer', 'onboarding', 'important', 2],
            ['Lohnkonto einrichten', 'Gehaltsgruppe · Krankenkasse · Urlaubsanspruch', 'onboarding', 'important', 3],
            ['Sozialversicherung anmelden', 'SV-Anmeldung bei Krankenkasse einreichen', 'onboarding', 'normal', 4],
            ['Gehaltsabrechnung vorbereiten', 'Erstes Gehalt anteilig berechnen · Auszahlungstermin', 'onboarding', 'important', 5],
        ];
        const bkOff = [
            ['Letzte Gehaltsabrechnung', 'Anteiliges Gehalt · Urlaubsabgeltung · Auszahlungsdatum', 'offboarding', 'critical', 1],
            ['DATEV-Austritt buchen', 'Austrittsdatum eintragen · Kostenstelle abmelden', 'offboarding', 'important', 2],
            ['Offene Spesen prüfen', 'Reisekostenabrechnungen abschließen · Firmenkarte sperren', 'offboarding', 'normal', 3],
        ];

        const allProcesses = [
            ...itOn.map(p => ['it', ...p]),
            ...itOff.map(p => ['it', ...p]),
            ...hrOn.map(p => ['hr', ...p]),
            ...hrOff.map(p => ['hr', ...p]),
            ...bkOn.map(p => ['buchhaltung', ...p]),
            ...bkOff.map(p => ['buchhaltung', ...p]),
        ];

        const departments = [
            ['Wartung',     '🔧', 1],
            ['TBO/Service', '🛠️', 2],
            ['Vertrieb AD', '💼', 3],
            ['Vertrieb ID', '📊', 4],
            ['KAW',         '📦', 5],
            ['IT',          '💻', 6],
            ['Verwaltung',  '🏢', 7],
            ['Produktion',  '🏭', 8],
        ];

        const seed = db.transaction(() => {
            departments.forEach(([name, icon, order]) => {
                const deptId = insertDept.run(name, icon, order).lastInsertRowid;
                allProcesses.forEach(([team, title, desc, applies, tag, sort]) => {
                    insertProc.run(deptId, team, title, desc, applies, tag, sort);
                });
            });
        });
        seed();
    }

    // ── Departments ──────────────────────────────────────────────────────────

    static getAllDepartments() {
        const db = getDatabase();
        return db.prepare(
            'SELECT * FROM onboarding_departments ORDER BY sort_order, name'
        ).all();
    }

    static getDepartmentById(id) {
        const db = getDatabase();
        return db.prepare('SELECT * FROM onboarding_departments WHERE id = ?').get(id);
    }

    static createDepartment({ name, icon = '🏢', sort_order = 0 }) {
        const db = getDatabase();
        const r = db.prepare(
            'INSERT INTO onboarding_departments (name, icon, sort_order) VALUES (?, ?, ?)'
        ).run(name, icon, sort_order);
        return this.getDepartmentById(r.lastInsertRowid);
    }

    static updateDepartment(id, { name, icon, sort_order }) {
        const db = getDatabase();
        const fields = [];
        const vals = [];
        if (name !== undefined)       { fields.push('name = ?');       vals.push(name); }
        if (icon !== undefined)       { fields.push('icon = ?');       vals.push(icon); }
        if (sort_order !== undefined) { fields.push('sort_order = ?'); vals.push(sort_order); }
        if (!fields.length) return this.getDepartmentById(id);
        vals.push(id);
        db.prepare(`UPDATE onboarding_departments SET ${fields.join(', ')} WHERE id = ?`).run(...vals);
        return this.getDepartmentById(id);
    }

    static deleteDepartment(id) {
        const db = getDatabase();
        return db.prepare('DELETE FROM onboarding_departments WHERE id = ?').run(id).changes > 0;
    }

    static reorderDepartments(orderedIds) {
        const db = getDatabase();
        const stmt = db.prepare('UPDATE onboarding_departments SET sort_order = ? WHERE id = ?');
        db.transaction(() => {
            orderedIds.forEach((id, idx) => stmt.run(idx, id));
        })();
    }

    // ── Processes ────────────────────────────────────────────────────────────

    static getAllProcesses({ departmentId, appliesTo, responsibleTeam } = {}) {
        const db = getDatabase();
        const where = [];
        const vals = [];
        if (departmentId)    { where.push('p.department_id = ?');    vals.push(departmentId); }
        if (appliesTo)       { where.push("(p.applies_to = ? OR p.applies_to = 'both')"); vals.push(appliesTo); }
        if (responsibleTeam) { where.push('p.responsible_team = ?'); vals.push(responsibleTeam); }
        const sql = `
            SELECT p.*, d.name as department_name, d.icon as department_icon
            FROM onboarding_processes p
            JOIN onboarding_departments d ON p.department_id = d.id
            ${where.length ? 'WHERE ' + where.join(' AND ') : ''}
            ORDER BY d.sort_order, d.name, p.responsible_team, p.sort_order, p.title
        `;
        return db.prepare(sql).all(...vals);
    }

    static getProcessesForChecklist(appliesTo, departmentId) {
        return this.getAllProcesses({ appliesTo, departmentId });
    }

    static getProcessById(id) {
        const db = getDatabase();
        return db.prepare(
            'SELECT p.*, d.name as department_name FROM onboarding_processes p JOIN onboarding_departments d ON p.department_id = d.id WHERE p.id = ?'
        ).get(id);
    }

    static createProcess({ department_id, responsible_team = 'it', title, description = null, applies_to = 'both', tag = 'normal', sort_order = 0 }) {
        const db = getDatabase();
        const r = db.prepare(
            'INSERT INTO onboarding_processes (department_id, responsible_team, title, description, applies_to, tag, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?)'
        ).run(department_id, responsible_team, title, description, applies_to, tag, sort_order);
        return this.getProcessById(r.lastInsertRowid);
    }

    static updateProcess(id, { title, description, applies_to, tag, sort_order, department_id, responsible_team }) {
        const db = getDatabase();
        const fields = [];
        const vals = [];
        if (title !== undefined)            { fields.push('title = ?');            vals.push(title); }
        if (description !== undefined)      { fields.push('description = ?');      vals.push(description); }
        if (applies_to !== undefined)       { fields.push('applies_to = ?');       vals.push(applies_to); }
        if (tag !== undefined)              { fields.push('tag = ?');              vals.push(tag); }
        if (sort_order !== undefined)       { fields.push('sort_order = ?');       vals.push(sort_order); }
        if (department_id !== undefined)    { fields.push('department_id = ?');    vals.push(department_id); }
        if (responsible_team !== undefined) { fields.push('responsible_team = ?'); vals.push(responsible_team); }
        if (!fields.length) return this.getProcessById(id);
        vals.push(id);
        db.prepare(`UPDATE onboarding_processes SET ${fields.join(', ')} WHERE id = ?`).run(...vals);
        return this.getProcessById(id);
    }

    static deleteProcess(id) {
        const db = getDatabase();
        return db.prepare('DELETE FROM onboarding_processes WHERE id = ?').run(id).changes > 0;
    }

    static reorderProcesses(departmentId, orderedIds) {
        const db = getDatabase();
        const stmt = db.prepare('UPDATE onboarding_processes SET sort_order = ? WHERE id = ? AND department_id = ?');
        db.transaction(() => {
            orderedIds.forEach((id, idx) => stmt.run(idx, id, departmentId));
        })();
    }
}

module.exports = OnboardingProcess;
