<?php
// File: /public_html/erp.jewellersbd.com/api/cash/cash_transaction_update.php
// Cash Module 2.0 — edit a MANUAL cash transaction
// Audit Added: cash_transactions UPDATE

header("Content-Type: application/json; charset=UTF-8");

require_once __DIR__ . '/../../config/session.php';
require_once __DIR__ . '/../../config/db.php';

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

function ctu_send($ok, $msg, $data = null, $code = 200)
{
    http_response_code($code);
    echo json_encode([
        "success" => $ok,
        "message" => $msg,
        "data" => $data
    ], JSON_UNESCAPED_UNICODE);
    exit;
}

/**
 * Safe Audit Logger
 * Audit fail হলেও cash update বন্ধ হবে না।
 */
function ctu_safe_audit_log($pdo, $tableName, $recordId, $action, $changedBy, $note = '')
{
    try {
        if (!$pdo || !($pdo instanceof PDO)) {
            return;
        }

        $ipAddress = $_SERVER['REMOTE_ADDR'] ?? '';

        $stmt = $pdo->prepare("
            INSERT INTO audit_log
                (table_name, record_id, action, changed_by, changed_at, ip_address, note)
            VALUES
                (:table_name, :record_id, :action, :changed_by, NOW(), :ip_address, :note)
        ");

        $stmt->execute([
            ':table_name' => $tableName,
            ':record_id'  => (int)$recordId,
            ':action'     => $action,
            ':changed_by' => (int)$changedBy,
            ':ip_address' => $ipAddress,
            ':note'       => $note
        ]);

    } catch (Throwable $e) {
        return;
    }
}

// --- auth ---
if (
    (!isset($_SESSION['user_id']) || empty($_SESSION['user_id'])) &&
    (!function_exists('is_logged_in') || !is_logged_in())
) {
    ctu_send(false, "লগইন প্রয়োজন", null, 401);
}

if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
    ctu_send(false, "Invalid method", null, 405);
}

$in = json_decode(file_get_contents('php://input'), true);

if (!is_array($in)) {
    ctu_send(false, "Invalid JSON", null, 400);
}

// --- inputs ---
$id         = (int)($in['id'] ?? 0);
$txnDate    = trim((string)($in['transaction_date'] ?? ''));
$categoryId = (int)($in['category_id'] ?? 0);
$direction  = strtoupper(trim((string)($in['direction'] ?? '')));
$amount     = round((float)($in['amount'] ?? 0), 2);
$note       = trim((string)($in['note'] ?? ''));
$partyId    = (isset($in['party_id']) && (int)$in['party_id'] > 0) ? (int)$in['party_id'] : null;

$userId = (int)($_SESSION['user_id'] ?? 0);

// --- validation ---
if ($id <= 0) {
    ctu_send(false, "id দিন", null, 422);
}

if ($txnDate === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $txnDate)) {
    ctu_send(false, "সঠিক তারিখ দিন (YYYY-MM-DD)", null, 422);
}

if ($categoryId <= 0) {
    ctu_send(false, "ক্যাটাগরি নির্বাচন করুন", null, 422);
}

if (!in_array($direction, ['IN', 'OUT'], true)) {
    ctu_send(false, "ধরন IN অথবা OUT হতে হবে", null, 422);
}

if ($amount <= 0) {
    ctu_send(false, "টাকার পরিমাণ ০ এর বেশি হতে হবে", null, 422);
}

try {
    // fetch existing
    $st = $pdo->prepare("
        SELECT 
            id,
            cash_account_id,
            transaction_date,
            category_id,
            direction,
            amount,
            note,
            party_id,
            reference_type,
            is_locked,
            is_deleted,
            voucher_no
        FROM cash_transactions 
        WHERE id = ? 
        LIMIT 1
    ");
    $st->execute([$id]);
    $txn = $st->fetch();

    if (!$txn) {
        ctu_send(false, "লেনদেন পাওয়া যায়নি", null, 404);
    }

    if ((int)$txn['is_deleted'] === 1) {
        ctu_send(false, "মুছে ফেলা লেনদেন সম্পাদনা করা যাবে না", null, 422);
    }

    if ((int)$txn['is_locked'] === 1) {
        ctu_send(false, "দিন বন্ধ (locked) — এই এন্ট্রি সম্পাদনা করা যাবে না", null, 422);
    }

    if ((string)$txn['reference_type'] !== 'MANUAL') {
        ctu_send(false, "এই এন্ট্রিটি " . $txn['reference_type'] . " এর সাথে যুক্ত — সংশ্লিষ্ট মডিউল থেকে পরিবর্তন করুন", null, 422);
    }

    // category must exist & be active
    $cs = $pdo->prepare("
        SELECT id 
        FROM cash_categories 
        WHERE id = ? AND is_active = 1 
        LIMIT 1
    ");
    $cs->execute([$categoryId]);

    if (!$cs->fetch()) {
        ctu_send(false, "ক্যাটাগরি সঠিক নয় বা নিষ্ক্রিয়", null, 422);
    }

    // party optional
    if ($partyId !== null) {
        $ps = $pdo->prepare("
            SELECT id 
            FROM parties 
            WHERE id = ? AND deleted_at IS NULL 
            LIMIT 1
        ");
        $ps->execute([$partyId]);

        if (!$ps->fetch()) {
            ctu_send(false, "পার্টি পাওয়া যায়নি", null, 422);
        }
    }

    $accountId = (int)$txn['cash_account_id'];

    $changes = [];

    if ((string)$txn['transaction_date'] !== $txnDate) {
        $changes[] = 'তারিখ: ' . $txn['transaction_date'] . ' → ' . $txnDate;
    }

    if ((int)$txn['category_id'] !== $categoryId) {
        $changes[] = 'ক্যাটাগরি#: ' . $txn['category_id'] . ' → ' . $categoryId;
    }

    if ((string)$txn['direction'] !== $direction) {
        $changes[] = 'ধরন: ' . $txn['direction'] . ' → ' . $direction;
    }

    if (abs((float)$txn['amount'] - $amount) > 0.001) {
        $changes[] = 'পরিমাণ: ' . number_format((float)$txn['amount'], 2) . ' → ' . number_format($amount, 2);
    }

    if ((int)($txn['party_id'] ?? 0) !== (int)($partyId ?? 0)) {
        $changes[] = 'পার্টি#: ' . ($txn['party_id'] ?? '-') . ' → ' . ($partyId ?? '-');
    }

    if ((string)($txn['note'] ?? '') !== $note) {
        $changes[] = 'নোট পরিবর্তিত';
    }

    $pdo->beginTransaction();

    $upd = $pdo->prepare("
        UPDATE cash_transactions
        SET 
            transaction_date = ?,
            category_id = ?,
            direction = ?,
            amount = ?,
            party_id = ?,
            note = ?,
            updated_by = ?
        WHERE id = ?
          AND reference_type = 'MANUAL'
          AND is_locked = 0
          AND is_deleted = 0
    ");

    $upd->execute([
        $txnDate,
        $categoryId,
        $direction,
        $amount,
        $partyId,
        ($note !== '' ? $note : null),
        $userId,
        $id
    ]);

    if ($upd->rowCount() === 0) {
        $pdo->rollBack();
        ctu_send(false, "কোনো পরিবর্তন প্রয়োগ হয়নি (লেনদেন সম্পাদনযোগ্য নয় বা অপরিবর্তিত)", null, 422);
    }

    // recalc balance
    if (function_exists('gs_recalc_cash_account')) {
        gs_recalc_cash_account($pdo, $accountId);
    }

    $auditNote = "Manual cash transaction updated"
        . " | Voucher: " . ($txn['voucher_no'] ?? '')
        . " | " . ($changes ? implode(' | ', $changes) : 'No field changed');

    ctu_safe_audit_log(
        $pdo,
        'cash_transactions',
        $id,
        'UPDATE',
        $userId,
        $auditNote
    );

    $pdo->commit();

    $bs = $pdo->prepare("
        SELECT account_name, current_balance 
        FROM cash_accounts 
        WHERE id = ? 
        LIMIT 1
    ");
    $bs->execute([$accountId]);
    $b = $bs->fetch() ?: [];

    ctu_send(true, "লেনদেন আপডেট হয়েছে", [
        "id"           => $id,
        "account_name" => $b['account_name'] ?? '',
        "new_balance"  => round((float)($b['current_balance'] ?? 0), 2)
    ]);

} catch (Throwable $e) {
    if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
        $pdo->rollBack();
    }

    ctu_send(false, "সার্ভার সমস্যা: " . $e->getMessage(), null, 500);
}
?>