<?php
session_start();
include 'layouts/dbconn.php';

header('Content-Type: application/json');

try {
    // Check if user is logged in and has appropriate permissions
    if (!isset($_SESSION['user_id'])) {
        throw new Exception('User not authenticated');
    }

    // Get POST data
    $data = json_decode(file_get_contents('php://input'), true);
    if (!$data) {
        throw new Exception('Invalid input data');
    }

    // Validate required fields
    $requiredFields = [
        'payment_mode' => 'Payment mode',
        'cheque_no' => 'Cheque/Reference number',
        'cheque_date' => 'Payment date',
        'claims' => 'Claims',
        'payment_to' => 'Payment recipient',
        'total_amount' => 'Total amount'
    ];

    foreach ($requiredFields as $field => $label) {
        if (empty($data[$field])) {
            throw new Exception("$label is required");
        }
    }

    if (empty($data['claims'])) {
        throw new Exception('No claims selected for payment');
    }

    // Validate total amount matches sum of claims
    $claimsTotal = array_sum(array_column($data['claims'], 'amount'));
    if (abs($claimsTotal - $data['total_amount']) > 0.01) { // Allow for small floating point differences
        throw new Exception('Total amount mismatch with claims');
    }

    // Start transaction
    $conn->begin_transaction();

    try {
        // Generate payment and voucher numbers
        $payment_no = generatePaymentNumber($conn);
        $voucher_no = generateVoucherNumber($conn);

        // Set recipient details based on payment_to
        $provider = null;
        $member_no = null;
        $corp_id = null;
        $recipient_type = strtoupper($data['payment_to']);

        switch($data['payment_to']) {
            case 'provider':
                $provider = $data['recipient']['id'];
                break;
            case 'member':
                $member_no = $data['recipient']['id'];
                break;
            case 'corporate':
                $corp_id = $data['recipient']['id'];
                break;
            default:
                throw new Exception('Invalid payment recipient type');
        }

        // Assign corp_paid_for to a variable
        $corp_paid_for = $data['corp_paid_for'] ?? null;

        // Insert payment record
        $sql = "INSERT INTO bills_payment (
            payment_no,
            cheque_no,
            cheque_date,
            cheque_amount,
            provider,
            member_no,
            corp_id,
            admin_fee,
            corp_paid_for,
            payment_mode,
            voucher_no,
            dispatched,
            date_entered,
            user_id
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, CURDATE(), ?)";

        $stmt = $conn->prepare($sql);
        if (!$stmt) {
            throw new Exception("Error preparing payment statement: " . $conn->error);
        }

        $stmt->bind_param('sssdsssdisss',
            $payment_no,
            $data['cheque_no'],
            $data['cheque_date'],
            $data['total_amount'],
            $provider,
            $member_no,
            $corp_id,
            $data['admin_fee'],
            $corp_paid_for,
            $data['payment_mode'],
            $voucher_no,
            $_SESSION['user_id']
        );

        if (!$stmt->execute()) {
            throw new Exception("Error saving payment: " . $stmt->error);
        }

        // Create payment voucher
        $sql = "INSERT INTO payment_vouchers (
            voucher_no,
            payment_no,
            voucher_date,
            recipient_type,
            recipient_id,
            recipient_name,
            total_amount,
            status,
            created_by,
            created_at
        ) VALUES (?, ?, ?, ?, ?, ?, ?, 'POSTED', ?, NOW())";

        $stmt = $conn->prepare($sql);
        if (!$stmt) {
            throw new Exception("Error preparing voucher statement: " . $conn->error);
        }

        $stmt->bind_param('ssssssdi',
            $voucher_no,
            $payment_no,
            $data['cheque_date'],
            $recipient_type,
            $data['recipient']['id'],
            $data['recipient']['name'],
            $data['total_amount'],
            $_SESSION['user_id']
        );

        if (!$stmt->execute()) {
            throw new Exception("Error creating voucher: " . $stmt->error);
        }

        $voucher_id = $conn->insert_id;

        // Insert voucher items
        $sql = "INSERT INTO payment_voucher_items (
            voucher_id,
            claim_no,
            invoice_no,
            description,
            amount
        ) VALUES (?, ?, ?, ?, ?)";

        $stmt = $conn->prepare($sql);
        if (!$stmt) {
            throw new Exception("Error preparing voucher items statement: " . $conn->error);
        }

        foreach ($data['claims'] as $claim) {
            $description = sprintf(
                "Payment for claim %s / Invoice %s",
                $claim['claim_no'],
                $claim['invoice_no']
            );

            $stmt->bind_param('isssd',
                $voucher_id,
                $claim['claim_no'],
                $claim['invoice_no'],
                $description,
                $claim['amount']
            );

            if (!$stmt->execute()) {
                throw new Exception("Error saving voucher item: " . $stmt->error);
            }
        }

        // Update claims with payment details
        $sql = "UPDATE bills SET
            paid = 1,
            payment_no = ?,
            voucher_no = ?,
            voucher_user = ?,
            voucher_date = CURDATE()
        WHERE claim_no = ? AND invoice_no = ?";

        $stmt = $conn->prepare($sql);
        if (!$stmt) {
            throw new Exception("Error preparing claims update statement: " . $conn->error);
        }

        foreach ($data['claims'] as $claim) {
            $stmt->bind_param('sssss',
                $payment_no,
                $voucher_no,
                $_SESSION['user_id'],
                $claim['claim_no'],
                $claim['invoice_no']
            );

            if (!$stmt->execute()) {
                throw new Exception("Error updating claim " . $claim['claim_no'] . ": " . $stmt->error);
            }
        }

        // Log activity
        $sql = "INSERT INTO activity_log (
            user_id,
            action,
            table_name,
            record_id,
            new_values,
            ip_address,
            user_agent,
            action_date,
            additional_info
        ) VALUES (?, 'CREATE', 'bills_payment', ?, ?, ?, ?, NOW(), ?)";

        $stmt = $conn->prepare($sql);
        if (!$stmt) {
            throw new Exception("Error preparing activity log statement: " . $conn->error);
        }

        $new_values = json_encode([
            'payment_no' => $payment_no,
            'voucher_no' => $voucher_no,
            'amount' => $data['total_amount'],
            'payment_to' => $data['payment_to'],
            'recipient' => $data['recipient']
        ]);

        $additional_info = sprintf(
            "Payment processed for %d claim(s). Total amount: %.2f. Payment to: %s",
            count($data['claims']),
            $data['total_amount'],
            $data['recipient']['name']
        );

        $stmt->bind_param('ssssss',
            $_SESSION['user_id'],
            $payment_no,
            $new_values,
            $_SERVER['REMOTE_ADDR'],
            $_SERVER['HTTP_USER_AGENT'],
            $additional_info
        );

        if (!$stmt->execute()) {
            throw new Exception("Error logging activity: " . $stmt->error);
        }

        // Commit transaction
        $conn->commit();

        echo json_encode([
            'success' => true,
            'message' => 'Payment and voucher processed successfully',
            'payment_no' => $payment_no,
            'voucher_no' => $voucher_no,
            'total_amount' => $data['total_amount']
        ]);

    } catch (Exception $e) {
        // Rollback transaction on error
        $conn->rollback();
        throw $e;
    }

} catch (Exception $e) {
    error_log("Payment processing error: " . $e->getMessage());
    echo json_encode([
        'success' => false,
        'error' => $e->getMessage()
    ]);
}

/**
 * Generates a new payment number
 */
function generatePaymentNumber($conn) {
    $year = date('Y');
    $sql = "SELECT MAX(CAST(SUBSTRING(payment_no, 5) AS UNSIGNED)) as max_no
            FROM bills_payment WHERE payment_no LIKE '$year%'";
    $result = $conn->query($sql);
    if (!$result) {
        throw new Exception("Error generating payment number: " . $conn->error);
    }

    $row = $result->fetch_assoc();
    $next_no = ($row['max_no'] ?? 0) + 1;
    return $year . str_pad($next_no, 4, '0', STR_PAD_LEFT);
}

/**
 * Generates a new voucher number
 */
function generateVoucherNumber($conn) {
    $year = date('Y');
    $sql = "SELECT MAX(CAST(SUBSTRING(voucher_no, 9) AS UNSIGNED)) as max_no
            FROM bills_payment WHERE voucher_no LIKE 'VCH-$year%'";
    $result = $conn->query($sql);
    if (!$result) {
        throw new Exception("Error generating voucher number: " . $conn->error);
    }

    $row = $result->fetch_assoc();
    $next_no = ($row['max_no'] ?? 0) + 1;
    return 'VCH-' . $year . str_pad($next_no, 4, '0', STR_PAD_LEFT);
}

$conn->close();
?>
