import db from "../db.js"; // Get all contacts with optional filters export function getAllContacts(filters = {}) { let query = ` SELECT c.*, COUNT(DISTINCT pc.project_id) as project_count FROM contacts c LEFT JOIN project_contacts pc ON c.contact_id = pc.contact_id WHERE 1=1 `; const params = []; // Filter by active status if (filters.is_active !== undefined) { query += ` AND c.is_active = ?`; params.push(filters.is_active ? 1 : 0); } // Filter by contact type if (filters.contact_type) { query += ` AND c.contact_type = ?`; params.push(filters.contact_type); } // Search by name, phone, email, or company if (filters.search) { query += ` AND ( c.name LIKE ? OR c.phone LIKE ? OR c.email LIKE ? OR c.company LIKE ? )`; const searchTerm = `%${filters.search}%`; params.push(searchTerm, searchTerm, searchTerm, searchTerm); } query += ` GROUP BY c.contact_id ORDER BY c.name ASC`; return db.prepare(query).all(...params); } // Get contact by ID export function getContactById(contactId) { const contact = db .prepare( ` SELECT c.* FROM contacts c WHERE c.contact_id = ? ` ) .get(contactId); if (!contact) return null; // Get associated projects const projects = db .prepare( ` SELECT p.project_id, p.project_name, p.project_number, pc.relationship_type, pc.is_primary, pc.added_at FROM project_contacts pc JOIN projects p ON pc.project_id = p.project_id WHERE pc.contact_id = ? ORDER BY pc.is_primary DESC, pc.added_at DESC ` ) .all(contactId); return { ...contact, projects }; } // Create new contact export function createContact(data) { const stmt = db.prepare(` INSERT INTO contacts ( name, phone, email, company, position, contact_type, notes, is_active ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) `); const result = stmt.run( data.name, data.phone || null, data.email || null, data.company || null, data.position || null, data.contact_type || "other", data.notes || null, data.is_active !== undefined ? (data.is_active ? 1 : 0) : 1 ); return getContactById(result.lastInsertRowid); } // Update contact export function updateContact(contactId, data) { const updates = []; const params = []; if (data.name !== undefined) { updates.push("name = ?"); params.push(data.name); } if (data.phone !== undefined) { updates.push("phone = ?"); params.push(data.phone || null); } if (data.email !== undefined) { updates.push("email = ?"); params.push(data.email || null); } if (data.company !== undefined) { updates.push("company = ?"); params.push(data.company || null); } if (data.position !== undefined) { updates.push("position = ?"); params.push(data.position || null); } if (data.contact_type !== undefined) { updates.push("contact_type = ?"); params.push(data.contact_type); } if (data.notes !== undefined) { updates.push("notes = ?"); params.push(data.notes || null); } if (data.is_active !== undefined) { updates.push("is_active = ?"); params.push(data.is_active ? 1 : 0); } if (updates.length === 0) { return getContactById(contactId); } updates.push("updated_at = CURRENT_TIMESTAMP"); params.push(contactId); const query = `UPDATE contacts SET ${updates.join(", ")} WHERE contact_id = ?`; db.prepare(query).run(...params); return getContactById(contactId); } // Delete contact (soft delete by setting is_active = 0) export function deleteContact(contactId) { const stmt = db.prepare(` UPDATE contacts SET is_active = 0, updated_at = CURRENT_TIMESTAMP WHERE contact_id = ? `); return stmt.run(contactId); } // Hard delete contact (permanent deletion) export function hardDeleteContact(contactId) { // First remove all project associations db.prepare(`DELETE FROM project_contacts WHERE contact_id = ?`).run( contactId ); // Then delete the contact const stmt = db.prepare(`DELETE FROM contacts WHERE contact_id = ?`); return stmt.run(contactId); } // Get contacts for a specific project export function getProjectContacts(projectId) { return db .prepare( ` SELECT c.*, pc.relationship_type, pc.is_primary, pc.added_at, u.name as added_by_name FROM project_contacts pc JOIN contacts c ON pc.contact_id = c.contact_id LEFT JOIN users u ON pc.added_by = u.id WHERE pc.project_id = ? AND c.is_active = 1 ORDER BY pc.is_primary DESC, c.name ASC ` ) .all(projectId); } // Link contact to project export function linkContactToProject( projectId, contactId, relationshipType = "general", isPrimary = false, userId = null ) { const stmt = db.prepare(` INSERT OR REPLACE INTO project_contacts ( project_id, contact_id, relationship_type, is_primary, added_by ) VALUES (?, ?, ?, ?, ?) `); return stmt.run( projectId, contactId, relationshipType, isPrimary ? 1 : 0, userId ); } // Unlink contact from project export function unlinkContactFromProject(projectId, contactId) { const stmt = db.prepare(` DELETE FROM project_contacts WHERE project_id = ? AND contact_id = ? `); return stmt.run(projectId, contactId); } // Set primary contact for a project export function setPrimaryContact(projectId, contactId) { // First, remove primary flag from all contacts for this project db.prepare(` UPDATE project_contacts SET is_primary = 0 WHERE project_id = ? `).run(projectId); // Then set the specified contact as primary const stmt = db.prepare(` UPDATE project_contacts SET is_primary = 1 WHERE project_id = ? AND contact_id = ? `); return stmt.run(projectId, contactId); } // Get contact statistics export function getContactStats() { return db .prepare( ` SELECT COUNT(*) as total_contacts, COUNT(CASE WHEN is_active = 1 THEN 1 END) as active_contacts, COUNT(CASE WHEN is_active = 0 THEN 1 END) as inactive_contacts, COUNT(CASE WHEN contact_type = 'project' THEN 1 END) as project_contacts, COUNT(CASE WHEN contact_type = 'contractor' THEN 1 END) as contractor_contacts, COUNT(CASE WHEN contact_type = 'office' THEN 1 END) as office_contacts, COUNT(CASE WHEN contact_type = 'supplier' THEN 1 END) as supplier_contacts, COUNT(CASE WHEN contact_type = 'other' THEN 1 END) as other_contacts FROM contacts ` ) .get(); } // Search contacts by phone number export function searchContactsByPhone(phoneNumber) { const searchTerm = `%${phoneNumber}%`; return db .prepare( ` SELECT * FROM contacts WHERE phone LIKE ? AND is_active = 1 ORDER BY name ASC ` ) .all(searchTerm); } // Search contacts by email export function searchContactsByEmail(email) { const searchTerm = `%${email}%`; return db .prepare( ` SELECT * FROM contacts WHERE email LIKE ? AND is_active = 1 ORDER BY name ASC ` ) .all(searchTerm); } // Bulk link contacts to project export function bulkLinkContactsToProject(projectId, contactIds, userId = null) { const stmt = db.prepare(` INSERT OR IGNORE INTO project_contacts ( project_id, contact_id, added_by ) VALUES (?, ?, ?) `); const results = contactIds.map((contactId) => stmt.run(projectId, contactId, userId) ); return results; } // Get contacts not linked to a specific project (for selection) export function getAvailableContactsForProject(projectId) { return db .prepare( ` SELECT c.* FROM contacts c WHERE c.is_active = 1 AND c.contact_id NOT IN ( SELECT contact_id FROM project_contacts WHERE project_id = ? ) ORDER BY c.name ASC ` ) .all(projectId); }