<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Sync Controller
 * Handles offline/online data synchronization
 */
class Sync extends MY_Controller
{
    
    public function __construct()
    {
        parent::__construct();
        $this->CI =& get_instance();
        $this->load->helper('data_sync');
        $this->load->helper('dual_mode');
    }

    /**
     * Auto-sync endpoint - syncs offline transactions
     */
    public function auto_sync()
    {
        header('Content-Type: application/json');
        
        if (!$this->session->userdata('user_id')) {
            echo json_encode(['success' => false, 'message' => 'Unauthorized']);
            return;
        }

        try {
            $transaction_type = $this->input->post('transaction_type');
            $transaction_data = $this->input->post('transaction_data');
            $transaction_id = $this->input->post('transaction_id');
            $timestamp = $this->input->post('timestamp');

            // Decode transaction data
            $data = json_decode($transaction_data, true);
            
            if (!$data) {
                echo json_encode(['success' => false, 'message' => 'Invalid transaction data']);
                return;
            }

            // Process transaction based on type
            $result = $this->processOfflineTransaction($transaction_type, $data);

            echo json_encode([
                'success' => true,
                'message' => 'Transaction synced successfully',
                'transaction_id' => $transaction_id,
                'details' => $result
            ]);

        } catch (Exception $e) {
            log_message('error', 'Auto-sync failed: ' . $e->getMessage());
            echo json_encode(['success' => false, 'message' => $e->getMessage()]);
        }
    }

    /**
     * Process offline transaction based on type
     */
    private function processOfflineTransaction($type, $data) {
        switch ($type) {
            case 'sale':
                return $this->processOfflineSale($data);
            case 'purchase':
                return $this->processOfflinePurchase($data);
            case 'return':
                return $this->processOfflineReturn($data);
            case 'purchase_return':
                return $this->processOfflinePurchaseReturn($data);
            default:
                return ['success' => false, 'message' => 'Unknown transaction type'];
        }
    }

    /**
     * Process offline sale
     */
    private function processOfflineSale($data) {
        // Example: Insert sale into database
        // In real implementation, you would insert into db_sales table
        return ['success' => true, 'message' => 'Sale synced'];
    }

    /**
     * Process offline purchase
     */
    private function processOfflinePurchase($data) {
        // Example: Insert purchase into database
        return ['success' => true, 'message' => 'Purchase synced'];
    }

    /**
     * Process offline return
     */
    private function processOfflineReturn($data) {
        return ['success' => true, 'message' => 'Return synced'];
    }

    /**
     * Process offline purchase return
     */
    private function processOfflinePurchaseReturn($data) {
        return ['success' => true, 'message' => 'Purchase return synced'];
    }

    /**
     * Sync a single item from queue
     */
    private function syncItem($item)
    {
        try {
            $url = isset($item['url']) ? $item['url'] : '';
            $method = isset($item['method']) ? $item['method'] : 'POST';
            $data = isset($item['data']) ? $item['data'] : [];

            // Here you would implement the actual sync logic
            // For now, simulate success
            return [
                'success' => true,
                'url' => $url,
                'records_synced' => 1
            ];

        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    /**
     * Get sync status
     * This endpoint is used to check if the server is reachable (connection check)
     * It should be lightweight and not require authentication for basic connectivity check
     */
    public function status()
    {
        header('Content-Type: application/json');
        // Allow CORS for connection checks
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: GET, OPTIONS');
        header('Access-Control-Allow-Headers: X-Requested-With');

        // Handle preflight OPTIONS request
        if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
            http_response_code(200);
            exit;
        }

        try {
            // Simple response to indicate server is reachable
            // Don't require authentication for basic connectivity check
            echo json_encode([
                'success' => true,
                'online' => true,
                'timestamp' => date('Y-m-d H:i:s')
            ]);

        } catch (Exception $e) {
            // Even on error, if we can respond, we're online
            echo json_encode([
                'success' => true,
                'online' => true,
                'error' => $e->getMessage(),
                'timestamp' => date('Y-m-d H:i:s')
            ]);
        }
    }

    /**
     * Manual sync trigger
     */
    public function manual()
    {
        header('Content-Type: application/json');
        
        // Check if user is authenticated
        if (!$this->session->userdata('user_id')) {
            echo json_encode([
                'success' => false,
                'message' => 'Unauthorized'
            ]);
            return;
        }

        try {
            $sync_helper = new Data_sync_helper();
            
            // Perform bidirectional sync
            $result = $sync_helper->manual_sync_with_conflicts('offline_to_online');
            
            echo json_encode($result);

        } catch (Exception $e) {
            echo json_encode([
                'success' => false,
                'message' => 'Manual sync failed: ' . $e->getMessage()
            ]);
        }
    }

    /**
     * Check connection status
     */
    public function check_connection()
    {
        header('Content-Type: application/json');
        
        try {
            $sync_helper = new Data_sync_helper();
            $is_accessible = $sync_helper->is_online_accessible();
            
            echo json_encode([
                'success' => true,
                'isOnline' => $is_accessible,
                'timestamp' => date('Y-m-d H:i:s')
            ]);

        } catch (Exception $e) {
            echo json_encode([
                'success' => false,
                'isOnline' => false,
                'message' => $e->getMessage()
            ]);
        }
    }

    /**
     * Get pending sync items count
     */
    public function queue_status()
    {
        header('Content-Type: application/json');
        
        echo json_encode([
            'success' => true,
            'queue_count' => 0, // This would be retrieved from actual queue implementation
            'sync_in_progress' => false
        ]);
    }

    /**
     * Clear sync queue
     */
    public function clear_queue()
    {
        header('Content-Type: application/json');
        
        // In a real implementation, this would clear the actual queue
        echo json_encode([
            'success' => true,
            'message' => 'Queue cleared successfully'
        ]);
    }
}

