<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Content-Type: application/json");

include 'connection.php';
require 'vendor/autoload.php';

use \Firebase\JWT\JWT;
use \Firebase\JWT\Key;
use \Firebase\JWT\ExpiredException;

$secret_key = "1ED495A77B65435D317B3E6582E4C";

if ($conn->connect_error) {
    echo json_encode(['success' => false, 'message' => 'Connection failed: ' . $conn->connect_error]);
    exit;
}

$headers = apache_request_headers();
if (isset($headers['Authorization'])) {
    list($jwt) = sscanf($headers['Authorization'], 'Bearer %s');
} else {
    echo json_encode(["success" => false, "message" => "Authorization header missing"]);
    exit;
}

try {
    $decoded = JWT::decode($jwt, new Key($secret_key, 'HS256'));
    $company_id = $decoded->data->companyId;

    /* =======================  GET — FETCH PAYMENTS  ======================= */

    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        // Check if we need to get last payment details for a deposit
        if (isset($_GET['deposit_no']) && isset($_GET['get_last_payment']) && $_GET['get_last_payment'] === 'true') {
            $deposit_no = $_GET['deposit_no'];
            
            // Fetch deposit details
            $deposit_stmt = $conn->prepare("SELECT * FROM deposit_entry WHERE com_id=? AND deposit_no=?");
            $deposit_stmt->bind_param("is", $company_id, $deposit_no);
            $deposit_stmt->execute();
            $deposit_result = $deposit_stmt->get_result();
            
            if ($deposit_result->num_rows === 0) {
                $deposit_stmt->close();
                echo json_encode(["success" => false, "message" => "Deposit not found"]);
                exit;
            }
            
            $deposit = $deposit_result->fetch_assoc();
            $deposit_stmt->close();
            
            // Fetch last payment for this deposit
            $last_payment_stmt = $conn->prepare("
                SELECT * FROM payment_entry 
                WHERE com_id=? AND deposit_no=? 
                ORDER BY date DESC, id DESC 
                LIMIT 1
            ");
            $last_payment_stmt->bind_param("is", $company_id, $deposit_no);
            $last_payment_stmt->execute();
            $last_payment_result = $last_payment_stmt->get_result();
            $last_payment = $last_payment_result->fetch_assoc();
            $last_payment_stmt->close();
            
            // Calculate dates
            $current_date = date('Y-m-d');
            $deposit_date = $deposit['deposit_date'];
            $deposit_amount = floatval($deposit['deposit_amt']);
            $interest_percent = floatval($deposit['interest_percent']);
            $interest_type = $deposit['interest_type'] ?? 'Monthly';
            
            // Determine from_date: use last payment's to_date or next_due_date, otherwise use deposit_date
            if ($last_payment) {
                $from_date = !empty($last_payment['to_date']) ? $last_payment['to_date'] : 
                            (!empty($last_payment['next_due_date']) ? $last_payment['next_due_date'] : $last_payment['date']);
            } else {
                $from_date = $deposit_date;
            }
            
            $to_date = $current_date;
            
            // Calculate months and days between from_date and to_date
            $from = new DateTime($from_date);
            $to = new DateTime($to_date);
            
            // Calculate total days difference
            $total_days_diff = $from->diff($to)->days;
            
            // Convert to months and days (using 30 days per month for calculation)
            $total_months = floor($total_days_diff / 30);
            $total_days = $total_days_diff % 30;
            
            // Calculate interest amount
            $int_pay_amount = 0.0;
            if ($deposit_amount > 0 && $interest_percent > 0) {
                $monthly_interest_rate = $interest_percent / 12;
                $monthly_interest_amount = ($deposit_amount * $monthly_interest_rate) / 100;
                $interest_for_months = $total_months * $monthly_interest_amount;
                $interest_for_days = ($total_days / 30) * $monthly_interest_amount;
                $int_pay_amount = $interest_for_months + $interest_for_days;
            }
            
            // Calculate next due date (if monthly, add 1 month to to_date)
            $next_due_date = $to_date;
            if ($interest_type === 'Monthly') {
                $next_due = new DateTime($to_date);
                $next_due->modify('+1 month');
                $next_due_date = $next_due->format('Y-m-d');
            }
            
            echo json_encode([
                "success" => true,
                "deposit" => $deposit,
                "last_payment" => $last_payment,
                "calculated_data" => [
                    "from_date" => $from_date,
                    "to_date" => $to_date,
                    "int_pay_months" => $total_months,
                    "int_pay_days" => $total_days,
                    "int_pay_amount" => round($int_pay_amount, 2),
                    "next_due_date" => $next_due_date,
                    "deposit_amount" => $deposit_amount,
                    "interest_percent" => $interest_percent,
                    "interest_type" => $interest_type
                ]
            ]);
            exit;
        }
        
        // 1. Fetch payments
        if (isset($_GET['payment_no'])) {
            $payment_no = $_GET['payment_no'];
            $stmt = $conn->prepare("SELECT * FROM payment_entry WHERE com_id=? AND payment_no=?");
            $stmt->bind_param("is", $company_id, $payment_no);
        } elseif (isset($_GET['id'])) {
            $payment_id = intval($_GET['id']);
            $stmt = $conn->prepare("SELECT * FROM payment_entry WHERE com_id=? AND id=?");
            $stmt->bind_param("ii", $company_id, $payment_id);
        } else {
            $stmt = $conn->prepare("SELECT * FROM payment_entry WHERE com_id=? ORDER BY id DESC");
            $stmt->bind_param("i", $company_id);
        }

        $stmt->execute();
        $result = $stmt->get_result();

        $payments = [];
        while ($row = $result->fetch_assoc()) {
            $payments[] = $row;
        }
        $stmt->close();

        // 2. Fetch last payment number
        $lastStmt = $conn->prepare("
            SELECT payment_no 
            FROM payment_entry 
            WHERE com_id=? AND payment_no != '' AND payment_no IS NOT NULL
            ORDER BY payment_no DESC 
            LIMIT 1
        ");

        $lastStmt->bind_param("i", $company_id);
        $lastStmt->execute();
        $lastResult = $lastStmt->get_result();
        $lastRow = $lastResult->fetch_assoc();
        $lastStmt->close();

        // 3. Generate next payment number
        if ($lastRow && !empty($lastRow['payment_no'])) {
            $last_payment_no = $lastRow['payment_no'];

            $prefix = substr($last_payment_no, 0, 2);
            $year = substr($last_payment_no, 2, 4);
            $number = intval(substr($last_payment_no, 6));
            $next_number = $number + 1;

            $next_payment_no = $prefix . $year . str_pad($next_number, 3, "0", STR_PAD_LEFT);

        } else {
            $prefix = "PN";
            $year = date("Y");
            $next_payment_no = $prefix . $year . "001";
            $last_payment_no = null;
        }

        echo json_encode([
            "success" => true,
            "last_payment_no" => $last_payment_no,
            "next_payment_no" => $next_payment_no,
            "data" => $payments
        ]);
        exit;
    }

    /* =======================  INSERT  ======================= */

    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $raw_input = file_get_contents("php://input");
        $data = json_decode($raw_input, true);
        
        // Debug: Log JSON decode result
        if (json_last_error() !== JSON_ERROR_NONE) {
            error_log("JSON decode error: " . json_last_error_msg());
            error_log("Raw input: " . substr($raw_input, 0, 500));
        }

        $payment_no = $data['payment_no'] ?? '';
        $deposit_no = $data['deposit_no'] ?? '';
        $customer_name = $data['customer_name'] ?? '';
        $mobile = $data['mobile'] ?? '';
        $deposit_amount = $data['deposit_amount'] ?? '';
        $deposit_type = $data['deposit_type'] ?? 'Capital';
        $interest_type = $data['interest_type'] ?? '';
        $interest_percent = !empty($data['interest_percent']) ? floatval($data['interest_percent']) : 0.0;
        $interest_deposit_amt = $data['interest_deposit_amt'] ?? '';
        $deposit_date = $data['deposit_date'] ?? '';
        $date = $data['date'] ?? '';
        $add_less = $data['add_less'] ?? '';
        $principal_amt_raw = $data['principal_amt'] ?? '';
        $principal_amt = (empty($principal_amt_raw) || trim($principal_amt_raw) === '') ? '' : $principal_amt_raw;
        $int_pay_months = $data['int_pay_months'] ?? '';
        $int_pay_days = $data['int_pay_days'] ?? '';
        $int_pay_amount = !empty($data['int_pay_amount']) ? floatval($data['int_pay_amount']) : 0.0;
        $pay_amt = !empty($data['pay_amt']) ? floatval($data['pay_amt']) : 0.0;
        $total_amount = !empty($data['total_amount']) ? floatval($data['total_amount']) : 0.0;
        $from_date = $data['from_date'] ?? '';
        $to_date = $data['to_date'] ?? '';
        $next_due_date = $data['next_due_date'] ?? '';
        $remarks = $data['remarks'] ?? '';
        $ledger_ac = $data['ledger_ac'] ?? '';
        $is_close = intval($data['is_close'] ?? 0);

        $stmt = $conn->prepare("
            INSERT INTO payment_entry
            (
                com_id, payment_no, deposit_no, customer_name, mobile,
                deposit_amount, deposit_type, interest_type, interest_percent, interest_deposit_amt, deposit_date,
                date, add_less, principal_amt, int_pay_months, int_pay_days, int_pay_amount,
                pay_amt, total_amount, from_date, to_date, next_due_date,
                remarks, ledger_ac, is_close
            )
            VALUES 
            (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");

        $deposit_amount_num = !empty($deposit_amount) ? floatval($deposit_amount) : 0.0;
        $interest_deposit_amt_num = !empty($interest_deposit_amt) ? floatval($interest_deposit_amt) : 0.0;
        $principal_amt_num = !empty($principal_amt) ? floatval($principal_amt) : 0.0;
        $int_pay_months_num = !empty($int_pay_months) ? intval($int_pay_months) : 0;
        $int_pay_days_num = !empty($int_pay_days) ? intval($int_pay_days) : 0;

        $stmt->bind_param(
            "issssdssddsssdiiddddssssi",
            $company_id,
            $payment_no,
            $deposit_no,
            $customer_name,
            $mobile,
            $deposit_amount_num,
            $deposit_type,
            $interest_type,
            $interest_percent,
            $interest_deposit_amt_num,
            $deposit_date,
            $date,
            $add_less,
            $principal_amt_num,
            $int_pay_months_num,
            $int_pay_days_num,
            $int_pay_amount,
            $pay_amt,
            $total_amount,
            $from_date,
            $to_date,
            $next_due_date,
            $remarks,
            $ledger_ac,
            $is_close
        );

        if ($stmt->execute()) {
            $payment_id = $stmt->insert_id;
            $stmt->close();

            $principal_amt_calc = (empty($principal_amt_raw) || trim($principal_amt_raw) === '') ? 0 : floatval($principal_amt_raw);
            $int_pay_amount_calc = floatval($int_pay_amount);
            $deposit_amount_calc = floatval($deposit_amount);
            $uid = isset($_SESSION['uid']) ? intval($_SESSION['uid']) : 1;

            $com_id_str = (string)$company_id;
            $uid_str = (string)$uid;

            $particulars = $payment_no . '-' . $customer_name;
            $voucher_type_deposit = 'Deposit';
            // Use a human‑readable voucher type for interest, e.g. "Deposit interest"
            $voucher_type_interest_base = $deposit_type . ' interest';

            // Insert into deposit_entry table when principal_amt is not empty
            if (!empty($principal_amt_raw) && trim($principal_amt_raw) !== '') {
                // Validate required fields before inserting
                if (empty($deposit_no) || empty($customer_name)) {
                    error_log("Skipping deposit_entry insert: deposit_no or customer_name is empty. deposit_no='$deposit_no', customer_name='$customer_name'");
                } else {
                    $payment_type = strtolower($add_less) === 'add' ? 'payment_add' : 'payment_less';
                    $deposit_amt_value = floatval($principal_amt_raw);
                    $interest_percent_value = !empty($interest_percent) ? floatval($interest_percent) : 0.0;
                    $int_amt_value = !empty($int_pay_amount) ? floatval($int_pay_amount) : 0.0;

                    // Set default values for fields not available in payment context
                    // Use empty strings instead of null for string fields to avoid binding issues
                    $pan_no = '';
                    $exist_flag = 0;
                    $address = '';
                    $cheque_no = '';
                    $bank_name = '';
                    $cheque_date = '';
                    $profile_image = '';
                    
                    // Use payment date as deposit_date for payment_add/payment_less entries
                    // This represents when the adjustment occurred
                    if (empty($deposit_date)) {
                        // If deposit_date is empty, use payment date
                        $deposit_date = !empty($date) ? $date : date('Y-m-d');
                    }

                    // Debug: Log all values before inserting
                    error_log("=== DEPOSIT ENTRY INSERT DEBUG ===");
                    error_log("deposit_no: '$deposit_no'");
                    error_log("company_id: '$company_id'");
                    error_log("customer_name: '$customer_name'");
                    error_log("mobile: '$mobile'");
                    error_log("pan_no: '$pan_no'");
                    error_log("deposit_date: '$deposit_date'");
                    error_log("exist_flag: '$exist_flag'");
                    error_log("address: '$address'");
                    error_log("deposit_amt_value: '$deposit_amt_value'");
                    error_log("interest_percent_value: '$interest_percent_value'");
                    error_log("deposit_type: '$deposit_type'");
                    error_log("ledger_ac: '$ledger_ac'");
                    error_log("cheque_no: '$cheque_no'");
                    error_log("bank_name: '$bank_name'");
                    error_log("interest_type: '$interest_type'");
                    error_log("cheque_date: '$cheque_date'");
                    error_log("int_amt_value: '$int_amt_value'");
                    error_log("payment_type: '$payment_type'");
                    error_log("remarks: '$remarks'");
                    error_log("profile_image: '$profile_image'");
                    error_log("===================================");

                    $deposit_stmt = $conn->prepare("
                        INSERT INTO deposit_entry
                        (
                            deposit_no, com_id, name, mobile_no, pan_no, deposit_date, exist_flag, address,
                            deposit_amt, interest_percent, deposit_type, ledger_name, cheque_no, 
                            bank_name, interest_type, cheque_date, int_amt, type, remarks, profile_image
                        )
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                    ");

                    if (!$deposit_stmt) {
                        error_log("Prepare failed: " . $conn->error);
                    }

                    // Bind types must match 20 values:
                    // deposit_no(s), com_id(i), name(s), mobile_no(s), pan_no(s), deposit_date(s), 
                    // exist_flag(i), address(s), deposit_amt(d), interest_percent(d), deposit_type(s), 
                    // ledger_name(s), cheque_no(s), bank_name(s), interest_type(s), cheque_date(s), 
                    // int_amt(d), type(s), remarks(s), profile_image(s)
                    $bind_result = $deposit_stmt->bind_param(
                        "sissssisdsssssssisss",
                        $deposit_no,
                        $company_id,
                        $customer_name,
                        $mobile,
                        $pan_no,
                        $deposit_date,
                        $exist_flag,
                        $address,
                        $deposit_amt_value,
                        $interest_percent_value,
                        $deposit_type,
                        $ledger_ac,
                        $cheque_no,
                        $bank_name,
                        $interest_type,
                        $cheque_date,
                        $int_amt_value,
                        $payment_type,
                        $remarks,
                        $profile_image
                    );

                    if (!$bind_result) {
                        error_log("Bind param failed: " . $deposit_stmt->error);
                    }

                    if (!$deposit_stmt->execute()) {
                        // Log error but don't fail the entire operation
                        error_log("Deposit entry insert failed: " . $deposit_stmt->error);
                        error_log("Values: deposit_no=$deposit_no, name=$customer_name, mobile=$mobile, deposit_date=$deposit_date, deposit_amt=$deposit_amt_value");
                    } else {
                        error_log("Deposit entry inserted successfully: deposit_no=$deposit_no, name=$customer_name, deposit_amt=$deposit_amt_value");
                    }
                    $deposit_stmt->close();
                }
            }

            // Update deposit_entry status to closed when is_close == 1
            if ($is_close == 1 && !empty($deposit_no)) {
                $update_deposit_stmt = $conn->prepare("
                    UPDATE deposit_entry 
                    SET type = 'closed' 
                    WHERE deposit_no = ? AND com_id = ?
                ");
                $update_deposit_stmt->bind_param("si", $deposit_no, $company_id);
                if (!$update_deposit_stmt->execute()) {
                    // Log error but don't fail the entire operation
                    error_log("Deposit status update failed: " . $update_deposit_stmt->error);
                }
                $update_deposit_stmt->close();
            }

            $ledger_stmt = $conn->prepare("
                INSERT INTO ledger_day_wise 
                (com_id, uid, date, ledger, particulars, voucher_type, voucher_number, credit, debit, createdOn)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
            ");

            if ($is_close == 1) {
                if ($deposit_amount_calc > 0) {
                    $credit1 = $deposit_amount_calc;
                    $debit1 = 0.0;
                    $voucher_type1 = $voucher_type_deposit;
                    $ledger_stmt->bind_param(
                        "sssssssdd",
                        $com_id_str,
                        $uid_str,
                        $date,
                        $ledger_ac,
                        $particulars,
                        $voucher_type1,
                        $payment_no,
                        $credit1,
                        $debit1
                    );
                    $ledger_stmt->execute();
                }

                if ($int_pay_amount_calc > 0) {
                    $credit2 = $int_pay_amount_calc;
                    $debit2 = 0.0;
                    $voucher_type2 = $voucher_type_interest_base;
                    $ledger_stmt->bind_param(
                        "sssssssdd",
                        $com_id_str,
                        $uid_str,
                        $date,
                        $ledger_ac,
                        $particulars,
                        $voucher_type2,
                        $payment_no,
                        $credit2,
                        $debit2
                    );
                    $ledger_stmt->execute();
                }
            } else {
                // When principal_amt is not empty
                if ($principal_amt_calc > 0) {
                    if (strtolower($add_less) === 'add') {
                        // Add: Interest in CREDIT, Principal in DEBIT (separate entries)
                        // Entry 1: Interest amount in CREDIT side
                        if ($int_pay_amount_calc > 0) {
                            $credit = $int_pay_amount_calc;
                            $debit = 0.0;
                            $ledger_stmt->bind_param(
                                "sssssssdd",
                                $com_id_str,
                                $uid_str,
                                $date,
                                $ledger_ac,
                                $particulars,
                                $deposit_type,
                                $payment_no,
                                $credit,
                                $debit
                            );
                            $ledger_stmt->execute();
                        }
                        
                        // Entry 2: Principal amount in DEBIT side
                        $credit = 0.0;
                        $debit = $principal_amt_calc;
                        $ledger_stmt->bind_param(
                            "sssssssdd",
                            $com_id_str,
                            $uid_str,
                            $date,
                            $ledger_ac,
                            $particulars,
                            $deposit_type,
                            $payment_no,
                            $credit,
                            $debit
                        );
                        $ledger_stmt->execute();
                    } elseif (strtolower($add_less) === 'less') {
                        // Less: Principal in CREDIT, Interest in CREDIT (separate entries)
                        // Entry 1: Principal amount in CREDIT side
                        $credit = $principal_amt_calc;
                        $debit = 0.0;
                        $ledger_stmt->bind_param(
                            "sssssssdd",
                            $com_id_str,
                            $uid_str,
                            $date,
                            $ledger_ac,
                            $particulars,
                            $deposit_type,
                            $payment_no,
                            $credit,
                            $debit
                        );
                        $ledger_stmt->execute();
                        
                        // Entry 2: Interest amount in CREDIT side
                        if ($int_pay_amount_calc > 0) {
                            $credit = $int_pay_amount_calc;
                            $debit = 0.0;
                            $ledger_stmt->bind_param(
                                "sssssssdd",
                                $com_id_str,
                                $uid_str,
                                $date,
                                $ledger_ac,
                                $particulars,
                                $deposit_type,
                                $payment_no,
                                $credit,
                                $debit
                            );
                            $ledger_stmt->execute();
                        }
                    }
                } elseif ($principal_amt_calc == 0 && $int_pay_amount_calc > 0) {
                    // When principal_amt is empty, only interest payment
                    $credit = $int_pay_amount_calc;
                    $debit = 0.0;
                    $ledger_stmt->bind_param(
                        "sssssssdd",
                        $com_id_str,
                        $uid_str,
                        $date,
                        $ledger_ac,
                        $particulars,
                        $voucher_type_interest_base,
                        $payment_no,
                        $credit,
                        $debit
                    );
                    $ledger_stmt->execute();
                }
            }

            $ledger_stmt->close();
            echo json_encode(["success" => true, "message" => "Payment inserted successfully"]);
        } else {
            echo json_encode(["success" => false, "message" => "Insert failed: " . $stmt->error]);
            $stmt->close();
        }
    }

    /* =======================  UPDATE  ======================= */

    if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
        $payment_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
        
        if ($payment_id <= 0) {
            echo json_encode(["success" => false, "message" => "Payment ID is required"]);
            exit;
        }

        // Fetch existing payment entry to get old values
        $fetch_stmt = $conn->prepare("SELECT payment_no, deposit_no, is_close FROM payment_entry WHERE id = ? AND com_id = ?");
        $fetch_stmt->bind_param("ii", $payment_id, $company_id);
        $fetch_stmt->execute();
        $result = $fetch_stmt->get_result();
        
        if ($result->num_rows === 0) {
            $fetch_stmt->close();
            echo json_encode(["success" => false, "message" => "Payment entry not found"]);
            exit;
        }
        
        $old_payment = $result->fetch_assoc();
        $old_payment_no = $old_payment['payment_no'];
        $old_deposit_no = $old_payment['deposit_no'];
        $old_is_close = intval($old_payment['is_close']);
        $fetch_stmt->close();

        // Delete old ledger entries
        $delete_ledger_stmt = $conn->prepare("DELETE FROM ledger_day_wise WHERE voucher_number = ? AND com_id = ?");
        $delete_ledger_stmt->bind_param("si", $old_payment_no, $company_id);
        $delete_ledger_stmt->execute();
        $delete_ledger_stmt->close();

        // Delete old deposit_entry records created by this payment
        $delete_deposit_stmt = $conn->prepare("DELETE FROM deposit_entry WHERE deposit_no = ? AND com_id = ? AND type IN ('payment_add', 'payment_less')");
        $delete_deposit_stmt->bind_param("si", $old_deposit_no, $company_id);
        $delete_deposit_stmt->execute();
        $delete_deposit_stmt->close();

        // If deposit was closed, revert its status (set type back to original or NULL)
        // Only revert the main deposit entry, not payment entries (payment_add/payment_less)
        if ($old_is_close == 1 && !empty($old_deposit_no)) {
            $revert_deposit_stmt = $conn->prepare("
                UPDATE deposit_entry 
                SET type = NULL 
                WHERE deposit_no = ? AND com_id = ? AND type = 'closed' 
                AND type NOT IN ('payment_add', 'payment_less')
            ");
            $revert_deposit_stmt->bind_param("si", $old_deposit_no, $company_id);
            if (!$revert_deposit_stmt->execute()) {
                error_log("Deposit revert failed: " . $revert_deposit_stmt->error);
            }
            $revert_deposit_stmt->close();
        }

        // Get new data from request
        $data = json_decode(file_get_contents("php://input"), true);

        $payment_no = $data['payment_no'] ?? $old_payment_no;
        $deposit_no = $data['deposit_no'] ?? $old_deposit_no;
        $customer_name = $data['customer_name'] ?? '';
        $mobile = $data['mobile'] ?? '';
        $deposit_amount = $data['deposit_amount'] ?? '';
        $deposit_type = $data['deposit_type'] ?? 'Capital';
        $interest_type = $data['interest_type'] ?? '';
        $interest_percent = !empty($data['interest_percent']) ? floatval($data['interest_percent']) : 0.0;
        $interest_deposit_amt = $data['interest_deposit_amt'] ?? '';
        $deposit_date = $data['deposit_date'] ?? '';
        $date = $data['date'] ?? '';
        $add_less = $data['add_less'] ?? '';
        $principal_amt_raw = $data['principal_amt'] ?? '';
        $principal_amt = (empty($principal_amt_raw) || trim($principal_amt_raw) === '') ? '' : $principal_amt_raw;
        $int_pay_months = $data['int_pay_months'] ?? '';
        $int_pay_days = $data['int_pay_days'] ?? '';
        $int_pay_amount = !empty($data['int_pay_amount']) ? floatval($data['int_pay_amount']) : 0.0;
        $pay_amt = !empty($data['pay_amt']) ? floatval($data['pay_amt']) : 0.0;
        $total_amount = !empty($data['total_amount']) ? floatval($data['total_amount']) : 0.0;
        $from_date = $data['from_date'] ?? '';
        $to_date = $data['to_date'] ?? '';
        $next_due_date = $data['next_due_date'] ?? '';
        $remarks = $data['remarks'] ?? '';
        $ledger_ac = $data['ledger_ac'] ?? '';
        $is_close = intval($data['is_close'] ?? 0);

        $deposit_amount_num = !empty($deposit_amount) ? floatval($deposit_amount) : 0.0;
        $interest_deposit_amt_num = !empty($interest_deposit_amt) ? floatval($interest_deposit_amt) : 0.0;
        $principal_amt_num = !empty($principal_amt) ? floatval($principal_amt) : 0.0;
        $int_pay_months_num = !empty($int_pay_months) ? intval($int_pay_months) : 0;
        $int_pay_days_num = !empty($int_pay_days) ? intval($int_pay_days) : 0;

        // Update payment_entry
        $update_stmt = $conn->prepare("
            UPDATE payment_entry SET
                payment_no = ?, deposit_no = ?, customer_name = ?, mobile = ?,
                deposit_amount = ?, deposit_type = ?, interest_type = ?, interest_percent = ?, interest_deposit_amt = ?, deposit_date = ?,
                date = ?, add_less = ?, principal_amt = ?, int_pay_months = ?, int_pay_days = ?, int_pay_amount = ?,
                pay_amt = ?, total_amount = ?, from_date = ?, to_date = ?, next_due_date = ?,
                remarks = ?, ledger_ac = ?, is_close = ?
            WHERE id = ? AND com_id = ?
        ");

        $update_stmt->bind_param(
            "ssssdssddsssdiiddddssssiii",
            $payment_no,
            $deposit_no,
            $customer_name,
            $mobile,
            $deposit_amount_num,
            $deposit_type,
            $interest_type,
            $interest_percent,
            $interest_deposit_amt_num,
            $deposit_date,
            $date,
            $add_less,
            $principal_amt_num,
            $int_pay_months_num,
            $int_pay_days_num,
            $int_pay_amount,
            $pay_amt,
            $total_amount,
            $from_date,
            $to_date,
            $next_due_date,
            $remarks,
            $ledger_ac,
            $is_close,
            $payment_id,
            $company_id
        );

        if ($update_stmt->execute()) {
            $update_stmt->close();

            $principal_amt_calc = (empty($principal_amt_raw) || trim($principal_amt_raw) === '') ? 0 : floatval($principal_amt_raw);
            $int_pay_amount_calc = floatval($int_pay_amount);
            $deposit_amount_calc = floatval($deposit_amount);
            $uid = isset($_SESSION['uid']) ? intval($_SESSION['uid']) : 1;

            $com_id_str = (string)$company_id;
            $uid_str = (string)$uid;

            $particulars = $payment_no . '-' . $customer_name;
            $voucher_type_deposit = 'Deposit';
            // Use a human‑readable voucher type for interest, e.g. "Deposit interest"
            $voucher_type_interest_base = $deposit_type . ' interest';

            // Insert into deposit_entry table when principal_amt is not empty
            if (!empty($principal_amt_raw) && trim($principal_amt_raw) !== '') {
                // Validate required fields before inserting
                if (empty($deposit_no) || empty($customer_name)) {
                    error_log("Skipping deposit_entry insert (UPDATE): deposit_no or customer_name is empty. deposit_no='$deposit_no', customer_name='$customer_name'");
                } else {
                    $payment_type = strtolower($add_less) === 'add' ? 'payment_add' : 'payment_less';
                    $deposit_amt_value = floatval($principal_amt_raw);
                    $interest_percent_value = !empty($interest_percent) ? floatval($interest_percent) : 0.0;
                    $int_amt_value = !empty($int_pay_amount) ? floatval($int_pay_amount) : 0.0;

                    // Set default values for fields not available in payment context
                    // Use empty strings instead of null for string fields to avoid binding issues
                    $pan_no = '';
                    $exist_flag = 0;
                    $address = '';
                    $cheque_no = '';
                    $bank_name = '';
                    $cheque_date = '';
                    $profile_image = '';
                    
                    // Use payment date as deposit_date for payment_add/payment_less entries
                    // This represents when the adjustment occurred
                    if (empty($deposit_date)) {
                        // If deposit_date is empty, use payment date
                        $deposit_date = !empty($date) ? $date : date('Y-m-d');
                    }

                    $deposit_stmt = $conn->prepare("
                        INSERT INTO deposit_entry
                        (
                            deposit_no, com_id, name, mobile_no, pan_no, deposit_date, exist_flag, address,
                            deposit_amt, interest_percent, deposit_type, ledger_name, cheque_no, 
                            bank_name, interest_type, cheque_date, int_amt, type, remarks, profile_image
                        )
                        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
                    ");

                    // Bind types must match 20 values (same as insert):
                    // deposit_no(s), com_id(i), name(s), mobile_no(s), pan_no(s), deposit_date(s), 
                    // exist_flag(i), address(s), deposit_amt(d), interest_percent(d), deposit_type(s), 
                    // ledger_name(s), cheque_no(s), bank_name(s), interest_type(s), cheque_date(s), 
                    // int_amt(d), type(s), remarks(s), profile_image(s)
                    $deposit_stmt->bind_param(
                        "sissssisdsssssssisss",
                        $deposit_no,
                        $company_id,
                        $customer_name,
                        $mobile,
                        $pan_no,
                        $deposit_date,
                        $exist_flag,
                        $address,
                        $deposit_amt_value,
                        $interest_percent_value,
                        $deposit_type,
                        $ledger_ac,
                        $cheque_no,
                        $bank_name,
                        $interest_type,
                        $cheque_date,
                        $int_amt_value,
                        $payment_type,
                        $remarks,
                        $profile_image
                    );

                    if (!$deposit_stmt->execute()) {
                        error_log("Deposit entry insert failed (UPDATE): " . $deposit_stmt->error);
                        error_log("Values: deposit_no=$deposit_no, name=$customer_name, mobile=$mobile, deposit_date=$deposit_date, deposit_amt=$deposit_amt_value");
                    } else {
                        error_log("Deposit entry inserted successfully (UPDATE): deposit_no=$deposit_no, name=$customer_name, deposit_amt=$deposit_amt_value");
                    }
                    $deposit_stmt->close();
                }
            }

            // Update deposit_entry status to closed when is_close == 1
            // Only update the main deposit entry (where type is NULL or empty), not payment entries
            if ($is_close == 1 && !empty($deposit_no)) {
                $update_deposit_stmt = $conn->prepare("
                    UPDATE deposit_entry 
                    SET type = 'closed' 
                    WHERE deposit_no = ? AND com_id = ? 
                    AND (type IS NULL OR type = '' OR type NOT IN ('payment_add', 'payment_less'))
                ");
                $update_deposit_stmt->bind_param("si", $deposit_no, $company_id);
                if (!$update_deposit_stmt->execute()) {
                    error_log("Deposit status update failed: " . $update_deposit_stmt->error);
                }
                $update_deposit_stmt->close();
            } elseif ($old_is_close == 1 && $is_close == 0 && !empty($deposit_no)) {
                // If changing from closed to not closed, ensure deposit is not marked as closed
                // (This is a safety check, the revert above should have already handled it)
                $ensure_not_closed_stmt = $conn->prepare("
                    UPDATE deposit_entry 
                    SET type = NULL 
                    WHERE deposit_no = ? AND com_id = ? AND type = 'closed'
                    AND type NOT IN ('payment_add', 'payment_less')
                ");
                $ensure_not_closed_stmt->bind_param("si", $deposit_no, $company_id);
                if (!$ensure_not_closed_stmt->execute()) {
                    error_log("Deposit un-close failed: " . $ensure_not_closed_stmt->error);
                }
                $ensure_not_closed_stmt->close();
            }

            // Re-create ledger entries
            $ledger_stmt = $conn->prepare("
                INSERT INTO ledger_day_wise 
                (com_id, uid, date, ledger, particulars, voucher_type, voucher_number, credit, debit, createdOn)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
            ");

            if ($is_close == 1) {
                if ($deposit_amount_calc > 0) {
                    $credit1 = $deposit_amount_calc;
                    $debit1 = 0.0;
                    $voucher_type1 = $voucher_type_deposit;
                    $ledger_stmt->bind_param(
                        "sssssssdd",
                        $com_id_str,
                        $uid_str,
                        $date,
                        $ledger_ac,
                        $particulars,
                        $voucher_type1,
                        $payment_no,
                        $credit1,
                        $debit1
                    );
                    $ledger_stmt->execute();
                }

                if ($int_pay_amount_calc > 0) {
                    $credit2 = $int_pay_amount_calc;
                    $debit2 = 0.0;
                    $voucher_type2 = $voucher_type_interest_base;
                    $ledger_stmt->bind_param(
                        "sssssssdd",
                        $com_id_str,
                        $uid_str,
                        $date,
                        $ledger_ac,
                        $particulars,
                        $voucher_type2,
                        $payment_no,
                        $credit2,
                        $debit2
                    );
                    $ledger_stmt->execute();
                }
            } else {
                // When principal_amt is not empty
                if ($principal_amt_calc > 0) {
                    if (strtolower($add_less) === 'add') {
                        // Add: Interest in CREDIT, Principal in DEBIT (separate entries)
                        // Entry 1: Interest amount in CREDIT side
                        if ($int_pay_amount_calc > 0) {
                            $credit = $int_pay_amount_calc;
                            $debit = 0.0;
                            $ledger_stmt->bind_param(
                                "sssssssdd",
                                $com_id_str,
                                $uid_str,
                                $date,
                                $ledger_ac,
                                $particulars,
                                $deposit_type,
                                $payment_no,
                                $credit,
                                $debit
                            );
                            $ledger_stmt->execute();
                        }
                        
                        // Entry 2: Principal amount in DEBIT side
                        $credit = 0.0;
                        $debit = $principal_amt_calc;
                        $ledger_stmt->bind_param(
                            "sssssssdd",
                            $com_id_str,
                            $uid_str,
                            $date,
                            $ledger_ac,
                            $particulars,
                            $deposit_type,
                            $payment_no,
                            $credit,
                            $debit
                        );
                        $ledger_stmt->execute();
                    } elseif (strtolower($add_less) === 'less') {
                        // Less: Principal in CREDIT, Interest in CREDIT (separate entries)
                        // Entry 1: Principal amount in CREDIT side
                        $credit = $principal_amt_calc;
                        $debit = 0.0;
                        $ledger_stmt->bind_param(
                            "sssssssdd",
                            $com_id_str,
                            $uid_str,
                            $date,
                            $ledger_ac,
                            $particulars,
                            $deposit_type,
                            $payment_no,
                            $credit,
                            $debit
                        );
                        $ledger_stmt->execute();
                        
                        // Entry 2: Interest amount in CREDIT side
                        if ($int_pay_amount_calc > 0) {
                            $credit = $int_pay_amount_calc;
                            $debit = 0.0;
                            $ledger_stmt->bind_param(
                                "sssssssdd",
                                $com_id_str,
                                $uid_str,
                                $date,
                                $ledger_ac,
                                $particulars,
                                $deposit_type,
                                $payment_no,
                                $credit,
                                $debit
                            );
                            $ledger_stmt->execute();
                        }
                    }
                } elseif ($principal_amt_calc == 0 && $int_pay_amount_calc > 0) {
                    // When principal_amt is empty, only interest payment
                    $credit = $int_pay_amount_calc;
                    $debit = 0.0;
                    $ledger_stmt->bind_param(
                        "sssssssdd",
                        $com_id_str,
                        $uid_str,
                        $date,
                        $ledger_ac,
                        $particulars,
                        $voucher_type_interest_base,
                        $payment_no,
                        $credit,
                        $debit
                    );
                    $ledger_stmt->execute();
                }
            }

            $ledger_stmt->close();
            echo json_encode(["success" => true, "message" => "Payment updated successfully"]);
        } else {
            echo json_encode(["success" => false, "message" => "Update failed: " . $update_stmt->error]);
            $update_stmt->close();
        }
    }

    /* =======================  DELETE  ======================= */

    if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
        $payment_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
        
        if ($payment_id <= 0) {
            echo json_encode(["success" => false, "message" => "Payment ID is required"]);
            exit;
        }

        // Fetch payment entry to get payment_no and deposit_no
        $fetch_stmt = $conn->prepare("SELECT payment_no, deposit_no, is_close FROM payment_entry WHERE id = ? AND com_id = ?");
        $fetch_stmt->bind_param("ii", $payment_id, $company_id);
        $fetch_stmt->execute();
        $result = $fetch_stmt->get_result();
        
        if ($result->num_rows === 0) {
            $fetch_stmt->close();
            echo json_encode(["success" => false, "message" => "Payment entry not found"]);
            exit;
        }
        
        $payment_data = $result->fetch_assoc();
        $payment_no = $payment_data['payment_no'];
        $deposit_no = $payment_data['deposit_no'];
        $is_close = intval($payment_data['is_close']);
        $fetch_stmt->close();

        // Delete ledger entries
        $delete_ledger_stmt = $conn->prepare("DELETE FROM ledger_day_wise WHERE voucher_number = ? AND com_id = ?");
        $delete_ledger_stmt->bind_param("si", $payment_no, $company_id);
        $delete_ledger_stmt->execute();
        $delete_ledger_stmt->close();

        // Delete deposit_entry records created by this payment
        if (!empty($deposit_no)) {
            $delete_deposit_stmt = $conn->prepare("DELETE FROM deposit_entry WHERE deposit_no = ? AND com_id = ? AND type IN ('payment_add', 'payment_less')");
            $delete_deposit_stmt->bind_param("si", $deposit_no, $company_id);
            $delete_deposit_stmt->execute();
            $delete_deposit_stmt->close();

            // If deposit was closed, revert its status
            if ($is_close == 1) {
                $revert_deposit_stmt = $conn->prepare("UPDATE deposit_entry SET type = NULL WHERE deposit_no = ? AND com_id = ? AND type = 'closed'");
                $revert_deposit_stmt->bind_param("si", $deposit_no, $company_id);
                $revert_deposit_stmt->execute();
                $revert_deposit_stmt->close();
            }
        }

        // Delete payment_entry
        $delete_stmt = $conn->prepare("DELETE FROM payment_entry WHERE id = ? AND com_id = ?");
        $delete_stmt->bind_param("ii", $payment_id, $company_id);
        
        if ($delete_stmt->execute()) {
            $delete_stmt->close();
            echo json_encode(["success" => true, "message" => "Payment deleted successfully"]);
        } else {
            echo json_encode(["success" => false, "message" => "Delete failed: " . $delete_stmt->error]);
            $delete_stmt->close();
        }
    }

} catch (Exception $e) {
    echo json_encode(["success" => false, "message" => "Token invalid", "error" => $e->getMessage()]);
}
?>
