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

class AssetAssignment {
    /**
     * Get all assignments with related information
     */
    static getAll() {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                aa.*,
                a.name as asset_name,
                a.type as asset_type,
                a.serial_number as asset_serial_number,
                u.username as user_username,
                u.email as user_email,
                ab.username as assigned_by_username
            FROM asset_assignments aa
            INNER JOIN assets a ON aa.asset_id = a.id
            INNER JOIN users u ON aa.user_id = u.id
            INNER JOIN users ab ON aa.assigned_by_user_id = ab.id
            ORDER BY aa.assigned_at DESC
        `);
        return stmt.all();
    }

    /**
     * Get assignment by ID
     */
    static getById(id) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                aa.*,
                a.name as asset_name,
                a.type as asset_type,
                a.serial_number as asset_serial_number,
                u.username as user_username,
                u.email as user_email,
                ab.username as assigned_by_username
            FROM asset_assignments aa
            INNER JOIN assets a ON aa.asset_id = a.id
            INNER JOIN users u ON aa.user_id = u.id
            INNER JOIN users ab ON aa.assigned_by_user_id = ab.id
            WHERE aa.id = ?
        `);
        return stmt.get(id);
    }

    /**
     * Get assignments for a specific asset
     */
    static getByAssetId(assetId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                aa.*,
                u.username as user_username,
                u.email as user_email,
                ab.username as assigned_by_username
            FROM asset_assignments aa
            INNER JOIN users u ON aa.user_id = u.id
            INNER JOIN users ab ON aa.assigned_by_user_id = ab.id
            WHERE aa.asset_id = ?
            ORDER BY aa.assigned_at DESC
        `);
        return stmt.all(assetId);
    }

    /**
     * Get assignments for a specific user
     */
    static getByUserId(userId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                aa.*,
                a.name as asset_name,
                a.type as asset_type,
                a.serial_number as asset_serial_number,
                ab.username as assigned_by_username
            FROM asset_assignments aa
            INNER JOIN assets a ON aa.asset_id = a.id
            INNER JOIN users ab ON aa.assigned_by_user_id = ab.id
            WHERE aa.user_id = ?
            ORDER BY aa.assigned_at DESC
        `);
        return stmt.all(userId);
    }

    /**
     * Get current assignment for an asset (not returned yet)
     */
    static getCurrentAssignment(assetId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                aa.*,
                u.username as user_username,
                u.email as user_email,
                ab.username as assigned_by_username
            FROM asset_assignments aa
            INNER JOIN users u ON aa.user_id = u.id
            INNER JOIN users ab ON aa.assigned_by_user_id = ab.id
            WHERE aa.asset_id = ?
              AND aa.returned_at IS NULL
            ORDER BY aa.assigned_at DESC
            LIMIT 1
        `);
        return stmt.get(assetId);
    }

    /**
     * Get active assignments for a user (not returned yet)
     */
    static getActiveAssignmentsByUser(userId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                aa.*,
                a.name as asset_name,
                a.type as asset_type,
                a.serial_number as asset_serial_number,
                ab.username as assigned_by_username
            FROM asset_assignments aa
            INNER JOIN assets a ON aa.asset_id = a.id
            INNER JOIN users ab ON aa.assigned_by_user_id = ab.id
            WHERE aa.user_id = ?
              AND aa.returned_at IS NULL
            ORDER BY aa.assigned_at DESC
        `);
        return stmt.all(userId);
    }

    /**
     * Create a new assignment
     */
    static create(assignmentData) {
        const db = getDatabase();
        const stmt = db.prepare(`
            INSERT INTO asset_assignments (
                asset_id,
                user_id,
                assigned_by_user_id,
                notes,
                onboarding_protocol_id
            ) VALUES (?, ?, ?, ?, ?)
        `);

        const result = stmt.run(
            assignmentData.asset_id,
            assignmentData.user_id,
            assignmentData.assigned_by_user_id,
            assignmentData.notes || null,
            assignmentData.onboarding_protocol_id || null
        );

        return this.getById(result.lastInsertRowid);
    }

    /**
     * Mark assignment as returned
     */
    static markAsReturned(id, offboardingProtocolId = null) {
        const db = getDatabase();
        const stmt = db.prepare(`
            UPDATE asset_assignments
            SET returned_at = CURRENT_TIMESTAMP,
                offboarding_protocol_id = ?
            WHERE id = ?
        `);

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

    /**
     * Update assignment notes
     */
    static updateNotes(id, notes) {
        const db = getDatabase();
        const stmt = db.prepare(`
            UPDATE asset_assignments
            SET notes = ?
            WHERE id = ?
        `);

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

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

module.exports = AssetAssignment;
