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

class OnboardingProtocol {
    /**
     * Get all onboarding protocols with related information
     */
    static getAll() {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                op.*,
                e.username as employee_username,
                e.first_name as employee_sys_first_name,
                e.last_name as employee_sys_last_name,
                e.email as employee_email,
                r.name as employee_role_name,
                cu.username as created_by_username,
                uu.username as updated_by_username
            FROM onboarding_protocols op
            LEFT JOIN users e ON op.employee_user_id = e.id
            LEFT JOIN roles r ON e.role_id = r.id
            LEFT JOIN users cu ON op.created_by_user_id = cu.id
            LEFT JOIN users uu ON op.updated_by_user_id = uu.id
            ORDER BY op.created_at DESC
        `);
        return stmt.all();
    }

    /**
     * Get onboarding protocol by ID
     */
    static getById(id) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                op.*,
                e.username as employee_username,
                e.first_name as employee_sys_first_name,
                e.last_name as employee_sys_last_name,
                e.email as employee_email,
                r.name as employee_role_name,
                cu.username as created_by_username,
                uu.username as updated_by_username
            FROM onboarding_protocols op
            LEFT JOIN users e ON op.employee_user_id = e.id
            LEFT JOIN roles r ON e.role_id = r.id
            LEFT JOIN users cu ON op.created_by_user_id = cu.id
            LEFT JOIN users uu ON op.updated_by_user_id = uu.id
            WHERE op.id = ?
        `);
        return stmt.get(id);
    }

    /**
     * Get onboarding protocols by status
     */
    static getByStatus(status) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                op.*,
                e.username as employee_username,
                e.first_name as employee_first_name,
                e.last_name as employee_last_name,
                e.email as employee_email,
                cu.username as created_by_username
            FROM onboarding_protocols op
            INNER JOIN users e ON op.employee_user_id = e.id
            LEFT JOIN users cu ON op.created_by_user_id = cu.id
            WHERE op.status = ?
            ORDER BY op.created_at DESC
        `);
        return stmt.all(status);
    }

    /**
     * Get onboarding protocols for an employee
     */
    static getByEmployee(employeeUserId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            SELECT
                op.*,
                cu.username as created_by_username
            FROM onboarding_protocols op
            LEFT JOIN users cu ON op.created_by_user_id = cu.id
            WHERE op.employee_user_id = ?
            ORDER BY op.created_at DESC
        `);
        return stmt.all(employeeUserId);
    }

    /**
     * Create a new onboarding protocol
     */
    static create(protocolData) {
        const db = getDatabase();
        const stmt = db.prepare(`
            INSERT INTO onboarding_protocols (
                employee_user_id,
                emp_first_name,
                emp_last_name,
                emp_private_email,
                emp_phone,
                emp_address,
                department,
                position,
                work_location,
                hours_model,
                vacation_model,
                dept_contacts,
                status,
                start_date,
                checklist_data,
                notes,
                created_by_user_id
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        `);

        const result = stmt.run(
            protocolData.employee_user_id || null,
            protocolData.emp_first_name || null,
            protocolData.emp_last_name || null,
            protocolData.emp_private_email || null,
            protocolData.emp_phone || null,
            protocolData.emp_address || null,
            protocolData.department || null,
            protocolData.position || null,
            protocolData.work_location || null,
            protocolData.hours_model || null,
            protocolData.vacation_model || null,
            protocolData.dept_contacts || null,
            protocolData.status,
            protocolData.start_date,
            protocolData.checklist_data || null,
            protocolData.notes || null,
            protocolData.created_by_user_id
        );

        return this.getById(result.lastInsertRowid);
    }

    /**
     * Update onboarding protocol
     */
    static update(id, protocolData, updatedByUserId) {
        const db = getDatabase();

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

        const personalFields = ['emp_first_name', 'emp_last_name', 'emp_private_email', 'emp_phone',
            'emp_address', 'department', 'position', 'work_location', 'hours_model', 'vacation_model',
            'dept_contacts', 'employee_user_id'];
        for (const f of personalFields) {
            if (protocolData[f] !== undefined) {
                fields.push(`${f} = ?`);
                values.push(protocolData[f]);
            }
        }

        if (protocolData.status !== undefined) {
            fields.push('status = ?');
            values.push(protocolData.status);
        }
        if (protocolData.start_date !== undefined) {
            fields.push('start_date = ?');
            values.push(protocolData.start_date);
        }
        if (protocolData.completion_date !== undefined) {
            fields.push('completion_date = ?');
            values.push(protocolData.completion_date);
        }
        if (protocolData.checklist_data !== undefined) {
            fields.push('checklist_data = ?');
            values.push(protocolData.checklist_data);
        }
        if (protocolData.notes !== undefined) {
            fields.push('notes = ?');
            values.push(protocolData.notes);
        }
        if (protocolData.pdf_file_path !== undefined) {
            fields.push('pdf_file_path = ?');
            values.push(protocolData.pdf_file_path);
        }

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

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

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

    /**
     * Update checklist data
     */
    static updateChecklist(id, checklistData, updatedByUserId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            UPDATE onboarding_protocols
            SET checklist_data = ?,
                updated_by_user_id = ?,
                updated_at = CURRENT_TIMESTAMP
            WHERE id = ?
        `);

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

    /**
     * Update PDF file path
     */
    static updatePdfPath(id, pdfFilePath, updatedByUserId) {
        const db = getDatabase();
        const stmt = db.prepare(`
            UPDATE onboarding_protocols
            SET pdf_file_path = ?,
                updated_by_user_id = ?,
                updated_at = CURRENT_TIMESTAMP
            WHERE id = ?
        `);

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

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

    /**
     * Set confirm token for employee confirmation email
     */
    static setConfirmToken(id, token) {
        const db = getDatabase();
        db.prepare('UPDATE onboarding_protocols SET confirm_token = ? WHERE id = ?').run(token, id);
    }

    /**
     * Get protocol by confirm token (public, no auth)
     */
    static getByConfirmToken(token) {
        const db = getDatabase();
        return db.prepare('SELECT * FROM onboarding_protocols WHERE confirm_token = ?').get(token);
    }

    /**
     * Mark employee confirmation
     */
    static confirmByToken(token) {
        const db = getDatabase();
        const result = db.prepare(
            `UPDATE onboarding_protocols SET employee_confirmed_at = CURRENT_TIMESTAMP, status = 'completed', confirm_token = NULL WHERE confirm_token = ?`
        ).run(token);
        return result.changes > 0;
    }

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

        const totalStmt = db.prepare('SELECT COUNT(*) as total FROM onboarding_protocols');
        const pendingStmt = db.prepare("SELECT COUNT(*) as pending FROM onboarding_protocols WHERE status = 'pending'");
        const inProgressStmt = db.prepare("SELECT COUNT(*) as in_progress FROM onboarding_protocols WHERE status = 'in_progress'");
        const completedStmt = db.prepare("SELECT COUNT(*) as completed FROM onboarding_protocols WHERE status = 'completed'");

        return {
            total: totalStmt.get().total,
            pending: pendingStmt.get().pending,
            in_progress: inProgressStmt.get().in_progress,
            completed: completedStmt.get().completed
        };
    }
}

module.exports = OnboardingProtocol;
