<?php
// REST API for Toko Barokah Android Application Sync
// Enables real-time or batched synchronization of local data.

header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

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

require_once 'config.php';

$action = isset($_GET['action']) ? $_GET['action'] : '';

switch ($action) {
    case 'get_products':
        handleGetProducts($pdo);
        break;
        
    case 'sync_data':
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            sendResponse(false, 'Only POST method is allowed for sync_data');
        }
        handleSyncData($pdo);
        break;

    case 'get_dashboard_data':
        handleGetDashboardData($pdo);
        break;
        
    case 'test':
        sendResponse(true, 'REST API Connection Successful!');
        break;
        
    default:
        sendResponse(false, 'Invalid action parameter');
        break;
}

// --- API Handler Functions ---

// 1. Fetch current catalog from MySQL
function handleGetProducts($pdo) {
    try {
        $stmt = $pdo->query("
            SELECT p.id, p.barcode, p.name, p.buy_price, p.sell_price, p.stock, p.unit, p.category_id, c.name as category_name 
            FROM products p 
            LEFT JOIN categories c ON p.category_id = c.id 
            ORDER BY p.name ASC
        ");
        $products = $stmt->fetchAll();
        
        echo json_encode([
            'success' => true,
            'products' => $products
        ]);
    } catch (PDOException $e) {
        sendResponse(false, 'Failed to fetch products: ' . $e->getMessage());
    }
}

// 2. Receive and process batched transactions, products and attendance from Android
function handleSyncData($pdo) {
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);
    
    if (!$data) {
        sendResponse(false, 'Invalid JSON payload received');
    }
    
    $syncCount = [
        'products' => 0,
        'transactions' => 0,
        'attendance' => 0
    ];
    
    $pdo->beginTransaction();
    
    try {
        // Sync Categories first (if any)
        if (isset($data['categories']) && is_array($data['categories'])) {
            $catStmt = $pdo->prepare("INSERT INTO categories (id, name) VALUES (:id, :name) ON DUPLICATE KEY UPDATE name = :name");
            foreach ($data['categories'] as $cat) {
                $catStmt->execute([
                    ':id' => $cat['id'],
                    ':name' => $cat['name']
                ]);
            }
        }

        // Sync Products (catalog updates or new inventory from mobile)
        if (isset($data['products']) && is_array($data['products'])) {
            $prodStmt = $pdo->prepare("
                INSERT INTO products (id, barcode, name, buy_price, sell_price, stock, unit, category_id)
                VALUES (:id, :barcode, :name, :buy_price, :sell_price, :stock, :unit, :category_id)
                ON DUPLICATE KEY UPDATE 
                    name = :name,
                    buy_price = :buy_price,
                    sell_price = :sell_price,
                    stock = :stock,
                    unit = :unit,
                    category_id = :category_id
            ");
            
            foreach ($data['products'] as $prod) {
                $prodStmt->execute([
                    ':id' => $prod['id'],
                    ':barcode' => $prod['barcode'],
                    ':name' => $prod['name'],
                    ':buy_price' => $prod['buy_price'],
                    ':sell_price' => $prod['sell_price'],
                    ':stock' => $prod['stock'],
                    ':unit' => $prod['unit'],
                    ':category_id' => !empty($prod['category_id']) ? $prod['category_id'] : null
                ]);
                $syncCount['products']++;
            }
        }
        
        // Sync Transactions (the sales logs)
        if (isset($data['transactions']) && is_array($data['transactions'])) {
            $txStmt = $pdo->prepare("
                INSERT INTO transactions (invoice_no, user_id, total_amount, discount, grand_total, pay, change_amount, payment_type, customer_name, due_date, status, created_at)
                VALUES (:invoice_no, :user_id, :total_amount, :discount, :grand_total, :pay, :change_amount, :payment_type, :customer_name, :due_date, :status, :created_at)
                ON DUPLICATE KEY UPDATE 
                    pay = :pay,
                    change_amount = :change_amount,
                    status = :status
            ");
            
            $detailStmt = $pdo->prepare("
                INSERT INTO transaction_details (transaction_id, product_id, product_name, price, qty, subtotal)
                VALUES (:transaction_id, :product_id, :product_name, :price, :qty, :subtotal)
            ");
            
            $recStmt = $pdo->prepare("
                INSERT INTO receivables (transaction_id, customer_name, total_amount, paid_amount, due_date, status, created_at)
                VALUES (:transaction_id, :customer_name, :total_amount, :paid_amount, :due_date, :status, :created_at)
                ON DUPLICATE KEY UPDATE 
                    paid_amount = :paid_amount,
                    status = :status
            ");

            $stockUpdateStmt = $pdo->prepare("UPDATE products SET stock = GREATEST(0, stock - :qty) WHERE id = :product_id");

            foreach ($data['transactions'] as $tx) {
                // Check if transaction already exists in MySQL
                $chk = $pdo->prepare("SELECT id FROM transactions WHERE invoice_no = ?");
                $chk->execute([$tx['invoice_no']]);
                $existingTx = $chk->fetch();
                
                if ($existingTx) {
                    // Transaction exists, update payment status but skip detail insertion to avoid duplicates
                    $txStmt->execute([
                        ':invoice_no' => $tx['invoice_no'],
                        ':user_id' => $tx['user_id'],
                        ':total_amount' => $tx['total_amount'],
                        ':discount' => $tx['discount'],
                        ':grand_total' => $tx['grand_total'],
                        ':pay' => $tx['pay'],
                        ':change_amount' => $tx['change_amount'],
                        ':payment_type' => $tx['payment_type'],
                        ':customer_name' => $tx['customer_name'],
                        ':due_date' => !empty($tx['due_date']) ? $tx['due_date'] : null,
                        ':status' => $tx['status'],
                        ':created_at' => $tx['created_at']
                    ]);
                    $txId = $existingTx['id'];
                } else {
                    // Insert new transaction record
                    $txStmt->execute([
                        ':invoice_no' => $tx['invoice_no'],
                        ':user_id' => $tx['user_id'],
                        ':total_amount' => $tx['total_amount'],
                        ':discount' => $tx['discount'],
                        ':grand_total' => $tx['grand_total'],
                        ':pay' => $tx['pay'],
                        ':change_amount' => $tx['change_amount'],
                        ':payment_type' => $tx['payment_type'],
                        ':customer_name' => $tx['customer_name'],
                        ':due_date' => !empty($tx['due_date']) ? $tx['due_date'] : null,
                        ':status' => $tx['status'],
                        ':created_at' => $tx['created_at']
                    ]);
                    $txId = $pdo->lastInsertId();
                    
                    // Insert details and adjust MySQL product stocks
                    if (isset($tx['details']) && is_array($tx['details'])) {
                        foreach ($tx['details'] as $detail) {
                            $detailStmt->execute([
                                ':transaction_id' => $txId,
                                ':product_id' => !empty($detail['product_id']) ? $detail['product_id'] : null,
                                ':product_name' => $detail['product_name'],
                                ':price' => $detail['price'],
                                ':qty' => $detail['qty'],
                                ':subtotal' => $detail['subtotal']
                            ]);
                            
                            // Adjust stock in cloud
                            if (!empty($detail['product_id'])) {
                                $stockUpdateStmt->execute([
                                    ':qty' => $detail['qty'],
                                    ':product_id' => $detail['product_id']
                                ]);
                            }
                        }
                    }

                    // Create receivable record for credit payments
                    if ($tx['payment_type'] === 'piutang') {
                        $recStmt->execute([
                            ':transaction_id' => $txId,
                            ':customer_name' => !empty($tx['customer_name']) ? $tx['customer_name'] : 'Pelanggan Umum',
                            ':total_amount' => $tx['grand_total'],
                            ':paid_amount' => $tx['pay'],
                            ':due_date' => !empty($tx['due_date']) ? $tx['due_date'] : null,
                            ':status' => $tx['pay'] > 0 ? 'partial' : 'unpaid',
                            ':created_at' => $tx['created_at']
                        ]);
                    }
                }
                
                $syncCount['transactions']++;
            }
        }
        
        // Sync Attendance Logs
        if (isset($data['attendance']) && is_array($data['attendance'])) {
            $attStmt = $pdo->prepare("
                INSERT INTO attendance (user_id, check_in, check_out, date, status, notes)
                VALUES (:user_id, :check_in, :check_out, :date, :status, :notes)
                ON DUPLICATE KEY UPDATE 
                    check_out = :check_out,
                    status = :status,
                    notes = :notes
            ");
            
            foreach ($data['attendance'] as $att) {
                $attStmt->execute([
                    ':user_id' => $att['user_id'],
                    ':check_in' => $att['check_in'],
                    ':check_out' => !empty($att['check_out']) ? $att['check_out'] : null,
                    ':date' => $att['date'],
                    ':status' => $att['status'],
                    ':notes' => $att['notes']
                ]);
                $syncCount['attendance']++;
            }
        }
        
        $pdo->commit();
        
        echo json_encode([
            'success' => true,
            'message' => 'Sync operation complete.',
            'synced' => $syncCount
        ]);
        
    } catch (Exception $e) {
        $pdo->rollBack();
        sendResponse(false, 'Transaction failed: ' . $e->getMessage());
    }
}

// Utility Response Helper
function sendResponse($success, $message) {
    echo json_encode([
        'success' => $success,
        'message' => $message
    ]);
    exit();
}

// 3. Fetch specific transaction details for web dashboard modal
function handleGetDashboardData($pdo) {
    $txId = isset($_GET['tx_id']) ? intval($_GET['tx_id']) : 0;
    if ($txId <= 0) {
        sendResponse(false, 'Missing or invalid tx_id parameter');
    }
    
    try {
        // Fetch transaction details
        $stmt = $pdo->prepare("
            SELECT t.id, t.invoice_no, u.name as cashier_name, t.total_amount, t.discount, t.grand_total, t.pay, t.change_amount, t.payment_type, t.customer_name, t.due_date, t.status, t.created_at 
            FROM transactions t 
            JOIN users u ON t.user_id = u.id 
            WHERE t.id = ?
        ");
        $stmt->execute([$txId]);
        $transaction = $stmt->fetch();
        
        if (!$transaction) {
            sendResponse(false, 'Transaction not found');
        }
        
        // Format timestamp
        $transaction['created_at'] = date('d M Y H:i', strtotime($transaction['created_at']));
        
        // Fetch items
        $stmt = $pdo->prepare("
            SELECT id, product_id, product_name, price, qty, subtotal 
            FROM transaction_details 
            WHERE transaction_id = ?
        ");
        $stmt->execute([$txId]);
        $details = $stmt->fetchAll();
        
        echo json_encode([
            'success' => true,
            'transaction' => $transaction,
            'details' => $details
        ]);
    } catch (PDOException $e) {
        sendResponse(false, 'Failed to fetch details: ' . $e->getMessage());
    }
}
?>
