<?php
ob_start(); // start output buffering
header('Content-Type: application/json');
error_reporting(0);
ini_set('display_errors', 0);


include 'cors.php'; // Handles CORS preflight & headers
header('Content-Type: application/json');
include 'connection.php';
require 'vendor/autoload.php'; // Load Composer dependencies

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

$config = include 'config.php';
$secret_key = $config['secret_key'];
$issuer = $config['issuer'];
$audience = $config['audience'];

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

// Common JWT verification for both GET and POST
$headers = function_exists('apache_request_headers') ? apache_request_headers() : [];
if (!isset($headers['Authorization'])) {
    echo json_encode(["success" => false, "message" => "Authorization header missing"]);
    exit;
}

list($jwt) = sscanf($headers['Authorization'], 'Bearer %s');

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

    // ✅ Handle GET request - Fetch vouchers for this company
    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        $voucher_id = isset($_GET['voucher_number']) ? $_GET['voucher_id'] : null;

        if ($voucher_id) {
            // Fetch single voucher by voucher_id
            $query = "SELECT * FROM voucher WHERE com_id = ? AND voucher_number = ?";
            $stmt = $conn->prepare($query);
            $stmt->bind_param("is", $company_id, $voucher_id);
        } else {
            // Fetch all vouchers for the company
            $query = "SELECT * FROM voucher WHERE com_id = ? ORDER BY date DESC";
            $stmt = $conn->prepare($query);
            $stmt->bind_param("i", $company_id);
        }

        $stmt->execute();
        $result = $stmt->get_result();
        $data = [];

        while ($row = $result->fetch_assoc()) {
            $data[] = $row;
        }

        if (empty($data)) {
            echo json_encode(["success" => false, "message" => "No vouchers found"]);
        } else {
            echo json_encode(["success" => true, "data" => $data]);
        }

        $stmt->close();
        exit;
    }

    // ✅ Handle POST request - Insert new voucher
   /* if ($_SERVER['REQUEST_METHOD'] === 'POST') {

        $required_fields = ['voucher_id','date','from','to','purpose','amount'];
        foreach ($required_fields as $field) {
            if (!isset($_POST[$field]) || $_POST[$field] === '') {
                echo json_encode(["success" => false, "message" => "Required field missing: $field"]);
                exit;
            }
        }

        $voucher_id = $_POST['voucher_id'];
        $date = $_POST['date'];
        $from = $_POST['from'];
        $to = $_POST['to'];
        $purpose = $_POST['purpose'];
        $notes = $_POST['notes'] ?? '';
        $amount = floatval($_POST['amount']); 

        $formatted_date = date('Y-m-d', strtotime($date));

        $conn->begin_transaction();

        // Check duplicate voucher
        $checkQuery = "SELECT COUNT(*) AS count FROM voucher WHERE voucher_id = ? AND com_id = ?";
        $checkStmt = $conn->prepare($checkQuery);
        $checkStmt->bind_param("si", $voucher_id, $company_id);
        $checkStmt->execute();
        $checkRow = $checkStmt->get_result()->fetch_assoc();
        $checkStmt->close();

        if ($checkRow['count'] > 0) {
            $conn->rollback();
            echo json_encode(["success" => false, "message" => "Voucher ID already exists!"]);
            exit;
        }

        // Insert voucher
        $insertVoucher = "INSERT INTO voucher (uid, com_id, voucher_id, date, `from`, `to`, purpose, amount, notes)
                          VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $stmt = $conn->prepare($insertVoucher);
        $stmt->bind_param("sisssssds", $uid, $company_id, $voucher_id, $formatted_date, $from, $to, $purpose, $amount, $notes);

        if (!$stmt->execute()) {
            $conn->rollback();
            echo json_encode(["success" => false, "message" => "Failed to insert voucher", "error" => $stmt->error]);
            exit;
        }
        $stmt->close();

        // Ledger entries
        $ledgerEntries = [
            ['ledger' => $from, 'particulars' => $to, 'debit' => $amount, 'credit' => 0.00],
            ['ledger' => $to, 'particulars' => $from, 'debit' => 0.00, 'credit' => $amount]
        ];

        foreach ($ledgerEntries as $entry) {
            $checkLedger = "SELECT COUNT(*) AS count FROM ledger_day_wise WHERE voucher_number = ? AND ledger = ? AND com_id = ?";
            $stmtCheck = $conn->prepare($checkLedger);
            $stmtCheck->bind_param("ssi", $voucher_id, $entry['ledger'], $company_id);
            $stmtCheck->execute();
            $res = $stmtCheck->get_result()->fetch_assoc();
            $stmtCheck->close();

            if ($res['count'] == 0) {
                $insertLedger = "INSERT INTO ledger_day_wise 
                    (com_id, date, ledger, particulars, voucher_type, voucher_number, debit, credit)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
                $stmtLedger = $conn->prepare($insertLedger);
                $stmtLedger->bind_param(
                    "isssssdd",
                    $company_id,
                    $formatted_date,
                    $entry['ledger'],
                    $entry['particulars'],
                    $purpose,
                    $voucher_id,
                    $entry['debit'],
                    $entry['credit']
                );
                if (!$stmtLedger->execute()) {
                    $conn->rollback();
                    echo json_encode(["success" => false, "message" => "Failed to insert ledger entry", "error" => $stmtLedger->error]);
                    exit;
                }
                $stmtLedger->close();
            }
        }

        $conn->commit();
        echo json_encode(["success" => true, "message" => "Voucher and ledger entries inserted successfully"]);
        exit;
    }*/
    
     if ($_SERVER['REQUEST_METHOD'] === 'POST') {

        $required_fields = ['voucher_id','date','from','to','purpose','amount'];
        foreach ($required_fields as $field) {
            if (!isset($_POST[$field]) || $_POST[$field] === '') {
                echo json_encode(["success" => false, "message" => "Required field missing: $field"]);
                exit;
            }
        }

        $voucher_id = $_POST['voucher_id'];
        $date = $_POST['date'];
        $from = $_POST['from'];
        $to = $_POST['to'];
        $purpose = $_POST['purpose'];
        $notes = $_POST['notes'] ?? '';
        $amount = floatval($_POST['amount']); 

        $formatted_date = date('Y-m-d', strtotime($date));

        $conn->begin_transaction();

        // Check duplicate voucher
        $checkQuery = "SELECT COUNT(*) AS count FROM voucher WHERE voucher_id = ? AND com_id = ?";
        $checkStmt = $conn->prepare($checkQuery);
        $checkStmt->bind_param("si", $voucher_id, $company_id);
        $checkStmt->execute();
        $checkRow = $checkStmt->get_result()->fetch_assoc();
        $checkStmt->close();

        if ($checkRow['count'] > 0) {
            $conn->rollback();
            echo json_encode(["success" => false, "message" => "Voucher ID already exists!"]);
            exit;
        }

        // Insert voucher
        $insertVoucher = "INSERT INTO voucher (uid, com_id, voucher_id, date, `from`, `to`, purpose, amount, notes)
                          VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $stmt = $conn->prepare($insertVoucher);
        $stmt->bind_param("sisssssds", $uid, $company_id, $voucher_id, $formatted_date, $from, $to, $purpose, $amount, $notes);

        if (!$stmt->execute()) {
            $conn->rollback();
            echo json_encode(["success" => false, "message" => "Failed to insert voucher", "error" => $stmt->error]);
            exit;
        }
        $stmt->close();

        // Ledger entries
       // Ledger entries (unchanged)
$ledgerEntries = [
    ['ledger' => $from, 'particulars' => $to,   'credit' => $amount, 'debit' => 0.00],
    ['ledger' => $to,   'particulars' => $from, 'credit' => 0.00,   'debit' => $amount]
];

foreach ($ledgerEntries as $entry) {
    // Improved duplicate check: include debit and credit so two rows with same ledger but different dr/cr are allowed
    $checkLedger = "SELECT COUNT(*) AS count 
                    FROM ledger_day_wise 
                    WHERE voucher_number = ? AND ledger = ? AND com_id = ? AND debit = ? AND credit = ?";
    $stmtCheck = $conn->prepare($checkLedger);
    if (!$stmtCheck) {
        $conn->rollback();
        echo json_encode(["success" => false, "message" => "Prepare failed (checkLedger): " . $conn->error]);
        exit;
    }
    // types: voucher_number (s), ledger (s), com_id (i), debit (d), credit (d)
    $stmtCheck->bind_param("ssidd", $voucher_id, $entry['ledger'], $company_id, $entry['debit'], $entry['credit']);
    if (!$stmtCheck->execute()) {
        $stmtCheck->close();
        $conn->rollback();
        echo json_encode(["success" => false, "message" => "Execute failed (checkLedger): " . $stmtCheck->error]);
        exit;
    }
    $res = $stmtCheck->get_result()->fetch_assoc();
    $stmtCheck->close();

    if ($res['count'] == 0) {
        $insertLedger = "INSERT INTO ledger_day_wise 
            (com_id, uid, date, ledger, particulars, voucher_type, voucher_number, debit, credit)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $stmtLedger = $conn->prepare($insertLedger);
        if (!$stmtLedger) {
            $conn->rollback();
            echo json_encode(["success" => false, "message" => "Prepare failed (insertLedger): " . $conn->error]);
            exit;
        }
        // types: com_id (i), date (s), ledger (s), particulars (s), voucher_type (s), voucher_number (s), debit (d), credit (d)
        $stmtLedger->bind_param(
            "issssssdd",
            $company_id,
            $uid,
            $formatted_date,
            $entry['ledger'],
            $entry['particulars'],
            $purpose,
            $voucher_id,
            $entry['debit'],
            $entry['credit']
        );

        if (!$stmtLedger->execute()) {
            $stmtLedger->close();
            $conn->rollback();
            echo json_encode(["success" => false, "message" => "Failed to insert ledger entry", "error" => $stmtLedger->error]);
            exit;
        }
        $stmtLedger->close();
    } // end if count==0
} // end foreach


        $conn->commit();
        echo json_encode(["success" => true, "message" => "Voucher and ledger entries inserted successfully"]);
        exit;
    }
    


// ✅ Voucher Edit


elseif ($_SERVER['REQUEST_METHOD'] === 'PUT') {
    $data = json_decode(file_get_contents("php://input"), true);
    $voucher_id = $data['voucher_id'] ?? 0;

    if (!$voucher_id) {
        ob_clean(); 
        echo json_encode(["success" => false, "message" => "Voucher ID required"]); 
        exit;
    }

    // ✅ Date formatting
    $formatted_date = null;
    if (!empty($data['date'])) {
        $timestamp = strtotime(str_replace('/', '-', $data['date']));
        if ($timestamp) {
            $formatted_date = date('Y-m-d', $timestamp);
        }
    }

    if (!$formatted_date) {
        ob_clean(); 
        echo json_encode(["success" => false, "message" => "Invalid date format"]); 
        exit;
    }

    $from = $data['from'];
    $to = $data['to'];
    $purpose = $data['purpose'];
    $amount = floatval($data['amount']);

    $conn->begin_transaction();

    // ✅ Update voucher table
    $stmt = $conn->prepare("UPDATE voucher SET date = ?, `from` = ?, `to` = ?, purpose = ?, amount = ? WHERE voucher_id = ? AND com_id = ?");
    $stmt->bind_param("ssssdsi", $formatted_date, $from, $to, $purpose, $amount, $voucher_id, $company_id);

    if (!$stmt->execute()) {
        $conn->rollback();
        ob_clean(); 
        echo json_encode(["success" => false, "message" => "Voucher update failed: ".$stmt->error]); 
        exit;
    }
    $stmt->close();

    // ✅ Update existing ledger entries only (no insert)
    $ledgerEntries = [
        ['ledger' => $from, 'particulars' => $to, 'credit' => $amount, 'debit' => 0.00],
        ['ledger' => $to, 'particulars' => $from, 'credit' => 0.00, 'debit' => $amount]
    ];

    foreach ($ledgerEntries as $entry) {
        $updateLedger = "UPDATE ledger_day_wise 
                         SET date = ?, particulars = ?, voucher_type = ?, debit = ?, credit = ?
                         WHERE voucher_number = ? AND ledger = ? AND com_id = ?";
        $stmtLedger = $conn->prepare($updateLedger);
        $stmtLedger->bind_param(
            "sssddssi",
            $formatted_date,
            $entry['particulars'],
            $purpose,
            $entry['debit'],
            $entry['credit'],
            $voucher_id,
            $entry['ledger'],
            $company_id
        );

        if (!$stmtLedger->execute()) {
            $conn->rollback();
            ob_clean();
            echo json_encode(["success" => false, "message" => "Ledger update failed", "error" => $stmtLedger->error]);
            exit;
        }
        $stmtLedger->close();
    }

    // ✅ Commit all updates
    $conn->commit();
    ob_clean();
    echo json_encode(["success" => true, "message" => "Voucher and ledger entries updated successfully"]);
    exit;
}




    
     // ✅ DELETE: Remove deposit + ledger
// ✅ DELETE: Remove voucher + ledger_day_wise records
elseif ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
    $data = json_decode(file_get_contents("php://input"), true);
    $voucher_no = $data['voucher_id'] ?? '';

    if (empty($voucher_no)) {
        echo json_encode(["success" => false, "message" => "Voucher ID required"]);
        exit;
    }

    // 🔹 1. Delete from voucher table
    $stmt1 = $conn->prepare("DELETE FROM voucher WHERE voucher_id=? AND com_id=?");
    $stmt1->bind_param("si", $voucher_no, $company_id);
    $stmt1->execute();

    // 🔹 2. Delete from ledger_day_wise using voucher_number
    $stmt2 = $conn->prepare("DELETE FROM ledger_day_wise WHERE voucher_number=? AND com_id=?");
    $stmt2->bind_param("si", $voucher_no, $company_id);
    $stmt2->execute();

    // 🔍 Check if any of the two deletions affected rows
    if ($stmt1->affected_rows > 0 || $stmt2->affected_rows > 0) {
        echo json_encode(["success" => true, "message" => "Voucher & ledger entries deleted successfully"]);
    } else {
        echo json_encode(["success" => false, "message" => "No matching data found to delete"]);
    }

    $stmt1->close();
    $stmt2->close();
    exit;
}


    
    



    // Invalid Method
    echo json_encode(['success' => false, 'message' => 'Invalid request method']);

} catch (ExpiredException $e) {
    echo json_encode(["success" => false, "message" => "Token has expired"]);
} catch (Exception $e) {
    echo json_encode(["success" => false, "message" => "Error: " . $e->getMessage()]);
}

$conn->close();
?>
