/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
*/

document.addEventListener('DOMContentLoaded', () => {
    // Configuration for expense categories and their corresponding emojis.
    const CATEGORIES: { [key: string]: string } = {
        'Tanken': '⛽',
        'Maut': '톨',
        'Stellplatz': '⛺',
        'Lebensmitteleinkauf': '🛒',
        'Essen gehen': '🍽️',
        'Sonstiges': '🧾',
    };
    
    interface Expense {
        id: number;
        date: string;
        amount: number;
        category: string;
        note: string;
    }

    // DOM Element references
    const totalExpensesEl = document.getElementById('total-expenses');
    const categorySummaryEl = document.getElementById('category-summary');
    const transactionListEl = document.getElementById('transaction-list');
    const addExpenseBtn = document.getElementById('add-expense-btn');
    const exportCsvBtn = document.getElementById('export-csv-btn');
    // Add/Edit Modal
    const modal = document.getElementById('add-expense-modal') as HTMLDivElement;
    const expenseForm = document.getElementById('expense-form') as HTMLFormElement;
    const modalTitle = document.getElementById('modal-title');
    const cancelBtn = document.getElementById('cancel-btn');
    // Confirm Delete Modal
    const confirmModal = document.getElementById('confirm-modal') as HTMLDivElement;
    const confirmTextEl = document.getElementById('confirm-text');
    const confirmDeleteBtn = document.getElementById('confirm-delete-btn');
    const confirmCancelBtn = document.getElementById('confirm-cancel-btn');


    // Check if all essential elements are found
    if (!totalExpensesEl || !categorySummaryEl || !transactionListEl || !addExpenseBtn || !modal || !expenseForm || !cancelBtn || !exportCsvBtn || !modalTitle || !confirmModal || !confirmTextEl || !confirmDeleteBtn || !confirmCancelBtn) {
        console.error('Ein oder mehrere kritische DOM-Elemente wurden nicht gefunden. Die Anwendung kann nicht initialisiert werden.');
        return;
    }
    
    // In-memory store
    let expenses: Expense[] = [];
    let editingExpenseId: number | null = null;
    let expenseIdToDelete: number | null = null;

    // --- Data Persistence ---

    const loadExpenses = () => {
        try {
            const savedExpenses = localStorage.getItem('camperExpenses');
            if (savedExpenses) {
                expenses = JSON.parse(savedExpenses);
            }
        } catch (e) {
            console.error("Fehler beim Laden der Ausgaben aus dem localStorage:", e);
            expenses = [];
        }
    };

    const saveExpenses = () => {
        try {
            localStorage.setItem('camperExpenses', JSON.stringify(expenses));
        } catch(e) {
            console.error("Fehler beim Speichern der Ausgaben im localStorage:", e);
        }
    };

    // --- UI Rendering ---

    const formatCurrency = (amount: number): string => {
        return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(amount);
    };

    const updateUI = () => {
        updateSummary();
        updateCategorySummary();
        updateTransactionList();
    };

    const updateSummary = () => {
        const total = expenses.reduce((sum, expense) => sum + (expense.amount || 0), 0);
        totalExpensesEl.textContent = formatCurrency(total);
    };

    const updateCategorySummary = () => {
        categorySummaryEl.innerHTML = '';
        const categoryTotals = expenses.reduce((acc, expense) => {
            if (!acc[expense.category]) {
                acc[expense.category] = 0;
            }
            acc[expense.category] += expense.amount;
            return acc;
        }, {} as Record<string, number>);

        Object.keys(CATEGORIES).forEach(category => {
            const total = categoryTotals[category] || 0;
            const emoji = CATEGORIES[category];
            const categoryItem = document.createElement('div');
            categoryItem.className = 'category-item';
            categoryItem.innerHTML = `
                <div class="name">${emoji} ${category}</div>
                <div class="amount">${formatCurrency(total)}</div>
            `;
            categorySummaryEl.appendChild(categoryItem);
        });
    };

    const escapeHTML = (str: string): string => {
        if (!str) return '';
        const p = document.createElement('p');
        p.textContent = str;
        return p.innerHTML;
    };

    const updateTransactionList = () => {
        transactionListEl.innerHTML = '';
        if (expenses.length === 0) {
            transactionListEl.innerHTML = `<li class="no-transactions">Noch keine Ausgaben erfasst.</li>`;
            return;
        }

        const recentExpenses = [...expenses].sort((a, b) => b.id - a.id);

        recentExpenses.forEach(expense => {
            const li = document.createElement('li');
            const transactionDate = new Date(expense.date || expense.id).toLocaleDateString('de-DE');
            const noteHTML = expense.note ? `<span class="transaction-note">${escapeHTML(expense.note)}</span>` : '';
            li.innerHTML = `
                <div class="transaction-info">
                    <div class="transaction-details">
                        <span class="transaction-category">${CATEGORIES[expense.category]} ${escapeHTML(expense.category)}</span>
                        ${noteHTML}
                    </div>
                    <div class="transaction-meta">
                        <span class="transaction-amount">${formatCurrency(expense.amount)}</span>
                        <span class="transaction-date">${transactionDate}</span>
                    </div>
                </div>
                <div class="transaction-actions">
                    <button class="btn-edit" data-id="${expense.id}" aria-label="Ausgabe bearbeiten">✏️</button>
                    <button class="btn-delete" data-id="${expense.id}" aria-label="Ausgabe löschen">🗑️</button>
                </div>
            `;
            transactionListEl.appendChild(li);
        });
    };
    
    // --- Modal Control ---
    
    const showModal = () => {
        modal.hidden = false;
        const firstInput = modal.querySelector('input[type="number"]') as HTMLInputElement | null;
        if (firstInput) {
            firstInput.focus();
        }
    };
    
    const hideModal = () => {
        modal.hidden = true;
        expenseForm.reset();
        editingExpenseId = null;
        modalTitle.textContent = 'Neue Ausgabe';
    };

    const hideConfirmModal = () => {
        confirmModal.hidden = true;
        expenseIdToDelete = null;
    };

    // --- Edit and Delete Logic ---

    const handleEdit = (id: number) => {
        const expenseToEdit = expenses.find(e => e.id === id);
        if (!expenseToEdit) return;

        editingExpenseId = id;

        (expenseForm.elements.namedItem('amount') as HTMLInputElement).value = expenseToEdit.amount.toString();
        (expenseForm.elements.namedItem('note') as HTMLInputElement).value = expenseToEdit.note;
        const categoryRadio = expenseForm.querySelector(`input[name="category"][value="${expenseToEdit.category}"]`) as HTMLInputElement | null;
        if (categoryRadio) {
            categoryRadio.checked = true;
        }
        
        modalTitle.textContent = 'Ausgabe bearbeiten';
        showModal();
    };

    const handleDelete = (id: number) => {
        const expenseToDelete = expenses.find(e => e.id === id);
        if (!expenseToDelete) return;

        expenseIdToDelete = id;
        confirmTextEl.textContent = `${expenseToDelete.category} (${formatCurrency(expenseToDelete.amount)}) wirklich löschen?`;
        confirmModal.hidden = false;
    };

    const exportToCSV = () => {
        if (expenses.length === 0) {
            alert('Keine Ausgaben zum Exportieren vorhanden.');
            return;
        }

        const headers = ['Datum', 'Kategorie', 'Betrag', 'Notiz'];
        const separator = ';'; 

        const csvRows = expenses.map(e => {
            const date = new Date(e.date || e.id).toISOString().slice(0, 10);
            const category = e.category;
            const amount = e.amount.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
            let note = e.note || '';
            if (note.includes(separator) || note.includes('"')) {
                note = `"${note.replace(/"/g, '""')}"`;
            }
            return [date, category, amount, note].join(separator);
        });

        const csvContent = [headers.join(separator), ...csvRows].join('\n');
        const blob = new Blob(['\uFEFF' + csvContent], { type: 'text/csv;charset=utf-8;' });
        
        const link = document.createElement('a');
        const url = URL.createObjectURL(blob);
        link.setAttribute('href', url);
        const filename = `camper_ausgaben_${new Date().toISOString().slice(0, 10)}.csv`;
        link.setAttribute('download', filename);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    };
    
    // --- Event Handlers ---

    const handleFormSubmit = (event: Event) => {
        event.preventDefault();
        
        const formData = new FormData(expenseForm);
        const amountStr = String(formData.get('amount') || '0').replace(',', '.');
        const amount = parseFloat(amountStr);
        const category = String(formData.get('category') || '');
        const note = String(formData.get('note') || '').trim();

        if (isNaN(amount) || amount <= 0 || !category) {
            alert('Bitte gib einen gültigen Betrag und eine Kategorie an.');
            return;
        }

        if (editingExpenseId !== null) {
            const expenseIndex = expenses.findIndex(e => e.id === editingExpenseId);
            if (expenseIndex > -1) {
                expenses[expenseIndex] = { ...expenses[expenseIndex], amount, category, note };
            }
        } else {
            const newExpense: Expense = { id: Date.now(), date: new Date().toISOString(), amount, category, note };
            expenses.push(newExpense);
        }

        saveExpenses();
        updateUI();
        hideModal();
    };

    // --- App Initialization ---
    
    const init = () => {
        addExpenseBtn.addEventListener('click', showModal);
        cancelBtn.addEventListener('click', hideModal);
        exportCsvBtn.addEventListener('click', exportToCSV);
        
        modal.addEventListener('click', (e) => { if (e.target === modal) hideModal(); });
        document.addEventListener('keydown', (e) => { 
            if (e.key === 'Escape') {
                if (!modal.hidden) hideModal();
                if (!confirmModal.hidden) hideConfirmModal();
            }
        });
        
        expenseForm.addEventListener('submit', handleFormSubmit);

        transactionListEl.addEventListener('click', (e: MouseEvent) => {
            const button = (e.target as HTMLElement).closest('button');
        
            if (!button || !button.dataset.id) return;
        
            const id = parseInt(button.dataset.id, 10);
            if (isNaN(id)) return;
        
            if (button.classList.contains('btn-edit')) {
                handleEdit(id);
            } else if (button.classList.contains('btn-delete')) {
                handleDelete(id);
            }
        });

        // --- Confirmation Modal Handlers ---
        confirmCancelBtn.addEventListener('click', hideConfirmModal);
        confirmModal.addEventListener('click', (e) => { if (e.target === confirmModal) hideConfirmModal(); });

        confirmDeleteBtn.addEventListener('click', () => {
            if (expenseIdToDelete === null) return;
            
            const expenseIndex = expenses.findIndex(e => e.id === expenseIdToDelete);
            if (expenseIndex > -1) {
                expenses.splice(expenseIndex, 1);
                saveExpenses();
                updateUI();
            }
            hideConfirmModal();
        });

        loadExpenses();
        updateUI();
    };
    
    init();
});