import * as SQLite from 'expo-sqlite'; import { Contact } from '@/store/useContactStore'; import { dbToContact } from '@/lib/contactHelpers'; let db: SQLite.SQLiteDatabase | null = null; export async function getDatabase(): Promise { if (!db) { db = await SQLite.openDatabaseAsync('territorylog.db'); await initSchema(db); } return db; } async function initSchema(database: SQLite.SQLiteDatabase): Promise { await database.execAsync(` PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON; CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, display_name TEXT NOT NULL, share_id TEXT UNIQUE NOT NULL, is_self INTEGER DEFAULT 1, created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS territories ( id TEXT PRIMARY KEY, territory_code TEXT UNIQUE NOT NULL, municipality TEXT, barangay TEXT, area TEXT, block TEXT, assigned_to TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS contacts ( id TEXT PRIMARY KEY, owner_id TEXT NOT NULL, full_name TEXT NOT NULL, address TEXT, household_count INTEGER DEFAULT 1, gender TEXT, category TEXT NOT NULL, status TEXT DEFAULT 'Active', tags TEXT DEFAULT '[]', notes TEXT, territory_code TEXT REFERENCES territories(territory_code), latitude REAL, longitude REAL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, deleted_at INTEGER ); CREATE TABLE IF NOT EXISTS visits ( id TEXT PRIMARY KEY, contact_id TEXT NOT NULL REFERENCES contacts(id), visited_by_name TEXT NOT NULL, visited_by_id TEXT NOT NULL, visit_date INTEGER NOT NULL, topic TEXT, response TEXT, remarks TEXT, next_visit_date INTEGER, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS topics ( id TEXT PRIMARY KEY, name TEXT UNIQUE NOT NULL, is_default INTEGER DEFAULT 0, created_at INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS sync_log ( id TEXT PRIMARY KEY, partner_id TEXT NOT NULL, partner_name TEXT, synced_at INTEGER NOT NULL, sent_count INTEGER DEFAULT 0, received_count INTEGER DEFAULT 0 ); CREATE INDEX IF NOT EXISTS idx_contacts_name ON contacts(full_name); CREATE INDEX IF NOT EXISTS idx_contacts_status ON contacts(status); CREATE INDEX IF NOT EXISTS idx_contacts_territory ON contacts(territory_code); CREATE INDEX IF NOT EXISTS idx_visits_contact ON visits(contact_id); CREATE INDEX IF NOT EXISTS idx_visits_date ON visits(visit_date); `); // Seed default topics const now = Math.floor(Date.now() / 1000); const defaultTopics = [ { id: 't1', name: 'The Kingdom of God' }, { id: 't2', name: 'Paradise Earth' }, { id: 't3', name: 'Life After Death' }, { id: 't4', name: "The Bible's Reliability" }, { id: 't5', name: "God's Name (Jehovah)" }, { id: 't6', name: 'Why Bad Things Happen' }, { id: 't7', name: 'Jesus Christ' }, { id: 't8', name: 'The Resurrection' }, { id: 't9', name: 'Family Happiness' }, ]; for (const topic of defaultTopics) { await database.runAsync( 'INSERT OR IGNORE INTO topics (id, name, is_default, created_at) VALUES (?, ?, 1, ?)', [topic.id, topic.name, now] ); } } // ── Map helpers ────────────────────────────────────────────────────────────── export async function getContactsWithGPS(): Promise { const database = await getDatabase(); const result = await database.getAllAsync( `SELECT * FROM contacts WHERE latitude IS NOT NULL AND longitude IS NOT NULL AND deleted_at IS NULL ORDER BY full_name` ); return result.map(dbToContact); } export async function getAllContactsForMap(): Promise { const database = await getDatabase(); const result = await database.getAllAsync( `SELECT * FROM contacts WHERE deleted_at IS NULL ORDER BY full_name` ); return result.map(dbToContact); }