properties

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Property Manager</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Inter', sans-serif;
            background-color: #f0f4f8; /* Light blue-gray background */
            color: #1e293b; /* Dark slate text */
            min-height: 100vh;
            display: flex;
            flex-direction: column;
        }
        .container {
            background-color: #ffffff;
            border-radius: 1.5rem;
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
            padding: 2rem;
            margin: 2rem auto;
            width: 95%;
            max-width: 1200px;
            flex-grow: 1;
            display: flex;
            flex-direction: column;
            gap: 1.5rem;
        }
        .tab-button {
            padding: 0.75rem 1.5rem;
            border-radius: 0.75rem;
            font-weight: 600;
            transition: all 0.2s ease-in-out;
            cursor: pointer;
            background-color: #e2e8f0; /* Light gray */
            color: #475569; /* Slate gray */
        }
        .tab-button.active {
            background-color: #4f46e5; /* Indigo */
            color: white;
            box-shadow: 0 4px 10px rgba(79, 70, 229, 0.3);
        }
        .tab-button:hover:not(.active) {
            background-color: #cbd5e1; /* Lighter gray on hover */
        }
        .form-group label {
            display: block;
            margin-bottom: 0.5rem;
            font-weight: 600;
            color: #334155;
        }
        .form-group input[type="text"],
        .form-group input[type="number"],
        .form-group input[type="date"],
        .form-group select,
        .form-group textarea {
            width: 100%;
            padding: 0.75rem 1rem;
            border: 1px solid #cbd5e1;
            border-radius: 0.75rem;
            background-color: #f8fafc;
            font-size: 1rem;
            color: #334155;
            transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
        }
        .form-group input:focus,
        .form-group select:focus,
        .form-group textarea:focus {
            outline: none;
            border-color: #6366f1; /* Blue-indigo */
            box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
        }
        .btn-primary {
            background-color: #4f46e5; /* Indigo */
            color: white;
            border: none;
            border-radius: 0.75rem;
            padding: 0.75rem 1.5rem;
            font-size: 1rem;
            font-weight: 600;
            cursor: pointer;
            transition: background-color 0.2s ease-in-out, transform 0.1s ease-in-out;
            box-shadow: 0 4px 10px rgba(79, 70, 229, 0.3);
        }
        .btn-primary:hover {
            background-color: #4338ca; /* Darker indigo */
            transform: translateY(-1px);
        }
        .btn-primary:active {
            transform: translateY(0);
        }
        .message-box {
            background-color: #fff;
            border-radius: 0.75rem;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
            padding: 1.5rem;
            max-width: 400px;
            text-align: center;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            z-index: 1000;
            display: none; /* Hidden by default */
        }
        .message-box-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 999;
            display: none; /* Hidden by default */
        }
        .message-box-content {
            margin-bottom: 1rem;
            color: #334155;
        }
        .message-box-button {
            background-color: #4f46e5;
            color: white;
            border: none;
            border-radius: 0.5rem;
            padding: 0.5rem 1rem;
            cursor: pointer;
            transition: background-color 0.2s;
        }
        .message-box-button:hover {
            background-color: #4338ca;
        }
        .loading-spinner {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #4f46e5;
            border-radius: 50%;
            width: 30px;
            height: 30px;
            animation: spin 1s linear infinite;
            margin: 1rem auto;
            display: none; /* Hidden by default */
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .error-message {
            color: #ef4444; /* Red for errors */
            margin-top: 0.5rem;
            font-size: 0.9rem;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 1.5rem;
            background-color: #ffffff;
            border-radius: 0.75rem;
            overflow: hidden; /* Ensures rounded corners apply to content */
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
        }
        th, td {
            padding: 1rem 1.25rem;
            text-align: left;
            border-bottom: 1px solid #e2e8f0;
        }
        th {
            background-color: #f8fafc;
            font-weight: 600;
            color: #334155;
            text-transform: uppercase;
            font-size: 0.85rem;
        }
        tr:last-child td {
            border-bottom: none;
        }
        .action-buttons button {
            background-color: #ef4444; /* Red for delete */
            color: white;
            border: none;
            border-radius: 0.5rem;
            padding: 0.4rem 0.8rem;
            font-size: 0.8rem;
            cursor: pointer;
            transition: background-color 0.2s;
        }
        .action-buttons button:hover {
            background-color: #dc2626;
        }
        .action-buttons button.edit-btn {
            background-color: #22c55e; /* Green for edit */
            margin-right: 0.5rem;
        }
        .action-buttons button.edit-btn:hover {
            background-color: #16a34a;
        }
        .report-summary-card {
            background-color: #edf2f7; /* Light gray-blue */
            border-radius: 0.75rem;
            padding: 1.5rem;
            text-align: center;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
        }
        .report-summary-card h4 {
            font-size: 1.125rem;
            font-weight: 600;
            color: #475569;
            margin-bottom: 0.5rem;
        }
        .report-summary-card p {
            font-size: 2.25rem;
            font-weight: 700;
            color: #1e293b;
        }
        .report-summary-card.income p {
            color: #22c55e; /* Green */
        }
        .report-summary-card.expense p {
            color: #ef4444; /* Red */
        }
        .report-summary-card.profit p {
            color: #3b82f6; /* Blue */
        }


        /* Responsive adjustments */
        @media (max-width: 768px) {
            .container {
                padding: 1rem;
                margin: 1rem auto;
            }
            .tab-buttons {
                flex-direction: column;
            }
            .tab-button {
                width: 100%;
                margin-bottom: 0.5rem;
            }
            .form-grid {
                grid-template-columns: 1fr;
            }
            th, td {
                padding: 0.75rem 0.8rem;
                font-size: 0.9rem;
            }
            table thead {
                display: none; /* Hide table headers on small screens */
            }
            table, tbody, tr, td {
                display: block;
                width: 100%;
            }
            tr {
                margin-bottom: 1rem;
                border: 1px solid #e2e8f0;
                border-radius: 0.75rem;
                padding: 1rem;
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
            }
            td {
                text-align: right;
                padding-left: 50%;
                position: relative;
                border: none;
            }
            td::before {
                content: attr(data-label);
                position: absolute;
                left: 0;
                width: 50%;
                padding-left: 1rem;
                font-weight: 600;
                text-align: left;
                color: #334155;
            }
            .action-buttons {
                text-align: left;
                padding-left: 1rem;
                margin-top: 1rem;
            }
            .report-summary-grid {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1 class="text-4xl font-extrabold text-gray-900 mb-6 text-center">Property Management Software</h1>

        <div class="text-sm text-gray-600 text-center mb-4">
            User ID: <span id="userIdDisplay" class="font-mono text-blue-600">Loading...</span>
        </div>

        <div class="flex flex-wrap justify-center gap-4 mb-8 tab-buttons">
            <button id="propertiesTab" class="tab-button active">Properties</button>
            <button id="tenantsTab" class="tab-button">Tenants</button>
            <button id="incomeTab" class="tab-button">Income</button>
            <button id="expensesTab" class="tab-button">Expenses</button>
            <button id="reportsTab" class="tab-button">Reports</button>
        </div>

        <section id="propertiesSection" class="tab-content">
            <h2 class="text-2xl font-bold text-gray-800 mb-6">Manage Properties</h2>

            <form id="addPropertyForm" class="bg-gray-50 p-6 rounded-xl shadow-inner mb-8 grid grid-cols-1 md:grid-cols-2 gap-4 form-grid">
                <div class="form-group">
                    <label for="propertyName">Property Name</label>
                    <input type="text" id="propertyName" placeholder="e.g., Downtown Loft" required>
                </div>
                <div class="form-group">
                    <label for="propertyAddress">Address</label>
                    <input type="text" id="propertyAddress" placeholder="e.g., 123 Main St, City, State" required>
                </div>
                <div class="form-group">
                    <label for="propertyType">Type</label>
                    <select id="propertyType" required>
                        <option value="">Select Type</option>
                        <option value="Residential">Residential</option>
                        <option value="Commercial">Commercial</option>
                        <option value="Land">Land</option>
                        <option value="Other">Other</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="propertyPurchaseDate">Purchase Date</label>
                    <input type="date" id="propertyPurchaseDate">
                </div>
                <div class="md:col-span-2 text-right">
                    <button type="submit" class="btn-primary">Add Property</button>
                </div>
            </form>

            <h3 class="text-xl font-bold text-gray-800 mb-4">Your Properties</h3>
            <div id="propertiesList" class="relative">
                <div class="loading-spinner" id="propertiesLoading"></div>
                <p id="noPropertiesMessage" class="text-gray-500 text-center py-4 hidden">No properties added yet.</p>
                <table id="propertiesTable" class="min-w-full hidden">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Address</th>
                            <th>Type</th>
                            <th>Purchase Date</th>
                            <th>Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        </tbody>
                </table>
            </div>
        </section>

        <section id="tenantsSection" class="tab-content hidden">
            <h2 class="text-2xl font-bold text-gray-800 mb-6">Manage Tenants</h2>

            <form id="addTenantForm" class="bg-gray-50 p-6 rounded-xl shadow-inner mb-8 grid grid-cols-1 md:grid-cols-2 gap-4 form-grid">
                <div class="form-group">
                    <label for="tenantName">Tenant Name</label>
                    <input type="text" id="tenantName" placeholder="e.g., John Doe" required>
                </div>
                <div class="form-group">
                    <label for="tenantContact">Contact Info</label>
                    <input type="text" id="tenantContact" placeholder="e.g., john.doe@example.com or 555-123-4567" required>
                </div>
                <div class="form-group">
                    <label for="tenantProperty">Property</label>
                    <select id="tenantProperty" required>
                        <option value="">Select Property</option>
                        </select>
                </div>
                <div class="form-group">
                    <label for="leaseStartDate">Lease Start Date</label>
                    <input type="date" id="leaseStartDate" required>
                </div>
                <div class="form-group">
                    <label for="leaseEndDate">Lease End Date</label>
                    <input type="date" id="leaseEndDate">
                </div>
                <div class="form-group">
                    <label for="tenantRentAmount">Monthly Rent ($)</label>
                    <input type="number" id="tenantRentAmount" step="0.01" min="0" placeholder="e.g., 1500.00" required>
                </div>
                <div class="form-group">
                    <label for="tenantDepositAmount">Security Deposit ($)</label>
                    <input type="number" id="tenantDepositAmount" step="0.01" min="0" placeholder="e.g., 1500.00">
                </div>
                <div class="md:col-span-2 text-right">
                    <button type="submit" class="btn-primary">Add Tenant</button>
                </div>
            </form>

            <h3 class="text-xl font-bold text-gray-800 mb-4">Your Tenants</h3>
            <div id="tenantsList" class="relative">
                <div class="loading-spinner" id="tenantsLoading"></div>
                <p id="noTenantsMessage" class="text-gray-500 text-center py-4 hidden">No tenants added yet.</p>
                <table id="tenantsTable" class="min-w-full hidden">
                    <thead>
                        <tr>
                            <th>Name</th>
                            <th>Contact</th>
                            <th>Property</th>
                            <th>Lease Start</th>
                            <th>Lease End</th>
                            <th>Rent</th>
                            <th>Deposit</th>
                            <th>Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        </tbody>
                </table>
            </div>
        </section>

        <section id="incomeSection" class="tab-content hidden">
            <h2 class="text-2xl font-bold text-gray-800 mb-6">Track Income</h2>

            <form id="addIncomeForm" class="bg-gray-50 p-6 rounded-xl shadow-inner mb-8 grid grid-cols-1 md:grid-cols-2 gap-4 form-grid">
                <div class="form-group">
                    <label for="incomeProperty">Property</label>
                    <select id="incomeProperty" required>
                        <option value="">Select Property</option>
                        </select>
                </div>
                <div class="form-group">
                    <label for="incomeCategory">Category</label>
                    <select id="incomeCategory" required>
                        <option value="">Select Category</option>
                        <option value="Rent">Rent</option>
                        <option value="Late Fee">Late Fee</option>
                        <option value="Other Income">Other Income</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="incomeAmount">Amount ($)</label>
                    <input type="number" id="incomeAmount" step="0.01" min="0" placeholder="e.g., 1200.00" required>
                </div>
                <div class="form-group">
                    <label for="incomeDate">Date</label>
                    <input type="date" id="incomeDate" required>
                </div>
                <div class="form-group md:col-span-2">
                    <label for="incomeDescription">Description (Optional)</label>
                    <textarea id="incomeDescription" rows="2" placeholder="e.g., July rent payment"></textarea>
                </div>
                <div class="md:col-span-2 text-right">
                    <button type="submit" class="btn-primary">Add Income</button>
                </div>
            </form>

            <h3 class="text-xl font-bold text-gray-800 mb-4">Income Records</h3>
            <div id="incomeList" class="relative">
                <div class="loading-spinner" id="incomeLoading"></div>
                <p id="noIncomeMessage" class="text-gray-500 text-center py-4 hidden">No income records yet.</p>
                <table id="incomeTable" class="min-w-full hidden">
                    <thead>
                        <tr>
                            <th>Property</th>
                            <th>Category</th>
                            <th>Amount</th>
                            <th>Date</th>
                            <th>Description</th>
                            <th>Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        </tbody>
                </table>
            </div>
        </section>

        <section id="expensesSection" class="tab-content hidden">
            <h2 class="text-2xl font-bold text-gray-800 mb-6">Track Expenses</h2>

            <form id="addExpenseForm" class="bg-gray-50 p-6 rounded-xl shadow-inner mb-8 grid grid-cols-1 md:grid-cols-2 gap-4 form-grid">
                <div class="form-group">
                    <label for="expenseProperty">Property</label>
                    <select id="expenseProperty" required>
                        <option value="">Select Property</option>
                        </select>
                </div>
                <div class="form-group">
                    <label for="expenseCategory">Category</label>
                    <select id="expenseCategory" required>
                        <option value="">Select Category</option>
                        <option value="Repairs">Repairs</option>
                        <option value="Utilities">Utilities</option>
                        <option value="Property Tax">Property Tax</option>
                        <option value="Insurance">Insurance</option>
                        <option value="Mortgage">Mortgage</option>
                        <option value="Maintenance">Maintenance</option>
                        <option value="Other Expense">Other Expense</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="expenseAmount">Amount ($)</label>
                    <input type="number" id="expenseAmount" step="0.01" min="0" placeholder="e.g., 250.50" required>
                </div>
                <div class="form-group">
                    <label for="expenseDate">Date</label>
                    <input type="date" id="expenseDate" required>
                </div>
                <div class="form-group md:col-span-2">
                    <label for="expenseDescription">Description (Optional)</label>
                    <textarea id="expenseDescription" rows="2" placeholder="e.g., Plumbing repair for bathroom"></textarea>
                </div>
                <div class="md:col-span-2 text-right">
                    <button type="submit" class="btn-primary">Add Expense</button>
                </div>
            </form>

            <h3 class="text-xl font-bold text-gray-800 mb-4">Expense Records</h3>
            <div id="expensesList" class="relative">
                <div class="loading-spinner" id="expensesLoading"></div>
                <p id="noExpensesMessage" class="text-gray-500 text-center py-4 hidden">No expense records yet.</p>
                <table id="expensesTable" class="min-w-full hidden">
                    <thead>
                        <tr>
                            <th>Property</th>
                            <th>Category</th>
                            <th>Amount</th>
                            <th>Date</th>
                            <th>Description</th>
                            <th>Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        </tbody>
                </table>
            </div>
        </section>

        <section id="reportsSection" class="tab-content hidden">
            <h2 class="text-2xl font-bold text-gray-800 mb-6">Financial Reports</h2>

            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 report-summary-grid">
                <div class="report-summary-card income">
                    <h4>Total Income</h4>
                    <p id="totalIncome">$0.00</p>
                </div>
                <div class="report-summary-card expense">
                    <h4>Total Expenses</h4>
                    <p id="totalExpenses">$0.00</p>
                </div>
                <div class="report-summary-card profit">
                    <h4>Net Profit</h4>
                    <p id="netProfit">$0.00</p>
                </div>
            </div>

            <h3 class="text-xl font-bold text-gray-800 mt-8 mb-4">Detailed Breakdown (All Transactions)</h3>
            <div id="allTransactionsList" class="relative">
                <div class="loading-spinner" id="reportsLoading"></div>
                <p id="noReportsMessage" class="text-gray-500 text-center py-4 hidden">No transactions to report yet.</p>
                <table id="allTransactionsTable" class="min-w-full hidden">
                    <thead>
                        <tr>
                            <th>Type</th>
                            <th>Property</th>
                            <th>Category</th>
                            <th>Amount</th>
                            <th>Date</th>
                            <th>Description</th>
                        </tr>
                    </thead>
                    <tbody>
                        </tbody>
                </table>
            </div>
        </section>
    </div>

    <div id="messageBoxOverlay" class="message-box-overlay"></div>
    <div id="messageBox" class="message-box">
        <div id="messageBoxContent" class="message-box-content"></div>
        <button id="messageBoxClose" class="message-box-button">OK</button>
    </div>

    <script type="module">
        // Import Firebase modules
        import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-app.js";
        import { getAuth, signInAnonymously, signInWithCustomToken, onAuthStateChanged } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-auth.js";
        import { getFirestore, collection, addDoc, getDocs, doc, deleteDoc, onSnapshot, query, where, serverTimestamp, updateDoc } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-firestore.js";

        // Global variables provided by the Canvas environment
        const appId = typeof __app_id !== 'undefined' ? __app_id : 'default-app-id';
        const firebaseConfig = typeof __firebase_config !== 'undefined' ? JSON.parse(__firebase_config) : {};
        const initialAuthToken = typeof __initial_auth_token !== 'undefined' ? __initial_auth_token : null;

        // Firebase App and Services
        let app;
        let db;
        let auth;
        let currentUserId = null;
        let isAuthReady = false;

        // DOM Elements
        const propertiesTab = document.getElementById('propertiesTab');
        const tenantsTab = document.getElementById('tenantsTab'); // New
        const incomeTab = document.getElementById('incomeTab');
        const expensesTab = document.getElementById('expensesTab');
        const reportsTab = document.getElementById('reportsTab'); // New

        const propertiesSection = document.getElementById('propertiesSection');
        const tenantsSection = document.getElementById('tenantsSection'); // New
        const incomeSection = document.getElementById('incomeSection');
        const expensesSection = document.getElementById('expensesSection');
        const reportsSection = document.getElementById('reportsSection'); // New

        const addPropertyForm = document.getElementById('addPropertyForm');
        const propertiesTableBody = document.querySelector('#propertiesTable tbody');
        const propertiesTable = document.getElementById('propertiesTable');
        const noPropertiesMessage = document.getElementById('noPropertiesMessage');
        const propertiesLoading = document.getElementById('propertiesLoading');

        const addTenantForm = document.getElementById('addTenantForm'); // New
        const tenantPropertySelect = document.getElementById('tenantProperty'); // New
        const tenantsTableBody = document.querySelector('#tenantsTable tbody'); // New
        const tenantsTable = document.getElementById('tenantsTable'); // New
        const noTenantsMessage = document.getElementById('noTenantsMessage'); // New
        const tenantsLoading = document.getElementById('tenantsLoading'); // New

        const addIncomeForm = document.getElementById('addIncomeForm');
        const incomePropertySelect = document.getElementById('incomeProperty');
        const incomeTableBody = document.querySelector('#incomeTable tbody');
        const incomeTable = document.getElementById('incomeTable');
        const noIncomeMessage = document.getElementById('noIncomeMessage');
        const incomeLoading = document.getElementById('incomeLoading');

        const addExpenseForm = document.getElementById('addExpenseForm');
        const expensePropertySelect = document.getElementById('expenseProperty');
        const expensesTableBody = document.querySelector('#expensesTable tbody');
        const expensesTable = document.getElementById('expensesTable');
        const noExpensesMessage = document.getElementById('noExpensesMessage');
        const expensesLoading = document.getElementById('expensesLoading');

        const totalIncomeDisplay = document.getElementById('totalIncome'); // New
        const totalExpensesDisplay = document.getElementById('totalExpenses'); // New
        const netProfitDisplay = document.getElementById('netProfit'); // New
        const allTransactionsTableBody = document.querySelector('#allTransactionsTable tbody'); // New
        const allTransactionsTable = document.getElementById('allTransactionsTable'); // New
        const noReportsMessage = document.getElementById('noReportsMessage'); // New
        const reportsLoading = document.getElementById('reportsLoading'); // New


        const userIdDisplay = document.getElementById('userIdDisplay');

        const messageBox = document.getElementById('messageBox');
        const messageBoxOverlay = document.getElementById('messageBoxOverlay');
        const messageBoxContent = document.getElementById('messageBoxContent');
        const messageBoxClose = document.getElementById('messageBoxClose');

        let allProperties = []; // Store properties to populate select dropdowns
        let allTenants = []; // Store tenants
        let allTransactions = []; // Store all income and expense transactions for reporting

        let unsubscribeProperties = null;
        let unsubscribeTenants = null; // New
        let unsubscribeIncome = null;
        let unsubscribeExpenses = null;

        /**
         * Displays a custom message box instead of alert/confirm.
         * @param {string} message - The message to display.
         * @param {function} [onClose] - Optional callback function when the OK button is clicked.
         */
        function showMessageBox(message, onClose = null) {
            messageBoxContent.textContent = message;
            messageBox.style.display = 'block';
            messageBoxOverlay.style.display = 'block';

            const closeHandler = () => {
                messageBox.style.display = 'none';
                messageBoxOverlay.style.display = 'none';
                messageBoxClose.removeEventListener('click', closeHandler);
                if (onClose) {
                    onClose();
                }
            };
            messageBoxClose.addEventListener('click', closeHandler);
        }

        /**
         * Initializes Firebase and sets up authentication.
         */
        async function initializeFirebase() {
            try {
                app = initializeApp(firebaseConfig);
                db = getFirestore(app);
                auth = getAuth(app);

                // Listen for auth state changes
                onAuthStateChanged(auth, async (user) => {
                    if (user) {
                        currentUserId = user.uid;
                        userIdDisplay.textContent = currentUserId;
                        isAuthReady = true;
                        console.log("Firebase authenticated. User ID:", currentUserId);
                        // Once authenticated, start listening to data
                        setupFirestoreListeners();
                    } else {
                        // Not authenticated, try to sign in
                        if (initialAuthToken) {
                            await signInWithCustomToken(auth, initialAuthToken);
                        } else {
                            await signInAnonymously(auth);
                        }
                    }
                });
            } catch (error) {
                console.error("Error initializing Firebase or authenticating:", error);
                showMessageBox("Failed to initialize the application. Please try again later.");
            }
        }

        /**
         * Sets up real-time listeners for properties, income, and expenses.
         * This function should only be called once authentication is ready.
         */
        function setupFirestoreListeners() {
            if (!isAuthReady || !currentUserId) {
                console.warn("Authentication not ready, skipping Firestore listeners setup.");
                return;
            }

            // Unsubscribe from previous listeners if they exist
            if (unsubscribeProperties) unsubscribeProperties();
            if (unsubscribeTenants) unsubscribeTenants(); // New
            if (unsubscribeIncome) unsubscribeIncome();
            if (unsubscribeExpenses) unsubscribeExpenses();


            // Listen for properties
            propertiesLoading.style.display = 'block';
            const propertiesQuery = query(collection(db, `artifacts/${appId}/users/${currentUserId}/properties`));
            unsubscribeProperties = onSnapshot(propertiesQuery, (snapshot) => {
                allProperties = [];
                propertiesTableBody.innerHTML = '';
                if (snapshot.empty) {
                    noPropertiesMessage.classList.remove('hidden');
                    propertiesTable.classList.add('hidden');
                } else {
                    noPropertiesMessage.classList.add('hidden');
                    propertiesTable.classList.remove('hidden');
                    snapshot.forEach(doc => {
                        const property = { id: doc.id, ...doc.data() };
                        allProperties.push(property);
                        renderPropertyRow(property);
                    });
                }
                populatePropertySelects(); // Update dropdowns when properties change
                propertiesLoading.style.display = 'none';
            }, (error) => {
                console.error("Error fetching properties:", error);
                showMessageBox("Error loading properties. Please refresh the page.");
                propertiesLoading.style.display = 'none';
            });

            // Listen for tenants (New)
            tenantsLoading.style.display = 'block';
            const tenantsQuery = query(collection(db, `artifacts/${appId}/users/${currentUserId}/tenants`));
            unsubscribeTenants = onSnapshot(tenantsQuery, (snapshot) => {
                allTenants = [];
                tenantsTableBody.innerHTML = '';
                if (snapshot.empty) {
                    noTenantsMessage.classList.remove('hidden');
                    tenantsTable.classList.add('hidden');
                } else {
                    noTenantsMessage.classList.add('hidden');
                    tenantsTable.classList.remove('hidden');
                    snapshot.forEach(doc => {
                        const tenant = { id: doc.id, ...doc.data() };
                        allTenants.push(tenant);
                        renderTenantRow(tenant);
                    });
                }
                tenantsLoading.style.display = 'none';
            }, (error) => {
                console.error("Error fetching tenants:", error);
                showMessageBox("Error loading tenants. Please refresh the page.");
                tenantsLoading.style.display = 'none';
            });


            // Listen for all transactions (income and expenses combined for reporting)
            reportsLoading.style.display = 'block';
            const allTransactionsQuery = query(collection(db, `artifacts/${appId}/users/${currentUserId}/transactions`));
            onSnapshot(allTransactionsQuery, (snapshot) => {
                allTransactions = [];
                snapshot.forEach(doc => {
                    allTransactions.push({ id: doc.id, ...doc.data() });
                });
                generateReport(); // Generate report whenever transactions change
                reportsLoading.style.display = 'none';
            }, (error) => {
                console.error("Error fetching all transactions for reports:", error);
                showMessageBox("Error loading transaction data for reports. Please refresh the page.");
                reportsLoading.style.display = 'none';
            });


            // Listen for income
            incomeLoading.style.display = 'block';
            const incomeQuery = query(collection(db, `artifacts/${appId}/users/${currentUserId}/transactions`), where("type", "==", "income"));
            unsubscribeIncome = onSnapshot(incomeQuery, (snapshot) => {
                incomeTableBody.innerHTML = '';
                if (snapshot.empty) {
                    noIncomeMessage.classList.remove('hidden');
                    incomeTable.classList.add('hidden');
                } else {
                    noIncomeMessage.classList.add('hidden');
                    incomeTable.classList.remove('hidden');
                    snapshot.forEach(doc => {
                        const income = { id: doc.id, ...doc.data() };
                        renderTransactionRow(income, incomeTableBody);
                    });
                }
                incomeLoading.style.display = 'none';
            }, (error) => {
                console.error("Error fetching income:", error);
                showMessageBox("Error loading income records. Please refresh the page.");
                incomeLoading.style.display = 'none';
            });

            // Listen for expenses
            expensesLoading.style.display = 'block';
            const expensesQuery = query(collection(db, `artifacts/${appId}/users/${currentUserId}/transactions`), where("type", "==", "expense"));
            unsubscribeExpenses = onSnapshot(expensesQuery, (snapshot) => {
                expensesTableBody.innerHTML = '';
                if (snapshot.empty) {
                    noExpensesMessage.classList.remove('hidden');
                    expensesTable.classList.add('hidden');
                } else {
                    noExpensesMessage.classList.add('hidden');
                    expensesTable.classList.remove('hidden');
                    snapshot.forEach(doc => {
                        const expense = { id: doc.id, ...doc.data() };
                        renderTransactionRow(expense, expensesTableBody);
                    });
                }
                expensesLoading.style.display = 'none';
            }, (error) => {
                console.error("Error fetching expenses:", error);
                showMessageBox("Error loading expense records. Please refresh the page.");
                expensesLoading.style.display = 'none';
            });
        }

        /**
         * Populates the property select dropdowns for income, expense, and tenant forms.
         */
        function populatePropertySelects() {
            incomePropertySelect.innerHTML = '<option value="">Select Property</option>';
            expensePropertySelect.innerHTML = '<option value="">Select Property</option>';
            tenantPropertySelect.innerHTML = '<option value="">Select Property</option>'; // New

            allProperties.forEach(property => {
                const optionIncome = document.createElement('option');
                optionIncome.value = property.id;
                optionIncome.textContent = property.name;
                incomePropertySelect.appendChild(optionIncome);

                const optionExpense = document.createElement('option');
                optionExpense.value = property.id;
                optionExpense.textContent = property.name;
                expensePropertySelect.appendChild(optionExpense);

                const optionTenant = document.createElement('option'); // New
                optionTenant.value = property.id;
                optionTenant.textContent = property.name;
                tenantPropertySelect.appendChild(optionTenant);
            });
        }

        /**
         * Renders a single property row in the properties table.
         * @param {object} property - The property object.
         */
        function renderPropertyRow(property) {
            const row = propertiesTableBody.insertRow();
            row.innerHTML = `
                <td data-label="Name">${property.name}</td>
                <td data-label="Address">${property.address}</td>
                <td data-label="Type">${property.type}</td>
                <td data-label="Purchase Date">${property.purchaseDate || 'N/A'}</td>
                <td data-label="Actions" class="action-buttons">
                    <button class="delete-btn" data-id="${property.id}" data-type="property">Delete</button>
                </td>
            `;
        }

        /**
         * Renders a single tenant row in the tenants table. (New)
         * @param {object} tenant - The tenant object.
         */
        function renderTenantRow(tenant) {
            const row = tenantsTableBody.insertRow();
            const propertyName = allProperties.find(p => p.id === tenant.propertyId)?.name || 'Unknown Property';
            row.innerHTML = `
                <td data-label="Name">${tenant.name}</td>
                <td data-label="Contact">${tenant.contact}</td>
                <td data-label="Property">${propertyName}</td>
                <td data-label="Lease Start">${tenant.leaseStartDate}</td>
                <td data-label="Lease End">${tenant.leaseEndDate || 'N/A'}</td>
                <td data-label="Rent">$${tenant.rentAmount.toFixed(2)}</td>
                <td data-label="Deposit">$${tenant.depositAmount ? tenant.depositAmount.toFixed(2) : 'N/A'}</td>
                <td data-label="Actions" class="action-buttons">
                    <button class="delete-btn" data-id="${tenant.id}" data-type="tenant">Delete</button>
                </td>
            `;
        }


        /**
         * Renders a single transaction (income or expense) row in its respective table.
         * @param {object} transaction - The transaction object.
         * @param {HTMLElement} tableBody - The tbody element to append the row to.
         */
        function renderTransactionRow(transaction, tableBody) {
            const row = tableBody.insertRow();
            const propertyName = allProperties.find(p => p.id === transaction.propertyId)?.name || 'Unknown Property';
            row.innerHTML = `
                <td data-label="Property">${propertyName}</td>
                <td data-label="Category">${transaction.category}</td>
                <td data-label="Amount">$${transaction.amount.toFixed(2)}</td>
                <td data-label="Date">${transaction.date}</td>
                <td data-label="Description">${transaction.description || 'N/A'}</td>
                <td data-label="Actions" class="action-buttons">
                    <button class="delete-btn" data-id="${transaction.id}" data-type="transaction">Delete</button>
                </td>
            `;
        }

        /**
         * Handles adding a new property to Firestore.
         * @param {Event} event - The form submission event.
         */
        async function handleAddProperty(event) {
            event.preventDefault();
            if (!isAuthReady) {
                showMessageBox("Application is still initializing. Please wait.");
                return;
            }

            const name = document.getElementById('propertyName').value.trim();
            const address = document.getElementById('propertyAddress').value.trim();
            const type = document.getElementById('propertyType').value;
            const purchaseDate = document.getElementById('propertyPurchaseDate').value;

            if (!name || !address || !type) {
                showMessageBox("Please fill in all required property fields.");
                return;
            }

            const submitButton = event.target.querySelector('button[type="submit"]');
            submitButton.disabled = true;

            try {
                await addDoc(collection(db, `artifacts/${appId}/users/${currentUserId}/properties`), {
                    name,
                    address,
                    type,
                    purchaseDate: purchaseDate || null,
                    userId: currentUserId,
                    createdAt: serverTimestamp()
                });
                addPropertyForm.reset();
                showMessageBox("Property added successfully!");
            } catch (error) {
                console.error("Error adding property:", error);
                showMessageBox("Failed to add property. Please try again.");
            } finally {
                submitButton.disabled = false;
            }
        }

        /**
         * Handles adding a new tenant to Firestore. (New)
         * @param {Event} event - The form submission event.
         */
        async function handleAddTenant(event) {
            event.preventDefault();
            if (!isAuthReady) {
                showMessageBox("Application is still initializing. Please wait.");
                return;
            }

            const name = document.getElementById('tenantName').value.trim();
            const contact = document.getElementById('tenantContact').value.trim();
            const propertyId = document.getElementById('tenantProperty').value;
            const leaseStartDate = document.getElementById('leaseStartDate').value;
            const leaseEndDate = document.getElementById('leaseEndDate').value;
            const rentAmount = parseFloat(document.getElementById('tenantRentAmount').value);
            const depositAmount = parseFloat(document.getElementById('tenantDepositAmount').value);

            if (!name || !contact || !propertyId || !leaseStartDate || isNaN(rentAmount) || rentAmount <= 0) {
                showMessageBox("Please fill in all required tenant fields correctly (Name, Contact, Property, Lease Start Date, Monthly Rent).");
                return;
            }

            const submitButton = event.target.querySelector('button[type="submit"]');
            submitButton.disabled = true;

            try {
                await addDoc(collection(db, `artifacts/${appId}/users/${currentUserId}/tenants`), {
                    name,
                    contact,
                    propertyId,
                    leaseStartDate,
                    leaseEndDate: leaseEndDate || null,
                    rentAmount,
                    depositAmount: isNaN(depositAmount) ? 0 : depositAmount,
                    userId: currentUserId,
                    createdAt: serverTimestamp()
                });
                addTenantForm.reset();
                showMessageBox("Tenant added successfully!");
            } catch (error) {
                console.error("Error adding tenant:", error);
                showMessageBox("Failed to add tenant. Please try again.");
            } finally {
                submitButton.disabled = false;
            }
        }

        /**
         * Handles adding a new income record to Firestore.
         * @param {Event} event - The form submission event.
         */
        async function handleAddIncome(event) {
            event.preventDefault();
            if (!isAuthReady) {
                showMessageBox("Application is still initializing. Please wait.");
                return;
            }

            const propertyId = incomePropertySelect.value;
            const category = document.getElementById('incomeCategory').value;
            const amount = parseFloat(document.getElementById('incomeAmount').value);
            const date = document.getElementById('incomeDate').value;
            const description = document.getElementById('incomeDescription').value.trim();

            if (!propertyId || !category || isNaN(amount) || amount <= 0 || !date) {
                showMessageBox("Please fill in all required income fields correctly.");
                return;
            }

            const submitButton = event.target.querySelector('button[type="submit"]');
            submitButton.disabled = true;

            try {
                await addDoc(collection(db, `artifacts/${appId}/users/${currentUserId}/transactions`), {
                    propertyId,
                    type: 'income',
                    category,
                    amount,
                    date,
                    description: description || null,
                    userId: currentUserId,
                    createdAt: serverTimestamp()
                });
                addIncomeForm.reset();
                showMessageBox("Income record added successfully!");
            } catch (error) {
                console.error("Error adding income:", error);
                showMessageBox("Failed to add income record. Please try again.");
            } finally {
                submitButton.disabled = false;
            }
        }

        /**
         * Handles adding a new expense record to Firestore.
         * @param {Event} event - The form submission event.
         */
        async function handleAddExpense(event) {
            event.preventDefault();
            if (!isAuthReady) {
                showMessageBox("Application is still initializing. Please wait.");
                return;
            }

            const propertyId = expensePropertySelect.value;
            const category = document.getElementById('expenseCategory').value;
            const amount = parseFloat(document.getElementById('expenseAmount').value);
            const date = document.getElementById('expenseDate').value;
            const description = document.getElementById('expenseDescription').value.trim();

            if (!propertyId || !category || isNaN(amount) || amount <= 0 || !date) {
                showMessageBox("Please fill in all required expense fields correctly.");
                return;
            }

            const submitButton = event.target.querySelector('button[type="submit"]');
            submitButton.disabled = true;

            try {
                await addDoc(collection(db, `artifacts/${appId}/users/${currentUserId}/transactions`), {
                    propertyId,
                    type: 'expense',
                    category,
                    amount,
                    date,
                    description: description || null,
                    userId: currentUserId,
                    createdAt: serverTimestamp()
                });
                addExpenseForm.reset();
                showMessageBox("Expense record added successfully!");
            } catch (error) {
                console.error("Error adding expense:", error);
                showMessageBox("Failed to add expense record. Please try again.");
            } finally {
                submitButton.disabled = false;
            }
        }

        /**
         * Handles deleting a property, tenant, or transaction.
         * @param {string} id - The document ID to delete.
         * @param {string} type - 'property', 'tenant', or 'transaction'.
         */
        async function handleDelete(id, type) {
            if (!isAuthReady) {
                showMessageBox("Application is still initializing. Please wait.");
                return;
            }

            let collectionPath;
            switch (type) {
                case 'property':
                    collectionPath = `artifacts/${appId}/users/${currentUserId}/properties`;
                    break;
                case 'tenant':
                    collectionPath = `artifacts/${appId}/users/${currentUserId}/tenants`;
                    break;
                case 'transaction':
                    collectionPath = `artifacts/${appId}/users/${currentUserId}/transactions`;
                    break;
                default:
                    console.error("Invalid type for delete operation:", type);
                    showMessageBox("An unexpected error occurred during deletion.");
                    return;
            }

            // Custom confirmation dialog
            showMessageBox(`Are you sure you want to delete this ${type}? This action cannot be undone.`, async () => {
                try {
                    await deleteDoc(doc(db, collectionPath, id));
                    showMessageBox(`${type.charAt(0).toUpperCase() + type.slice(1)} deleted successfully!`);
                } catch (error) {
                    console.error(`Error deleting ${type}:`, error);
                    showMessageBox(`Failed to delete ${type}. Please try again.`);
                }
            });
        }

        /**
         * Generates and displays the financial report. (New)
         */
        function generateReport() {
            let totalIncome = 0;
            let totalExpenses = 0;

            allTransactionsTableBody.innerHTML = ''; // Clear previous report
            if (allTransactions.length === 0) {
                noReportsMessage.classList.remove('hidden');
                allTransactionsTable.classList.add('hidden');
                totalIncomeDisplay.textContent = '$0.00';
                totalExpensesDisplay.textContent = '$0.00';
                netProfitDisplay.textContent = '$0.00';
                return;
            } else {
                noReportsMessage.classList.add('hidden');
                allTransactionsTable.classList.remove('hidden');
            }

            // Sort transactions by date for the detailed breakdown
            const sortedTransactions = [...allTransactions].sort((a, b) => new Date(a.date) - new Date(b.date));

            sortedTransactions.forEach(transaction => {
                if (transaction.type === 'income') {
                    totalIncome += transaction.amount;
                } else if (transaction.type === 'expense') {
                    totalExpenses += transaction.amount;
                }
                renderReportTransactionRow(transaction);
            });

            const netProfit = totalIncome - totalExpenses;

            totalIncomeDisplay.textContent = `$${totalIncome.toFixed(2)}`;
            totalExpensesDisplay.textContent = `$${totalExpenses.toFixed(2)}`;
            netProfitDisplay.textContent = `$${netProfit.toFixed(2)}`;
        }

        /**
         * Renders a single transaction row in the all transactions report table. (New)
         * @param {object} transaction - The transaction object.
         */
        function renderReportTransactionRow(transaction) {
            const row = allTransactionsTableBody.insertRow();
            const propertyName = allProperties.find(p => p.id === transaction.propertyId)?.name || 'Unknown Property';
            const amountClass = transaction.type === 'income' ? 'text-green-600' : 'text-red-600';

            row.innerHTML = `
                <td data-label="Type" class="capitalize">${transaction.type}</td>
                <td data-label="Property">${propertyName}</td>
                <td data-label="Category">${transaction.category}</td>
                <td data-label="Amount" class="${amountClass}">$${transaction.amount.toFixed(2)}</td>
                <td data-label="Date">${transaction.date}</td>
                <td data-label="Description">${transaction.description || 'N/A'}</td>
            `;
        }


        /**
         * Switches between different sections (tabs).
         * @param {string} sectionId - The ID of the section to show.
         */
        function showSection(sectionId) {
            // Hide all sections
            propertiesSection.classList.add('hidden');
            tenantsSection.classList.add('hidden'); // New
            incomeSection.classList.add('hidden');
            expensesSection.classList.add('hidden');
            reportsSection.classList.add('hidden'); // New

            // Deactivate all tab buttons
            propertiesTab.classList.remove('active');
            tenantsTab.classList.remove('active'); // New
            incomeTab.classList.remove('active');
            expensesTab.classList.remove('active');
            reportsTab.classList.remove('active'); // New

            // Show the selected section and activate its button
            document.getElementById(sectionId).classList.remove('hidden');
            document.getElementById(sectionId.replace('Section', 'Tab')).classList.add('active');

            // If switching to reports, ensure report is generated
            if (sectionId === 'reportsSection') {
                generateReport();
            }
        }

        // Event Listeners for Tabs
        propertiesTab.addEventListener('click', () => showSection('propertiesSection'));
        tenantsTab.addEventListener('click', () => showSection('tenantsSection')); // New
        incomeTab.addEventListener('click', () => showSection('incomeSection'));
        expensesTab.addEventListener('click', () => showSection('expensesSection'));
        reportsTab.addEventListener('click', () => showSection('reportsSection')); // New

        // Event Listeners for Forms
        addPropertyForm.addEventListener('submit', handleAddProperty);
        addTenantForm.addEventListener('submit', handleAddTenant); // New
        addIncomeForm.addEventListener('submit', handleAddIncome);
        addExpenseForm.addEventListener('submit', handleAddExpense);

        // Event listener for delete buttons (delegated to document for dynamic elements)
        document.addEventListener('click', (event) => {
            if (event.target.classList.contains('delete-btn')) {
                const id = event.target.dataset.id;
                const type = event.target.dataset.type; // 'property', 'tenant', or 'transaction'
                handleDelete(id, type);
            }
        });

        // Initialize the app when the window loads
        window.onload = () => {
            initializeFirebase();
            showSection('propertiesSection'); // Show properties section by default
        };
    </script>
</body>
</html>