<?php
/**
 * ITRPOS Sales Journal Handler
 * Creates proper double-entry journal entries for sales transactions
 * Located in handlers folder for better organization
 */

require_once dirname(__DIR__) . '/financial_helpers.php';

/**
 * Create journal entry for sales transaction
 * @param mysqli $conn Database connection
 * @param int $sale_id Sale ID
 * @param float $total_amount Total sale amount
 * @param float $cost_amount Cost of goods sold (optional)
 * @param string $payment_method Payment method (cash, card, bank, etc.)
 * @param int $store_id Store ID (default 1)
 * @return bool Success status
 */
function createSalesJournalEntry($conn, $sale_id, $total_amount, $cost_amount = 0, $payment_method = 'cash', $store_id = 1) {
    try {
        // Check if journal entry already exists for this sale
        $check_stmt = $conn->prepare("SELECT id FROM journal_entries WHERE source_type = 'sale' AND reference_id = ? AND status = 'posted'");
        $check_stmt->bind_param("i", $sale_id);
        $check_stmt->execute();
        $result = $check_stmt->get_result();
        
        if ($result->num_rows > 0) {
            error_log("Journal entry already exists for sale #$sale_id");
            return true; // Already processed
        }
        $check_stmt->close();

        // Create journal entry
        $journal_entry_id = createJournalEntry($conn, 'sale', $sale_id, "Sale transaction #$sale_id", $store_id);
        
        if (!$journal_entry_id) {
            throw new Exception("Failed to create journal entry for sale #$sale_id");
        }
        
        // Get account mappings
        $cash_account_id = getAccountIdByMapping($conn, 'ast_Cash');
        if ($payment_method === 'card' || $payment_method === 'bank') {
            $cash_account_id = getAccountIdByMapping($conn, 'ast_Bank');
        }
        
        if (!$cash_account_id) {
            throw new Exception("Cash/Bank account not found for payment method: $payment_method");
        }
        
        // Get sales revenue account
        $sales_account_id = getAccountIdByMapping($conn, 'rev_Sale');
        if (!$sales_account_id) {
            throw new Exception("Sales revenue account not found");
        }
        
        // Create journal lines
        // Debit: Cash/Bank
        createJournalLine($conn, $journal_entry_id, $cash_account_id, $total_amount, 0, "Cash receipt for sale #$sale_id");
        
        // Credit: Sales Revenue
        createJournalLine($conn, $journal_entry_id, $sales_account_id, 0, $total_amount, "Sales revenue for sale #$sale_id");
        
        // Handle Cost of Goods Sold if provided
        if ($cost_amount > 0) {
            $cost_account_id = getAccountIdByMapping($conn, 'exp_CostOfSales');
            $inventory_account_id = getAccountIdByMapping($conn, 'ast_Stock');
            
            if (!$cost_account_id) {
                throw new Exception("Cost of sales account not found");
            }
            if (!$inventory_account_id) {
                throw new Exception("Inventory account not found");
            }
            
            // Debit: Cost of Sales
            createJournalLine($conn, $journal_entry_id, $cost_account_id, $cost_amount, 0, "Cost of sales for sale #$sale_id");
            
            // Credit: Inventory
            createJournalLine($conn, $journal_entry_id, $inventory_account_id, 0, $cost_amount, "Inventory reduction for sale #$sale_id");
        }
        
        // Post the journal entry
        $posted = postJournalEntry($conn, $journal_entry_id);
        
        if ($posted) {
            error_log("Successfully created journal entry #$journal_entry_id for sale #$sale_id");
            return true;
        } else {
            throw new Exception("Failed to post journal entry #$journal_entry_id");
        }
        
    } catch (Exception $e) {
        error_log("Sales journal entry error for sale #$sale_id: " . $e->getMessage());
        return false;
    }
}

/**
 * Calculate cost of goods sold for a sale
 * @param mysqli $conn Database connection
 * @param int $sale_id Sale ID
 * @return float Total cost amount
 */
function calculateSaleCost($conn, $sale_id) {
    $total_cost = 0;
    
    try {
        // Get sale items with their cost prices
        $stmt = $conn->prepare("
            SELECT si.quantity, i.cost_price
            FROM sale_items si
            JOIN items i ON si.item_id = i.id
            WHERE si.sale_id = ?
        ");
        $stmt->bind_param("i", $sale_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        while ($row = $result->fetch_assoc()) {
            $total_cost += $row['quantity'] * $row['cost_price'];
        }
        $stmt->close();
        
    } catch (Exception $e) {
        error_log("Error calculating cost for sale #$sale_id: " . $e->getMessage());
    }
    
    return $total_cost;
}

/**
 * Process sales journal entries for existing sales (backfill)
 * @param mysqli $conn Database connection
 * @param int $limit Number of sales to process (default 100)
 * @return array Processing results
 */
function processExistingSalesJournalEntries($conn, $limit = 100) {
    $results = [
        'processed' => 0,
        'success' => 0,
        'errors' => 0,
        'errors_list' => []
    ];
    
    try {
        // Get sales that don't have journal entries yet
        $stmt = $conn->prepare("
            SELECT s.id, s.total_amount, s.payment_method, s.store_id
            FROM sales s
            LEFT JOIN journal_entries je ON je.source_type = 'sale' AND je.reference_id = s.id
            WHERE je.id IS NULL 
            AND s.payment_method != 'void'
            ORDER BY s.id ASC
            LIMIT ?
        ");
        $stmt->bind_param("i", $limit);
        $stmt->execute();
        $result = $stmt->get_result();
        
        while ($sale = $result->fetch_assoc()) {
            $results['processed']++;
            
            // Calculate cost of goods sold
            $cost_amount = calculateSaleCost($conn, $sale['id']);
            
            // Create journal entry
            $success = createSalesJournalEntry(
                $conn, 
                $sale['id'], 
                $sale['total_amount'], 
                $cost_amount, 
                $sale['payment_method'], 
                $sale['store_id']
            );
            
            if ($success) {
                $results['success']++;
            } else {
                $results['errors']++;
                $results['errors_list'][] = "Sale #" . $sale['id'];
            }
        }
        $stmt->close();
        
    } catch (Exception $e) {
        error_log("Error processing existing sales: " . $e->getMessage());
        $results['errors']++;
        $results['errors_list'][] = "General error: " . $e->getMessage();
    }
    
    return $results;
}
