import * as SQLite from 'expo-sqlite';
import { API_BASE_URL } from './config';

type Action={id:number;clientActionId:string;type:string;payload:string;queuedAt:string;attempts:number};
const db=SQLite.openDatabaseSync('colorjet_sync.db');
export async function initOfflineQueue(){await db.execAsync(`CREATE TABLE IF NOT EXISTS sync_queue (id INTEGER PRIMARY KEY AUTOINCREMENT,client_action_id TEXT UNIQUE NOT NULL,type TEXT NOT NULL,payload TEXT NOT NULL,queued_at TEXT NOT NULL,attempts INTEGER NOT NULL DEFAULT 0,last_error TEXT);`);}
export async function enqueue(type:'ticket.start'|'ticket.note'|'ticket.complete',payload:Record<string,unknown>){const clientActionId=`mob-${Date.now()}-${Math.random().toString(36).slice(2,10)}`;await db.runAsync('INSERT INTO sync_queue (client_action_id,type,payload,queued_at) VALUES (?,?,?,?)',[clientActionId,type,JSON.stringify(payload),new Date().toISOString()]);return clientActionId;}
export async function pendingCount(){const r=await db.getFirstAsync<{count:number}>('SELECT COUNT(*) AS count FROM sync_queue');return Number(r?.count??0);}
export async function flushQueue(accessToken:string){const actions=await db.getAllAsync<Action>('SELECT id,client_action_id AS "clientActionId",type,payload,queued_at AS "queuedAt",attempts FROM sync_queue ORDER BY id LIMIT 50');if(!actions.length)return {flushed:0,failed:0};const body={actions:actions.map(a=>({clientActionId:a.clientActionId,type:a.type,payload:JSON.parse(a.payload),queuedAt:a.queuedAt}))};try{const r=await fetch(`${API_BASE_URL}/sync/push`,{method:'POST',headers:{'Content-Type':'application/json',Authorization:`Bearer ${accessToken}`,'X-Device-Name':'COLORJET Engineer Android'},body:JSON.stringify(body)});const data=await r.json();if(!r.ok||!data?.ok)throw new Error(data?.error?.message||'Sync rejected');let flushed=0,failed=0;for(const outcome of data.data.outcomes as Array<any>){const action=actions.find(a=>a.clientActionId===outcome.clientActionId);if(!action)continue;if(['applied','duplicate'].includes(outcome.status)){await db.runAsync('DELETE FROM sync_queue WHERE id=?',[action.id]);flushed++;}else{await db.runAsync('UPDATE sync_queue SET attempts=attempts+1,last_error=? WHERE id=?',[outcome.error||'Server rejected action',action.id]);failed++;}}return {flushed,failed};}catch(error){for(const action of actions)await db.runAsync('UPDATE sync_queue SET attempts=attempts+1,last_error=? WHERE id=?',[error instanceof Error?error.message:'Network unavailable',action.id]);return {flushed:0,failed:actions.length};}}
