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

class FidoKey {
    /**
     * Get all FIDO keys with related user information
     */
    static getAll() {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                fk.*,
                au.username as assigned_to_username,
                au.email as assigned_to_email,
                cu.username as created_by_username,
                uu.username as updated_by_username
            FROM fido_keys fk
            LEFT JOIN users au ON fk.assigned_to_user_id = au.id
            LEFT JOIN users cu ON fk.created_by_user_id = cu.id
            LEFT JOIN users uu ON fk.updated_by_user_id = uu.id
            ORDER BY fk.created_at DESC
        `);
        return stmt.all();
    }

    /**
     * Get FIDO key by ID
     */
    static getById(id) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                fk.*,
                au.username as assigned_to_username,
                au.email as assigned_to_email,
                cu.username as created_by_username,
                uu.username as updated_by_username
            FROM fido_keys fk
            LEFT JOIN users au ON fk.assigned_to_user_id = au.id
            LEFT JOIN users cu ON fk.created_by_user_id = cu.id
            LEFT JOIN users uu ON fk.updated_by_user_id = uu.id
            WHERE fk.id = ?
        `);
        return stmt.get(id);
    }

    /**
     * Get FIDO key by serial number
     */
    static getBySerialNumber(serialNumber) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                fk.*,
                au.username as assigned_to_username,
                cu.username as created_by_username
            FROM fido_keys fk
            LEFT JOIN users au ON fk.assigned_to_user_id = au.id
            LEFT JOIN users cu ON fk.created_by_user_id = cu.id
            WHERE fk.serial_number = ?
        `);
        return stmt.get(serialNumber);
    }

    /**
     * Get FIDO keys by status
     */
    static getByStatus(status) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                fk.*,
                au.username as assigned_to_username,
                cu.username as created_by_username
            FROM fido_keys fk
            LEFT JOIN users au ON fk.assigned_to_user_id = au.id
            LEFT JOIN users cu ON fk.created_by_user_id = cu.id
            WHERE fk.status = ?
            ORDER BY fk.created_at DESC
        `);
        return stmt.all(status);
    }

    /**
     * Get FIDO keys assigned to a specific user
     */
    static getByAssignedUser(userId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                fk.*,
                cu.username as created_by_username
            FROM fido_keys fk
            LEFT JOIN users cu ON fk.created_by_user_id = cu.id
            WHERE fk.assigned_to_user_id = ?
            ORDER BY fk.created_at DESC
        `);
        return stmt.all(userId);
    }

    /**
     * Create a new FIDO key
     */
    static create(keyData) {
        const db = getDatabase();
        const stmt = db.prepare(`
            INSERT INTO fido_keys (
                name,
                serial_number,
                status,
                description,
                assigned_to_user_id,
                created_by_user_id
            ) VALUES (?, ?, ?, ?, ?, ?)
        `);

        const result = stmt.run(
            keyData.name,
            keyData.serial_number,
            keyData.status,
            keyData.description || null,
            keyData.assigned_to_user_id || null,
            keyData.created_by_user_id
        );

        return this.getById(result.lastInsertRowid);
    }

    /**
     * Update FIDO key
     */
    static update(id, keyData, updatedByUserId) {
        const db = getDatabase();

        const fields = [];
        const values = [];

        if (keyData.name !== undefined) {
            fields.push('name = ?');
            values.push(keyData.name);
        }
        if (keyData.serial_number !== undefined) {
            fields.push('serial_number = ?');
            values.push(keyData.serial_number);
        }
        if (keyData.status !== undefined) {
            fields.push('status = ?');
            values.push(keyData.status);
        }
        if (keyData.description !== undefined) {
            fields.push('description = ?');
            values.push(keyData.description);
        }
        if (keyData.assigned_to_user_id !== undefined) {
            fields.push('assigned_to_user_id = ?');
            values.push(keyData.assigned_to_user_id);
        }

        fields.push('updated_by_user_id = ?');
        fields.push('updated_at = CURRENT_TIMESTAMP');
        values.push(updatedByUserId, id);

        const stmt = db.prepare(`
            UPDATE fido_keys
            SET ${fields.join(', ')}
            WHERE id = ?
        `);

        stmt.run(...values);
        return this.getById(id);
    }

    /**
     * Update only the status
     */
    static updateStatus(id, status, updatedByUserId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            UPDATE fido_keys
            SET status = ?,
                updated_by_user_id = ?,
                updated_at = CURRENT_TIMESTAMP
            WHERE id = ?
        `);

        stmt.run(status, updatedByUserId, id);
        return this.getById(id);
    }

    /**
     * Delete FIDO key
     */
    static delete(id) {
        const db = getDatabase();
        const stmt = db.prepare('DELETE FROM fido_keys WHERE id = ?');
        const result = stmt.run(id);
        return result.changes > 0;
    }

    /**
     * Get statistics
     */
    static getStatistics() {
        const db = getDatabase();

        const totalStmt = db.prepare('SELECT COUNT(*) as total FROM fido_keys');
        const activeStmt = db.prepare("SELECT COUNT(*) as active FROM fido_keys WHERE status = 'aktiv'");
        const inactiveStmt = db.prepare("SELECT COUNT(*) as inactive FROM fido_keys WHERE status = 'inaktiv'");
        const assignedStmt = db.prepare('SELECT COUNT(*) as assigned FROM fido_keys WHERE assigned_to_user_id IS NOT NULL');

        return {
            total: totalStmt.get().total,
            active: activeStmt.get().active,
            inactive: inactiveStmt.get().inactive,
            assigned: assignedStmt.get().assigned
        };
    }
}

module.exports = FidoKey;
