<?php
// api/record_payment.php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

header('Content-Type: application/json');
header('Access-Control-Allow-Origin', '*');

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

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

if (!$data || !isset($data['contractId']) || !isset($data['amount']) || !isset($data['paymentDate'])) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Invalid payload']);
    exit;
}

$contractId  = (int)$data['contractId'];
$clientId    = isset($data['clientId']) ? (int)$data['clientId'] : 0;
$amount      = (float)$data['amount'];
$paymentDate = $data['paymentDate']; // yyyy-MM-dd
$method      = $data['method'] ?? 'Other';
$reference   = $data['reference'] ?? null;
$notes       = $data['notes'] ?? null;

try {
    $pdo->beginTransaction();

    // Validate the payment against the current outstanding balance before insert.
    $sqlFinal = "SELECT FinalPrice FROM ClientContracts WHERE Id = :Id LIMIT 1 FOR UPDATE";
    $stmt = $pdo->prepare($sqlFinal);
    $stmt->execute([':Id' => $contractId]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$row) {
        throw new Exception('Contract not found.');
    }

    $finalPrice = (float)$row['FinalPrice'];

    $sqlTotalPaidBefore = "
        SELECT IFNULL(SUM(Amount), 0) AS TotalPaid
        FROM ClientPayments
        WHERE ContractId = :Id
          AND (IsDeleted IS NULL OR IsDeleted = 0)
    ";
    $stmt = $pdo->prepare($sqlTotalPaidBefore);
    $stmt->execute([':Id' => $contractId]);
    $paidRow = $stmt->fetch(PDO::FETCH_ASSOC);
    $totalPaidBefore = $paidRow ? (float)$paidRow['TotalPaid'] : 0.0;
    $outstandingBefore = max($finalPrice - $totalPaidBefore, 0);

    if ($amount <= 0) {
        $pdo->rollBack();
        http_response_code(400);
        echo json_encode(['success' => false, 'message' => 'Payment amount must be greater than zero.']);
        exit;
    }

    if ($amount > ($outstandingBefore + 0.01)) {
        $pdo->rollBack();
        http_response_code(400);
        echo json_encode([
            'success' => false,
            'message' => 'Overpayment is not allowed.',
            'outstanding' => $outstandingBefore
        ]);
        exit;
    }

    // Insert payment
    $uuid      = bin2hex(random_bytes(16));
    $nowUtc    = gmdate('Y-m-d H:i:s');
    $createdAt = date('Y-m-d H:i:s');

    $sqlInsert = "
        INSERT INTO ClientPayments 
            (ContractId, PaymentDate, Amount, Method, Reference, Notes, CreatedAt,
             Uuid, LastModified, IsDeleted)
        VALUES 
            (:ContractId, :PaymentDate, :Amount, :Method, :Reference, :Notes, :CreatedAt,
             :Uuid, :LastModified, 0)
    ";
    $stmt = $pdo->prepare($sqlInsert);
    $stmt->execute([
        ':ContractId'  => $contractId,
        ':PaymentDate' => $paymentDate,
        ':Amount'      => $amount,
        ':Method'      => $method,
        ':Reference'   => $reference,
        ':Notes'       => $notes,
        ':CreatedAt'   => $createdAt,
        ':Uuid'        => $uuid,
        ':LastModified'=> $nowUtc,
    ]);

    $paymentId = (int)$pdo->lastInsertId();
    $invoiceNumber = "INV-" . $paymentId;

    // Update invoice number
    $sqlInv = "
        UPDATE ClientPayments
        SET InvoiceNumber = :InvoiceNumber,
            LastModified  = :LastModified
        WHERE Id = :Id
    ";
    $stmt = $pdo->prepare($sqlInv);
    $stmt->execute([
        ':InvoiceNumber' => $invoiceNumber,
        ':LastModified'  => $nowUtc,
        ':Id'            => $paymentId,
    ]);

    // Get total paid after this payment
    $sqlTotalPaid = "
        SELECT IFNULL(SUM(Amount), 0) AS TotalPaid
        FROM ClientPayments
        WHERE ContractId = :Id
          AND (IsDeleted IS NULL OR IsDeleted = 0)
    ";
    $stmt = $pdo->prepare($sqlTotalPaid);
    $stmt->execute([':Id' => $contractId]);
    $paidRow = $stmt->fetch(PDO::FETCH_ASSOC);
    $totalPaidAfter = $paidRow ? (float)$paidRow['TotalPaid'] : 0.0;

    $outstanding = $finalPrice - $totalPaidAfter;
    if ($outstanding < 0) $outstanding = 0.0;

    // Update contract status if fully paid
    if ($totalPaidAfter >= $finalPrice) {
        $sqlStatus = "
            UPDATE ClientContracts
            SET Status = 'Completed'
            WHERE Id = :Id
        ";
        $stmt = $pdo->prepare($sqlStatus);
        $stmt->execute([':Id' => $contractId]);
    }

    $pdo->commit();

    echo json_encode([
        'success'        => true,
        'message'        => 'Payment recorded',
        'paymentId'      => $paymentId,
        'invoiceNumber'  => $invoiceNumber,
        'finalPrice'     => $finalPrice,
        'totalPaidAfter' => $totalPaidAfter,
        'outstanding'    => $outstanding
    ]);
} catch (Exception $e) {
    $pdo->rollBack();
    http_response_code(500);
    echo json_encode([
        'success' => false,
        'message' => 'Failed to record payment',
        'details' => $e->getMessage()
    ]);
}
