import { ref, computed } from 'vue';
import { db } from '../db';
import axios from 'axios';
import { useNetworkStore } from '../stores/network';

const isSyncing = ref(false);
const syncError = ref(null);
const syncErrors = ref([]);
const lastSyncTime = ref(localStorage.getItem('last_pos_sync') || null);
const pendingTransactionsCount = ref(0);

export function useOfflineStore() {
    const networkStore = useNetworkStore();

    const isOnline = computed(() => networkStore.isOnline);

    const updatePendingCount = async () => {
        const count = await db.pending_transactions
            .where('status')
            .equals('PENDING')
            .count();
        pendingTransactionsCount.value = count;
        return count;
    };

    /**
     * Pull products from server and update local DB
     */
    const syncProducts = async (storeHash) => {
        if (!isOnline.value) return;
        
        try {
            isSyncing.value = true;
            const response = await axios.get('/POS/GetProducts', {
                params: { target: storeHash }
            });
            
            if (response.data && response.data.products) {
                // Bulk put (overwrite existing)
                await db.products.bulkPut(response.data.products);
                lastSyncTime.value = new Date().toISOString();
                localStorage.setItem('last_pos_sync', lastSyncTime.value);
            }
        } catch (err) {
            console.error('[OfflineStore] Failed to sync products:', err);
            syncError.value = err.message;
        } finally {
            isSyncing.value = false;
        }
    };

    /**
     * Store a completed transaction locally
     */
    const storeTransactionOffline = async (txnData) => {
        const result = await db.pending_transactions.add({
            ...txnData,
            timestamp: new Date().toISOString(),
            status: 'PENDING'
        });
        await updatePendingCount();
        return result;
    };

    /**
     * Push all pending local transactions to the server
     */
    const pushPendingTransactions = async () => {
        if (!networkStore.isOnline || isSyncing.value) return 0;

        const pendings = await db.pending_transactions
            .where('status')
            .equals('PENDING')
            .toArray();

        if (pendings.length === 0) {
            await updatePendingCount();
            return 0;
        }

        isSyncing.value = true;
        let syncedCount = 0;

        syncErrors.value = [];

        try {
            const validPendings = pendings.filter(txn => txn.store_hash);
            const skippedCount = pendings.length - validPendings.length;

            if (skippedCount > 0) {
                console.warn(`[OfflineStore] Skipping ${skippedCount} transactions with missing store_hash`);
            }

            if (validPendings.length === 0) {
                syncErrors.value = ['No valid transactions to sync (missing store reference)'];
                return 0;
            }

            const response = await axios.post('/api/pos/sync-offline', {
                transactions: validPendings.map(txn => ({
                    local_id: txn.id,
                    store_hash: txn.store_hash,
                    customer_name: txn.customer_name,
                    items: txn.items,
                    total: txn.total,
                    received: txn.received,
                    method: txn.method,
                    timestamp: txn.timestamp
                }))
            });

            if (response.data && response.data.success) {
                const { synced_count, synced_ids, errors } = response.data.data;
                syncedCount = synced_count;

                if (errors && errors.length > 0) {
                    console.error('[OfflineStore] Server sync errors:', errors);
                    syncErrors.value = errors;
                }

                if (synced_ids && synced_ids.length > 0) {
                    await db.pending_transactions.bulkUpdate(synced_ids.map(id => ({
                        key: id,
                        changes: { status: 'SYNCED' }
                    })));
                    await db.pending_transactions.where('status').equals('SYNCED').delete();
                }

                lastSyncTime.value = new Date().toLocaleTimeString();
            }
        } catch (error) {
            console.error('Offline Sync Failed:', error);
            syncErrors.value = [error?.response?.data?.message || error.message || 'Sync request failed'];
        } finally {
            isSyncing.value = false;
            await updatePendingCount();
        }

        return syncedCount;
    };

    /**
     * Search products locally
     */
    const searchProductsLocally = async (query, category = 'All') => {
        let collection = db.products;
        
        if (category !== 'All') {
            collection = collection.where('category').equals(category);
        } else {
            collection = collection.toCollection();
        }

        const products = await collection.toArray();
        if (!query) return products;

        const lowerQuery = query.toLowerCase();
        return products.filter(p => 
            p.name.toLowerCase().includes(lowerQuery) || 
            (p.barcode && p.barcode.includes(lowerQuery))
        );
    };

    return {
        isSyncing,
        syncError,
        syncErrors,
        lastSyncTime,
        pendingTransactionsCount,
        updatePendingCount,
        syncProducts,
        storeTransactionOffline,
        pushPendingTransactions,
        searchProductsLocally
    };
}
