<?php
/**
 * Accounting Helper for Automatic Journal Entries
 */

function createJournalEntry($date, $description, $reference, $source_type, $source_id, $items) {
    $db = db();
    try {
        $stmt = $db->prepare("INSERT INTO acc_journal_entries (entry_date, description, reference, source_type, source_id) VALUES (?, ?, ?, ?, ?)");
        $stmt->execute([$date, $description, $reference, $source_type, $source_id]);
        $entryId = $db->lastInsertId();

        $stmtLedger = $db->prepare("INSERT INTO acc_ledger (journal_entry_id, account_id, debit, credit) VALUES (?, ?, ?, ?)");
        foreach ($items as $item) {
            // Find account ID by code
            $stmtAcc = $db->prepare("SELECT id FROM acc_accounts WHERE code = ?");
            $stmtAcc->execute([$item['code']]);
            $accountId = $stmtAcc->fetchColumn();
            
            if ($accountId) {
                $stmtLedger->execute([$entryId, $accountId, $item['debit'] ?? 0, $item['credit'] ?? 0]);
            }
        }
        return $entryId;
    } catch (Exception $e) {
        error_log("Accounting Error: " . $e->getMessage());
        return false;
    }
}

/**
 * Record a Sale
 */
function recordSaleJournal($invoice_id, $amount, $date, $items_data = [], $vat_amount = 0) {
    $subtotal = $amount - $vat_amount;
    $entries = [
        ['code' => '1300', 'debit' => $amount], // Accounts Receivable (Asset increases)
        ['code' => '4100', 'credit' => $subtotal] // Sales Revenue (Revenue increases)
    ];

    if ($vat_amount > 0) {
        $entries[] = ['code' => '2300', 'credit' => $vat_amount]; // VAT Payable (Liability increases)
    }
    
    // Inventory & COGS
    $total_cogs = 0;
    foreach ($items_data as $item) {
        $stmt = db()->prepare("SELECT purchase_price FROM stock_items WHERE id = ?");
        $stmt->execute([$item['id']]);
        $cost = (float)$stmt->fetchColumn();
        $total_cogs += ($cost * $item['qty']);
    }
    
    if ($total_cogs > 0) {
        $entries[] = ['code' => '5100', 'debit' => $total_cogs]; // COGS (Expense increases)
        $entries[] = ['code' => '1400', 'credit' => $total_cogs]; // Inventory (Asset decreases)
    }

    return createJournalEntry($date, "Sale Invoice #$invoice_id", "INV-$invoice_id", 'invoice', $invoice_id, $entries);
}

/**
 * Record a Purchase
 */
function recordPurchaseJournal($invoice_id, $amount, $date, $items_data = [], $vat_amount = 0) {
    $subtotal = $amount - $vat_amount;
    $entries = [
        ['code' => '1400', 'debit' => $subtotal], // Inventory (Asset increases)
        ['code' => '2100', 'credit' => $amount] // Accounts Payable (Liability increases)
    ];

    if ($vat_amount > 0) {
        $entries[] = ['code' => '1500', 'debit' => $vat_amount]; // VAT Input (Asset increases)
    }

    return createJournalEntry($date, "Purchase Invoice #$invoice_id", "PINV-$invoice_id", 'invoice', $invoice_id, $entries);
}

/**
 * Record a Payment Received (from Customer)
 */
function recordPaymentReceivedJournal($payment_id, $amount, $date, $method) {
    $code = ($method === 'Bank' || $method === 'Transfer') ? '1200' : '1100';
    $entries = [
        ['code' => $code, 'debit' => $amount], // Cash/Bank (Asset increases)
        ['code' => '1300', 'credit' => $amount] // Accounts Receivable (Asset decreases)
    ];
    return createJournalEntry($date, "Payment Received #$payment_id", "PAY-$payment_id", 'payment', $payment_id, $entries);
}

/**
 * Record a Payment Made (to Supplier)
 */
function recordPaymentMadeJournal($payment_id, $amount, $date, $method) {
    $code = ($method === 'Bank' || $method === 'Transfer') ? '1200' : '1100';
    $entries = [
        ['code' => '2100', 'debit' => $amount], // Accounts Payable (Liability decreases)
        ['code' => $code, 'credit' => $amount] // Cash/Bank (Asset decreases)
    ];
    return createJournalEntry($date, "Payment Made #$payment_id", "PAY-$payment_id", 'payment', $payment_id, $entries);
}

/**
 * Record a Sales Return
 */
function recordSalesReturnJournal($return_id, $amount, $date) {
    $entries = [
        ['code' => '4100', 'debit' => $amount], // Sales Revenue (Revenue decreases) - ideally a "Sales Returns" account
        ['code' => '1300', 'credit' => $amount] // Accounts Receivable (Asset decreases)
    ];
    return createJournalEntry($date, "Sales Return #$return_id", "SRET-$return_id", 'sales_return', $return_id, $entries);
}

/**
 * Record a Purchase Return
 */
function recordPurchaseReturnJournal($return_id, $amount, $date) {
    $entries = [
        ['code' => '2100', 'debit' => $amount], // Accounts Payable (Liability decreases)
        ['code' => '1400', 'credit' => $amount] // Inventory (Asset decreases)
    ];
    return createJournalEntry($date, "Purchase Return #$return_id", "PRET-$return_id", 'purchase_return', $return_id, $entries);
}

/**
 * Record an Expense
 */
function recordExpenseJournal($expense_id, $amount, $date, $description, $method = 'Cash') {
    $paymentCode = ($method === 'Bank' || $method === 'Transfer') ? '1200' : '1100';
    $entries = [
        ['code' => '5200', 'debit' => $amount], // Operating Expenses (Expense increases)
        ['code' => $paymentCode, 'credit' => $amount] // Cash/Bank (Asset decreases)
    ];
    return createJournalEntry($date, "Expense: $description", "EXP-$expense_id", 'expense', $expense_id, $entries);
}

/**
 * Record Payroll Payment
 */
function recordPayrollJournal($payroll_id, $amount, $date, $emp_name) {
    $entries = [
        ['code' => '5200', 'debit' => $amount], // Using 5200 for now, or could use 5300 if added
        ['code' => '1100', 'credit' => $amount] // Paid in Cash
    ];
    return createJournalEntry($date, "Payroll Payment - $emp_name", "PAYROLL-$payroll_id", 'payroll', $payroll_id, $entries);
}

/**
 * Get Account Balance
 */
function getAccountBalance($code, $start_date = null, $end_date = null) {
    $db = db();
    $sql = "SELECT SUM(l.debit) - SUM(l.credit) as balance 
            FROM acc_ledger l 
            JOIN acc_accounts a ON l.account_id = a.id 
            JOIN acc_journal_entries e ON l.journal_entry_id = e.id 
            WHERE a.code LIKE ?";
    $params = [$code . '%'];
    
    if ($start_date) {
        $sql .= " AND e.entry_date >= ?";
        $params[] = $start_date;
    }
    if ($end_date) {
        $sql .= " AND e.entry_date <= ?";
        $params[] = $end_date;
    }
    
    $stmt = $db->prepare($sql);
    $stmt->execute($params);
    $balance = (float)$stmt->fetchColumn();
    
    // For Liability, Equity, Revenue: Balance = Credit - Debit
    $stmtType = $db->prepare("SELECT type FROM acc_accounts WHERE code = ?");
    $stmtType->execute([$code]);
    $type = $stmtType->fetchColumn();
    
    if (in_array($type, ['liability', 'equity', 'revenue'])) {
        return -$balance;
    }
    return $balance;
}

/**
 * Get VAT Report
 */
function getVatReport($start_date = null, $end_date = null) {
    $input_vat = getAccountBalance('1500', $start_date, $end_date);
    $output_vat = getAccountBalance('2300', $start_date, $end_date);
    
    return [
        'input_vat' => $input_vat,
        'output_vat' => $output_vat,
        'net_vat' => $output_vat - $input_vat
    ];
}

/**
 * Alias for Payroll Expense Journal
 */
function recordExpenseJournalForPayroll($payroll_id, $amount, $date) {
    $entries = [
        ['code' => '5200', 'debit' => $amount],
        ['code' => '1100', 'credit' => $amount]
    ];
    return createJournalEntry($date, "Payroll Expense #$payroll_id", "PAYROLL-$payroll_id", 'payroll', $payroll_id, $entries);
}
