#!/usr/bin/env python3
"""
Nebenkostenabrechnung - PySide6 GUI-Anwendung
"""

import sys
import os
import json
from pathlib import Path
from datetime import datetime
from io import BytesIO

from PySide6.QtWidgets import (
    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
    QFormLayout, QGridLayout, QStackedWidget, QListWidget, QListWidgetItem,
    QLineEdit, QDoubleSpinBox, QSpinBox, QPushButton, QLabel, QGroupBox,
    QTableWidget, QTableWidgetItem, QHeaderView, QMessageBox, QFileDialog,
    QComboBox, QFrame, QSplitter, QScrollArea, QSizePolicy
)
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QFont, QIcon, QColor

from reportlab.lib.pagesizes import A4
from reportlab.lib.units import cm
from reportlab.pdfgen import canvas
from reportlab.lib import colors

try:
    from PyPDF2 import PdfReader, PdfWriter
    PYPDF2_AVAILABLE = True
except ImportError:
    PYPDF2_AVAILABLE = False


class DatenManager:
    """Verwaltet Stammdaten und Historie"""

    # Konfigurations-Datei im Home-Verzeichnis
    CONFIG_DATEI = Path.home() / ".config" / "nebenkostenabrechnung" / "config.json"

    def __init__(self):
        # Arbeitsverzeichnis setzen
        self.basis_pfad = Path(__file__).parent
        os.chdir(self.basis_pfad)

        # Standard-Pfade
        self.daten_ordner = str(self.basis_pfad / "daten")
        self.dokumente_ordner = str(self.basis_pfad / "dokumente")
        self.vorlagen_ordner = str(self.basis_pfad / "vorlagen")

        # Konfig laden (überschreibt Standard-Pfade)
        self.lade_config()

        # Ordner erstellen
        Path(self.daten_ordner).mkdir(parents=True, exist_ok=True)
        Path(self.dokumente_ordner).mkdir(parents=True, exist_ok=True)
        Path(self.vorlagen_ordner).mkdir(parents=True, exist_ok=True)

        # Dynamische Pfade
        self.stammdaten_datei = Path(self.daten_ordner) / "stammdaten.json"
        self.historie_datei = Path(self.daten_ordner) / "historie.json"
        self.vorlage_datei = Path(self.vorlagen_ordner) / "vorlage.pdf"

        # Standard-Daten
        self.vermieter = {
            "name": "", "adresse": "", "iban": "", "bic": "", "bank": ""
        }
        self.mieter = {
            "name": "", "adresse": "", "iban": "", "bic": "", "bank": "", "email": ""
        }
        self.objekt_adresse = ""
        self.vorauszahlung_monat = 50.0
        self.kostenarten = ["Wasser/Abwasser", "Müllabfuhr", "Schornsteinfeger"]
        self.briefkopf_hoehe = 4.5
        self.historie = {}

        self.lade_stammdaten()
        self.lade_historie()

    def lade_config(self):
        """Lädt Pfad-Konfiguration"""
        if self.CONFIG_DATEI.exists():
            try:
                with open(self.CONFIG_DATEI, "r", encoding="utf-8") as f:
                    config = json.load(f)
                    self.daten_ordner = config.get("daten_ordner", self.daten_ordner)
                    self.dokumente_ordner = config.get("dokumente_ordner", self.dokumente_ordner)
                    self.vorlagen_ordner = config.get("vorlagen_ordner", self.vorlagen_ordner)
            except:
                pass

    def speichere_config(self):
        """Speichert Pfad-Konfiguration"""
        self.CONFIG_DATEI.parent.mkdir(parents=True, exist_ok=True)
        config = {
            "daten_ordner": self.daten_ordner,
            "dokumente_ordner": self.dokumente_ordner,
            "vorlagen_ordner": self.vorlagen_ordner,
        }
        with open(self.CONFIG_DATEI, "w", encoding="utf-8") as f:
            json.dump(config, f, ensure_ascii=False, indent=2)

    def aktualisiere_pfade(self):
        """Aktualisiert die Dateipfade nach Änderung der Ordner"""
        Path(self.daten_ordner).mkdir(parents=True, exist_ok=True)
        Path(self.dokumente_ordner).mkdir(parents=True, exist_ok=True)
        Path(self.vorlagen_ordner).mkdir(parents=True, exist_ok=True)
        self.stammdaten_datei = Path(self.daten_ordner) / "stammdaten.json"
        self.historie_datei = Path(self.daten_ordner) / "historie.json"
        self.vorlage_datei = Path(self.vorlagen_ordner) / "vorlage.pdf"

    def lade_stammdaten(self):
        if self.stammdaten_datei.exists():
            try:
                with open(self.stammdaten_datei, "r", encoding="utf-8") as f:
                    daten = json.load(f)
                    self.vermieter = daten.get("vermieter", self.vermieter)
                    self.mieter = daten.get("mieter", self.mieter)
                    self.objekt_adresse = daten.get("objekt_adresse", "")
                    self.vorauszahlung_monat = daten.get("vorauszahlung_monat", 50.0)
                    self.kostenarten = daten.get("kostenarten", self.kostenarten)
                    self.briefkopf_hoehe = daten.get("briefkopf_hoehe", 4.5)
            except Exception as e:
                print(f"Fehler beim Laden: {e}")

    def speichere_stammdaten(self):
        daten = {
            "vermieter": self.vermieter,
            "mieter": self.mieter,
            "objekt_adresse": self.objekt_adresse,
            "vorauszahlung_monat": self.vorauszahlung_monat,
            "kostenarten": self.kostenarten,
            "briefkopf_hoehe": self.briefkopf_hoehe,
        }
        with open(self.stammdaten_datei, "w", encoding="utf-8") as f:
            json.dump(daten, f, ensure_ascii=False, indent=2)

    def lade_historie(self):
        if self.historie_datei.exists():
            try:
                with open(self.historie_datei, "r", encoding="utf-8") as f:
                    self.historie = json.load(f)
            except:
                pass

    def get_abrechnung_ordner(self, jahr):
        """Gibt den Ordner für eine Abrechnung zurück"""
        ordner = Path(self.dokumente_ordner) / str(jahr)
        ordner.mkdir(parents=True, exist_ok=True)
        return ordner

    def get_belege_ordner(self, jahr):
        """Gibt den Belege-Ordner für eine Abrechnung zurück"""
        ordner = self.get_abrechnung_ordner(jahr) / "belege"
        ordner.mkdir(parents=True, exist_ok=True)
        return ordner

    def speichere_entwurf(self, jahr, kosten, belege, anzahl_monate, bemerkungen=""):
        """Speichert einen Entwurf (ohne PDF zu erstellen)"""
        import shutil

        belege_ordner = self.get_belege_ordner(jahr)
        gespeicherte_belege = {}

        # Belege kopieren
        for kostenart, dateien in belege.items():
            gespeicherte_belege[kostenart] = []
            for i, datei in enumerate(dateien):
                if datei and Path(datei).exists():
                    # Dateiname: Kostenart_Nr.pdf
                    ext = Path(datei).suffix
                    ziel_name = f"{kostenart.replace('/', '_')}_{i+1}{ext}"
                    ziel = belege_ordner / ziel_name
                    if str(datei) != str(ziel):  # Nur kopieren wenn nicht gleich
                        shutil.copy2(datei, ziel)
                    gespeicherte_belege[kostenart].append(str(ziel))

        summe_kosten = sum(kosten.values())
        summe_vz = self.vorauszahlung_monat * anzahl_monate

        self.historie[str(jahr)] = {
            "jahr": jahr,
            "mieter": self.mieter["name"],
            "kosten": kosten,
            "belege": gespeicherte_belege,
            "bemerkungen": bemerkungen,
            "summe_kosten": summe_kosten,
            "vorauszahlung_monat": self.vorauszahlung_monat,
            "anzahl_monate": anzahl_monate,
            "summe_vorauszahlung": summe_vz,
            "differenz": summe_kosten - summe_vz,
            "status": "entwurf",
            "datum": datetime.now().strftime("%Y-%m-%d %H:%M"),
        }

        with open(self.historie_datei, "w", encoding="utf-8") as f:
            json.dump(self.historie, f, ensure_ascii=False, indent=2)

        return gespeicherte_belege

    def lade_entwurf(self, jahr):
        """Lädt einen gespeicherten Entwurf"""
        if str(jahr) in self.historie:
            return self.historie[str(jahr)]
        return None

    def speichere_abrechnung(self, jahr, kosten, belege, anzahl_monate, bemerkungen=""):
        """Speichert eine fertige Abrechnung"""
        # Erst als Entwurf speichern (kopiert Belege)
        gespeicherte_belege = self.speichere_entwurf(jahr, kosten, belege, anzahl_monate, bemerkungen)

        summe_kosten = sum(kosten.values())
        summe_vz = self.vorauszahlung_monat * anzahl_monate

        self.historie[str(jahr)] = {
            "jahr": jahr,
            "mieter": self.mieter["name"],
            "kosten": kosten,
            "belege": gespeicherte_belege,
            "summe_kosten": summe_kosten,
            "vorauszahlung_monat": self.vorauszahlung_monat,
            "anzahl_monate": anzahl_monate,
            "summe_vorauszahlung": summe_vz,
            "differenz": summe_kosten - summe_vz,
            "status": "fertig",
            "datum": datetime.now().strftime("%Y-%m-%d %H:%M"),
        }

        with open(self.historie_datei, "w", encoding="utf-8") as f:
            json.dump(self.historie, f, ensure_ascii=False, indent=2)

        return gespeicherte_belege

    def get_vorjahr_kosten(self, jahr):
        vorjahr = str(jahr - 1)
        if vorjahr in self.historie:
            return self.historie[vorjahr].get("kosten", {})
        return {}


class StammdatenSeite(QWidget):
    """Seite für Stammdaten-Eingabe"""

    def __init__(self, daten: DatenManager):
        super().__init__()
        self.daten = daten
        self.setup_ui()
        self.lade_daten()

    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setSpacing(20)

        # Titel
        titel = QLabel("Stammdaten")
        titel.setFont(QFont("", 18, QFont.Bold))
        layout.addWidget(titel)

        # Scroll-Bereich
        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setFrameShape(QFrame.NoFrame)

        content = QWidget()
        content_layout = QVBoxLayout(content)
        content_layout.setSpacing(15)

        # Vermieter
        self.vermieter_group = QGroupBox("Vermieter")
        vl = QFormLayout(self.vermieter_group)
        self.v_name = QLineEdit()
        self.v_adresse = QLineEdit()
        self.v_iban = QLineEdit()
        self.v_bic = QLineEdit()
        self.v_bank = QLineEdit()
        vl.addRow("Name:", self.v_name)
        vl.addRow("Adresse:", self.v_adresse)
        vl.addRow("IBAN:", self.v_iban)
        vl.addRow("BIC:", self.v_bic)
        vl.addRow("Bank:", self.v_bank)
        content_layout.addWidget(self.vermieter_group)

        # Mieter
        self.mieter_group = QGroupBox("Mieter")
        ml = QFormLayout(self.mieter_group)
        self.m_name = QLineEdit()
        self.m_adresse = QLineEdit()
        self.m_email = QLineEdit()
        self.m_email.setPlaceholderText("Nur intern - nicht im PDF")
        self.m_iban = QLineEdit()
        self.m_iban.setPlaceholderText("Für Rückzahlung bei Guthaben")
        self.m_bic = QLineEdit()
        self.m_bank = QLineEdit()
        ml.addRow("Name:", self.m_name)
        ml.addRow("Adresse:", self.m_adresse)
        ml.addRow("E-Mail:", self.m_email)
        ml.addRow("IBAN:", self.m_iban)
        ml.addRow("BIC:", self.m_bic)
        ml.addRow("Bank:", self.m_bank)
        content_layout.addWidget(self.mieter_group)

        # Objekt
        self.objekt_group = QGroupBox("Mietobjekt")
        ol = QFormLayout(self.objekt_group)
        self.objekt_adresse = QLineEdit()
        self.vorauszahlung = QDoubleSpinBox()
        self.vorauszahlung.setRange(0, 10000)
        self.vorauszahlung.setSuffix(" €/Monat")
        self.vorauszahlung.setDecimals(2)
        ol.addRow("Adresse:", self.objekt_adresse)
        ol.addRow("Vorauszahlung:", self.vorauszahlung)
        content_layout.addWidget(self.objekt_group)

        content_layout.addStretch()
        scroll.setWidget(content)
        layout.addWidget(scroll)

        # Speichern-Button
        btn_layout = QHBoxLayout()
        btn_layout.addStretch()
        self.btn_speichern = QPushButton("Speichern")
        self.btn_speichern.setMinimumWidth(150)
        self.btn_speichern.clicked.connect(self.speichern)
        btn_layout.addWidget(self.btn_speichern)
        layout.addLayout(btn_layout)

    def lade_daten(self):
        v = self.daten.vermieter
        self.v_name.setText(v.get("name", ""))
        self.v_adresse.setText(v.get("adresse", ""))
        self.v_iban.setText(v.get("iban", ""))
        self.v_bic.setText(v.get("bic", ""))
        self.v_bank.setText(v.get("bank", ""))

        m = self.daten.mieter
        self.m_name.setText(m.get("name", ""))
        self.m_adresse.setText(m.get("adresse", ""))
        self.m_email.setText(m.get("email", ""))
        self.m_iban.setText(m.get("iban", ""))
        self.m_bic.setText(m.get("bic", ""))
        self.m_bank.setText(m.get("bank", ""))

        self.objekt_adresse.setText(self.daten.objekt_adresse)
        self.vorauszahlung.setValue(self.daten.vorauszahlung_monat)

    def speichern(self):
        self.daten.vermieter = {
            "name": self.v_name.text(),
            "adresse": self.v_adresse.text(),
            "iban": self.v_iban.text(),
            "bic": self.v_bic.text(),
            "bank": self.v_bank.text(),
        }
        self.daten.mieter = {
            "name": self.m_name.text(),
            "adresse": self.m_adresse.text(),
            "email": self.m_email.text(),
            "iban": self.m_iban.text(),
            "bic": self.m_bic.text(),
            "bank": self.m_bank.text(),
        }
        self.daten.objekt_adresse = self.objekt_adresse.text()
        self.daten.vorauszahlung_monat = self.vorauszahlung.value()
        self.daten.speichere_stammdaten()

        QMessageBox.information(self, "Gespeichert", "Stammdaten wurden gespeichert.")


class KostenartenSeite(QWidget):
    """Seite für Kostenarten-Verwaltung"""

    def __init__(self, daten: DatenManager):
        super().__init__()
        self.daten = daten
        self.setup_ui()
        self.lade_daten()

    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setSpacing(20)

        titel = QLabel("Kostenarten verwalten")
        titel.setFont(QFont("", 18, QFont.Bold))
        layout.addWidget(titel)

        info = QLabel("Diese Kostenarten werden bei jeder Abrechnung abgefragt.")
        info.setStyleSheet("color: gray;")
        layout.addWidget(info)

        # Tabelle
        self.tabelle = QTableWidget()
        self.tabelle.setColumnCount(1)
        self.tabelle.setHorizontalHeaderLabels(["Kostenart"])
        self.tabelle.horizontalHeader().setStretchLastSection(True)
        self.tabelle.setSelectionBehavior(QTableWidget.SelectRows)
        layout.addWidget(self.tabelle)

        # Buttons
        btn_layout = QHBoxLayout()

        self.input_neu = QLineEdit()
        self.input_neu.setPlaceholderText("Neue Kostenart eingeben...")
        self.input_neu.returnPressed.connect(self.hinzufuegen)
        btn_layout.addWidget(self.input_neu)

        self.btn_add = QPushButton("Hinzufügen")
        self.btn_add.clicked.connect(self.hinzufuegen)
        btn_layout.addWidget(self.btn_add)

        self.btn_del = QPushButton("Löschen")
        self.btn_del.clicked.connect(self.loeschen)
        btn_layout.addWidget(self.btn_del)

        layout.addLayout(btn_layout)

    def lade_daten(self):
        self.tabelle.setRowCount(len(self.daten.kostenarten))
        for i, art in enumerate(self.daten.kostenarten):
            self.tabelle.setItem(i, 0, QTableWidgetItem(art))

    def hinzufuegen(self):
        text = self.input_neu.text().strip()
        if text and text not in self.daten.kostenarten:
            self.daten.kostenarten.append(text)
            self.daten.speichere_stammdaten()
            self.lade_daten()
            self.input_neu.clear()

    def loeschen(self):
        row = self.tabelle.currentRow()
        if row >= 0:
            art = self.daten.kostenarten[row]
            self.daten.kostenarten.remove(art)
            self.daten.speichere_stammdaten()
            self.lade_daten()


class KostenZeile(QWidget):
    """Widget für eine Kostenart mit Betrag und Belegen"""

    def __init__(self, kostenart, vorjahr_wert=0, parent=None):
        super().__init__(parent)
        self.kostenart = kostenart
        self.belege = []  # Liste der Beleg-Pfade

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 2, 0, 2)

        # Label
        label = kostenart
        if vorjahr_wert > 0:
            label = f"{kostenart} (VJ: {vorjahr_wert:.2f} €)"
        self.lbl = QLabel(label)
        self.lbl.setMinimumWidth(200)
        layout.addWidget(self.lbl)

        # Betrag
        self.betrag = QDoubleSpinBox()
        self.betrag.setRange(0, 100000)
        self.betrag.setDecimals(2)
        self.betrag.setSuffix(" €")
        self.betrag.setMinimumWidth(120)
        layout.addWidget(self.betrag)

        # Beleg-Button
        self.btn_beleg = QPushButton("📎 Beleg...")
        self.btn_beleg.setMinimumWidth(100)
        self.btn_beleg.clicked.connect(self.waehle_beleg)
        layout.addWidget(self.btn_beleg)

        # Beleg-Anzeige
        self.lbl_beleg = QLabel("")
        self.lbl_beleg.setStyleSheet("color: gray; font-size: 9px;")
        layout.addWidget(self.lbl_beleg, 1)

    def waehle_beleg(self):
        dateien, _ = QFileDialog.getOpenFileNames(
            self, f"Belege für {self.kostenart}",
            "", "PDF/Bilder (*.pdf *.jpg *.jpeg *.png);;Alle (*.*)"
        )
        if dateien:
            self.belege = dateien
            self.aktualisiere_beleg_anzeige()

    def aktualisiere_beleg_anzeige(self):
        if self.belege:
            namen = [Path(b).name for b in self.belege]
            text = ", ".join(namen)
            if len(text) > 40:
                text = f"{len(self.belege)} Belege"
            self.lbl_beleg.setText(f"✓ {text}")
            self.lbl_beleg.setStyleSheet("color: green; font-size: 9px;")
        else:
            self.lbl_beleg.setText("")

    def setze_belege(self, belege_liste):
        """Setzt Belege aus gespeichertem Entwurf"""
        self.belege = [b for b in belege_liste if Path(b).exists()]
        self.aktualisiere_beleg_anzeige()


class AbrechnungSeite(QWidget):
    """Seite für neue Abrechnung mit Beleg-Upload"""

    def __init__(self, daten: DatenManager):
        super().__init__()
        self.daten = daten
        self.kosten_zeilen = {}  # kostenart -> KostenZeile
        self.setup_ui()

    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setSpacing(15)

        # Titel und Status
        titel_layout = QHBoxLayout()
        titel = QLabel("Abrechnung")
        titel.setFont(QFont("", 18, QFont.Bold))
        titel_layout.addWidget(titel)

        self.lbl_status = QLabel("")
        self.lbl_status.setStyleSheet("color: gray;")
        titel_layout.addWidget(self.lbl_status)
        titel_layout.addStretch()
        layout.addLayout(titel_layout)

        # Jahr, Monate und Laden
        periode_layout = QHBoxLayout()

        periode_layout.addWidget(QLabel("Jahr:"))
        self.jahr = QSpinBox()
        self.jahr.setRange(2000, 2100)
        self.jahr.setValue(datetime.now().year - 1)
        self.jahr.valueChanged.connect(self.jahr_geaendert)
        periode_layout.addWidget(self.jahr)

        periode_layout.addWidget(QLabel("Monate:"))
        self.monate = QSpinBox()
        self.monate.setRange(1, 12)
        self.monate.setValue(12)
        self.monate.valueChanged.connect(self.berechne)
        periode_layout.addWidget(self.monate)

        self.btn_laden = QPushButton("Entwurf laden")
        self.btn_laden.clicked.connect(self.lade_entwurf)
        periode_layout.addWidget(self.btn_laden)

        periode_layout.addStretch()
        layout.addLayout(periode_layout)

        # Scroll-Bereich für Kosten
        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setFrameShape(QFrame.NoFrame)
        scroll.setMaximumHeight(300)

        self.kosten_widget = QWidget()
        self.kosten_layout = QVBoxLayout(self.kosten_widget)
        self.kosten_layout.setSpacing(5)
        scroll.setWidget(self.kosten_widget)

        kosten_group = QGroupBox("Nebenkosten (Jahressummen) - mit Belegen")
        kosten_group_layout = QVBoxLayout(kosten_group)
        kosten_group_layout.addWidget(scroll)
        layout.addWidget(kosten_group)

        # Zusammenfassung
        summen_group = QGroupBox("Zusammenfassung")
        sl = QFormLayout(summen_group)

        self.lbl_summe_kosten = QLabel("0,00 €")
        self.lbl_summe_kosten.setFont(QFont("", 11))
        sl.addRow("Summe Nebenkosten:", self.lbl_summe_kosten)

        self.lbl_vorauszahlung = QLabel("0,00 €")
        self.lbl_vorauszahlung.setFont(QFont("", 11))
        sl.addRow("Vorauszahlungen:", self.lbl_vorauszahlung)

        self.lbl_differenz = QLabel("0,00 €")
        self.lbl_differenz.setFont(QFont("", 14, QFont.Bold))
        sl.addRow("Ergebnis:", self.lbl_differenz)

        layout.addWidget(summen_group)

        # Bemerkungen
        from PySide6.QtWidgets import QTextEdit
        bemerk_group = QGroupBox("Bemerkungen (erscheint im PDF)")
        bemerk_layout = QVBoxLayout(bemerk_group)
        self.bemerkungen = QTextEdit()
        self.bemerkungen.setMaximumHeight(80)
        self.bemerkungen.setPlaceholderText("Optionale Anmerkungen zur Abrechnung...")
        bemerk_layout.addWidget(self.bemerkungen)
        layout.addWidget(bemerk_group)

        # Buttons
        btn_layout = QHBoxLayout()

        self.btn_entwurf = QPushButton("💾 Entwurf speichern")
        self.btn_entwurf.clicked.connect(self.speichere_entwurf)
        btn_layout.addWidget(self.btn_entwurf)

        btn_layout.addStretch()

        self.btn_pdf = QPushButton("📄 PDF erstellen")
        self.btn_pdf.setMinimumWidth(150)
        self.btn_pdf.clicked.connect(self.erstelle_pdf)
        btn_layout.addWidget(self.btn_pdf)

        layout.addLayout(btn_layout)
        layout.addStretch()

        # Initial laden (inkl. vorhandener Daten)
        self.jahr_geaendert()

    def jahr_geaendert(self):
        """Wird aufgerufen wenn das Jahr geändert wird - lädt automatisch vorhandene Daten"""
        self.aktualisiere_kosten()

        # Prüfen ob Daten existieren und automatisch laden
        entwurf = self.daten.lade_entwurf(self.jahr.value())
        if entwurf:
            # Automatisch laden
            self.monate.setValue(entwurf.get("anzahl_monate", 12))

            kosten = entwurf.get("kosten", {})
            belege = entwurf.get("belege", {})

            for art, zeile in self.kosten_zeilen.items():
                if art in kosten:
                    zeile.betrag.setValue(kosten[art])
                if art in belege:
                    zeile.setze_belege(belege[art])

            # Bemerkungen laden
            self.bemerkungen.setPlainText(entwurf.get("bemerkungen", ""))

            status = entwurf.get("status", "entwurf")
            status_text = "Abrechnung" if status == "fertig" else "Entwurf"
            self.lbl_status.setText(f"[{status_text} vom {entwurf.get('datum', '?')}]")
            self.btn_laden.setEnabled(True)
            self.berechne()
        else:
            self.lbl_status.setText("")
            self.btn_laden.setEnabled(False)

    def aktualisiere_kosten(self):
        """Erstellt die Kosten-Zeilen neu"""
        # Alte Widgets entfernen
        while self.kosten_layout.count():
            item = self.kosten_layout.takeAt(0)
            if item.widget():
                item.widget().deleteLater()

        self.kosten_zeilen = {}
        vorjahr = self.daten.get_vorjahr_kosten(self.jahr.value())

        for art in self.daten.kostenarten:
            vj_wert = vorjahr.get(art, 0)
            zeile = KostenZeile(art, vj_wert)
            zeile.betrag.valueChanged.connect(self.berechne)
            self.kosten_layout.addWidget(zeile)
            self.kosten_zeilen[art] = zeile

        self.kosten_layout.addStretch()
        self.berechne()

    def lade_entwurf(self):
        """Lädt einen gespeicherten Entwurf"""
        entwurf = self.daten.lade_entwurf(self.jahr.value())
        if not entwurf:
            QMessageBox.information(self, "Kein Entwurf", "Kein Entwurf für dieses Jahr gefunden.")
            return

        # Monate setzen
        self.monate.setValue(entwurf.get("anzahl_monate", 12))

        # Kosten und Belege setzen
        kosten = entwurf.get("kosten", {})
        belege = entwurf.get("belege", {})

        for art, zeile in self.kosten_zeilen.items():
            if art in kosten:
                zeile.betrag.setValue(kosten[art])
            if art in belege:
                zeile.setze_belege(belege[art])

        self.lbl_status.setText(f"[Geladen: {entwurf.get('datum', '?')}]")
        self.berechne()

    def speichere_entwurf(self):
        """Speichert den aktuellen Stand als Entwurf"""
        kosten = {art: zeile.betrag.value() for art, zeile in self.kosten_zeilen.items()}
        belege = {art: zeile.belege for art, zeile in self.kosten_zeilen.items()}
        bemerkungen = self.bemerkungen.toPlainText()

        self.daten.speichere_entwurf(
            self.jahr.value(), kosten, belege, self.monate.value(), bemerkungen
        )

        self.lbl_status.setText(f"[Entwurf gespeichert: {datetime.now().strftime('%H:%M')}]")
        QMessageBox.information(self, "Gespeichert", "Entwurf wurde gespeichert.\nBelege wurden kopiert.")

    def berechne(self):
        summe = sum(zeile.betrag.value() for zeile in self.kosten_zeilen.values())
        vz = self.daten.vorauszahlung_monat * self.monate.value()
        diff = summe - vz

        self.lbl_summe_kosten.setText(f"{summe:,.2f} €".replace(",", "X").replace(".", ",").replace("X", "."))
        self.lbl_vorauszahlung.setText(f"{vz:,.2f} €".replace(",", "X").replace(".", ",").replace("X", "."))

        if diff > 0:
            self.lbl_differenz.setText(f"Nachzahlung: {diff:,.2f} €".replace(",", "X").replace(".", ",").replace("X", "."))
            self.lbl_differenz.setStyleSheet("color: #CC0000;")
        else:
            self.lbl_differenz.setText(f"Guthaben: {abs(diff):,.2f} €".replace(",", "X").replace(".", ",").replace("X", "."))
            self.lbl_differenz.setStyleSheet("color: #006600;")

    def erstelle_pdf(self):
        if not self.daten.vermieter.get("name"):
            QMessageBox.warning(self, "Fehler", "Bitte zuerst Stammdaten eingeben!")
            return

        # Kosten und Belege aus den Zeilen sammeln
        kosten = {art: zeile.betrag.value() for art, zeile in self.kosten_zeilen.items()}
        belege = {art: zeile.belege for art, zeile in self.kosten_zeilen.items()}
        jahr = self.jahr.value()
        anzahl_monate = self.monate.value()

        bemerkungen = self.bemerkungen.toPlainText()

        # Busy-Cursor anzeigen während PDF erstellt wird
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.lbl_status.setText("PDF wird erstellt...")
        QApplication.processEvents()

        try:
            # Speichern (kopiert auch Belege)
            gespeicherte_belege = self.daten.speichere_abrechnung(jahr, kosten, belege, anzahl_monate, bemerkungen)

            # PDF erstellen (mit angehängten Belegen)
            pdf_pfad = self._erstelle_pdf(jahr, kosten, anzahl_monate, gespeicherte_belege, bemerkungen)
        finally:
            QApplication.restoreOverrideCursor()

        QMessageBox.information(self, "PDF erstellt", f"PDF gespeichert:\n{pdf_pfad}")

        self.lbl_status.setText(f"[PDF erstellt: {datetime.now().strftime('%H:%M')}]")

        # PDF öffnen
        import subprocess
        subprocess.run(["xdg-open", pdf_pfad])

    def _erstelle_pdf(self, jahr, kosten, anzahl_monate, belege=None, bemerkungen=""):
        # Absoluten Pfad sicherstellen
        dok_ordner = Path(self.daten.dokumente_ordner).resolve()
        jahr_ordner = dok_ordner / str(jahr)
        jahr_ordner.mkdir(parents=True, exist_ok=True)
        print(f"PDF-Ordner: {jahr_ordner}")

        # Dateiname: Datum - Nebenkostenabrechnung - Objekt.pdf
        datum_str = datetime.now().strftime("%Y-%m-%d")
        objekt_safe = self.daten.objekt_adresse.replace('/', '-').replace('\\', '-').replace(':', '-')
        dateiname = jahr_ordner / f"{datum_str} - Nebenkostenabrechnung - {objekt_safe}.pdf"

        summe_kosten = sum(kosten.values())
        summe_vz = self.daten.vorauszahlung_monat * anzahl_monate
        differenz = summe_kosten - summe_vz

        # Hack-Schrift für PDF registrieren
        from reportlab.pdfbase import pdfmetrics
        from reportlab.pdfbase.ttfonts import TTFont
        try:
            pdfmetrics.registerFont(TTFont('Hack', '/usr/share/fonts/TTF/Hack-Regular.ttf'))
            pdfmetrics.registerFont(TTFont('Hack-Bold', '/usr/share/fonts/TTF/Hack-Bold.ttf'))
            FONT = 'Hack'
            FONT_BOLD = 'Hack-Bold'
        except:
            FONT = 'Helvetica'
            FONT_BOLD = 'Helvetica-Bold'

        # PDF erstellen
        buffer = BytesIO()
        c = canvas.Canvas(buffer, pagesize=A4)
        breite, hoehe = A4

        def format_eur(betrag):
            return f"{betrag:,.2f} EUR".replace(",", "X").replace(".", ",").replace("X", ".")

        def format_iban(iban):
            iban = iban.replace(" ", "")
            return " ".join([iban[i:i+4] for i in range(0, len(iban), 4)])

        # ============ BRIEFKOPF ============
        # Absender kommt aus der Vorlage (Briefkopf)

        # Absenderzeile klein (direkt über Empfänger mit 1 Leerzeile)
        y = hoehe - 4.5*cm
        c.setFont(FONT, 7)
        absender_zeile = f"{self.daten.vermieter['name']} · {self.daten.vermieter['adresse']}"
        c.drawString(2*cm, y, absender_zeile)

        # Leerzeile
        y -= 0.4*cm

        # Empfänger (Mieter) - "An:"
        y -= 0.4*cm
        c.setFont(FONT_BOLD, 10)
        c.drawString(2*cm, y, "An:")
        y -= 0.5*cm
        c.setFont(FONT, 11)
        c.drawString(2*cm, y, self.daten.mieter["name"])
        y -= 0.45*cm
        # Adresse aufteilen falls mit Komma
        adresse_teile = self.daten.mieter["adresse"].split(",")
        for teil in adresse_teile:
            c.drawString(2*cm, y, teil.strip())
            y -= 0.45*cm

        # Datum rechts
        c.setFont(FONT, 10)
        c.drawRightString(breite - 2*cm, y + 0.9*cm, f"Datum: {datetime.now().strftime('%d.%m.%Y')}")

        # ============ BETREFF / TITEL ============
        # 6 Zeilen tiefer (ca. 2.5cm)
        y -= 3.3*cm
        c.setFont(FONT_BOLD, 12)
        c.drawString(2*cm, y, f"Nebenkostenabrechnung {jahr}")
        y -= 0.5*cm
        c.setFont(FONT, 10)
        c.drawString(2*cm, y, f"Abrechnungszeitraum: 01.01.{jahr} - 31.12.{jahr}")

        # Objekt und Umlageschlüssel
        y -= 0.6*cm
        c.setFont(FONT, 9)
        c.drawString(2*cm, y, f"Mietobjekt: {self.daten.objekt_adresse}")
        y -= 0.4*cm
        c.drawString(2*cm, y, "Umlageschlüssel: 100%")

        # Trennlinie
        y -= 0.5*cm
        c.line(2*cm, y, breite - 2*cm, y)

        # Kosten
        y -= 0.8*cm
        c.setFont(FONT_BOLD, 11)
        c.drawString(2*cm, y, "Kostenaufstellung")

        y -= 0.5*cm
        c.setFont(FONT_BOLD, 9)
        c.drawString(2*cm, y, "Kostenart")
        c.drawRightString(breite - 2*cm, y, "Betrag")
        y -= 0.15*cm
        c.line(2*cm, y, breite - 2*cm, y)

        c.setFont(FONT, 9)
        for art, betrag in kosten.items():
            if betrag > 0:
                y -= 0.45*cm
                c.drawString(2*cm, y, art)
                c.drawRightString(breite - 2*cm, y, format_eur(betrag))

        y -= 0.15*cm
        c.line(2*cm, y, breite - 2*cm, y)
        y -= 0.45*cm
        c.setFont(FONT_BOLD, 9)
        c.drawString(2*cm, y, "Summe Nebenkosten")
        c.drawRightString(breite - 2*cm, y, format_eur(summe_kosten))

        # Vorauszahlung
        y -= 0.8*cm
        c.setFont(FONT_BOLD, 11)
        c.drawString(2*cm, y, "Vorauszahlungen")
        y -= 0.5*cm
        c.setFont(FONT, 9)
        c.drawString(2*cm, y, f"{anzahl_monate} Monate x {format_eur(self.daten.vorauszahlung_monat)}")
        c.drawRightString(breite - 2*cm, y, format_eur(summe_vz))

        # Ergebnis
        y -= 0.7*cm
        c.setLineWidth(1.5)
        c.line(2*cm, y, breite - 2*cm, y)
        y -= 0.6*cm
        c.setFont(FONT_BOLD, 11)

        if differenz > 0:
            c.drawString(2*cm, y, "Nachzahlung durch Mieter")
            c.setFillColor(colors.HexColor("#CC0000"))
        else:
            c.drawString(2*cm, y, "Guthaben für Mieter")
            c.setFillColor(colors.HexColor("#006600"))

        c.drawRightString(breite - 2*cm, y, format_eur(abs(differenz)))
        c.setFillColor(colors.black)

        # Zahlungshinweis
        y -= 1*cm
        c.setFont(FONT_BOLD, 9)
        c.drawString(2*cm, y, "Zahlungshinweis:")
        y -= 0.4*cm
        c.setFont(FONT, 8)

        if differenz > 0:
            c.drawString(2*cm, y, f"Bitte überweisen Sie {format_eur(abs(differenz))} innerhalb von 30 Tagen an:")
            y -= 0.4*cm
            if self.daten.vermieter["iban"]:
                c.drawString(2*cm, y, f"IBAN: {format_iban(self.daten.vermieter['iban'])}")
                if self.daten.vermieter["bank"]:
                    c.drawString(10*cm, y, f"Bank: {self.daten.vermieter['bank']}")
                y -= 0.35*cm
            c.drawString(2*cm, y, f"Verwendungszweck: Nebenkostennachzahlung {jahr}")
        else:
            c.drawString(2*cm, y, f"Das Guthaben von {format_eur(abs(differenz))} wird überwiesen an:")
            y -= 0.4*cm
            c.drawString(2*cm, y, f"Empfänger: {self.daten.mieter['name']}")
            if self.daten.mieter["iban"]:
                y -= 0.35*cm
                c.drawString(2*cm, y, f"IBAN: {format_iban(self.daten.mieter['iban'])}")

        # Bemerkungen (falls vorhanden)
        if bemerkungen and bemerkungen.strip():
            y -= 0.8*cm
            c.setFont(FONT_BOLD, 9)
            c.drawString(2*cm, y, "Bemerkungen:")
            y -= 0.4*cm
            c.setFont(FONT, 8)
            for zeile in bemerkungen.strip().split('\n'):
                c.drawString(2*cm, y, zeile)
                y -= 0.3*cm

        # Anlagen-Verzeichnis (falls Belege vorhanden)
        anlagen_liste = []
        if belege:
            for kostenart, dateien in belege.items():
                for datei in dateien:
                    if datei and Path(datei).exists():
                        anlagen_liste.append((kostenart, Path(datei).name))

        if anlagen_liste:
            y -= 0.8*cm
            c.setFont(FONT_BOLD, 9)
            c.drawString(2*cm, y, f"Anlagen ({len(anlagen_liste)} Beleg{'e' if len(anlagen_liste) > 1 else ''}):")
            y -= 0.4*cm
            c.setFont(FONT, 8)
            for i, (kostenart, anlage_name) in enumerate(anlagen_liste, 1):
                c.drawString(2*cm, y, f"  {i}. {kostenart}: {anlage_name}")
                y -= 0.3*cm

        # Rechtliche Hinweise (Pflichtangaben gem. § 556 BGB)
        y -= 0.5*cm
        c.setFont(FONT_BOLD, 8)
        c.drawString(2*cm, y, "Rechtliche Hinweise:")
        y -= 0.35*cm
        c.setFont(FONT, 7)
        c.drawString(2*cm, y, "• Sie haben das Recht, die dieser Abrechnung zugrunde liegenden Belege einzusehen (§ 556 Abs. 4 BGB).")
        y -= 0.3*cm
        c.drawString(2*cm, y, "• Einwendungen gegen diese Abrechnung sind innerhalb von 12 Monaten nach Zugang schriftlich geltend zu machen (§ 556 Abs. 3 BGB).")
        y -= 0.3*cm
        c.drawString(2*cm, y, "• Nach Ablauf dieser Frist können Einwendungen nicht mehr geltend gemacht werden, es sei denn, der Mieter hat die")
        y -= 0.3*cm
        c.drawString(2*cm, y, "  verspätete Geltendmachung nicht zu vertreten.")

        # Unterschrift
        y -= 0.8*cm
        c.setLineWidth(0.5)
        c.line(2*cm, y, 6*cm, y)
        y -= 0.3*cm
        c.setFont(FONT, 8)
        c.drawString(2*cm, y, self.daten.vermieter["name"])

        c.save()
        buffer.seek(0)

        # PDF zusammenstellen
        writer = PdfWriter()

        # Mit Vorlage zusammenführen oder direkt verwenden
        vorlage_pfad = self.daten.vorlage_datei
        if vorlage_pfad.exists() and PYPDF2_AVAILABLE:
            try:
                vorlage = PdfReader(vorlage_pfad)
                vorlage_seite = vorlage.pages[0]
                inhalt = PdfReader(buffer)
                vorlage_seite.merge_page(inhalt.pages[0])
                writer.add_page(vorlage_seite)
            except:
                buffer.seek(0)
                inhalt = PdfReader(buffer)
                writer.add_page(inhalt.pages[0])
        elif PYPDF2_AVAILABLE:
            inhalt = PdfReader(buffer)
            writer.add_page(inhalt.pages[0])
        else:
            # Ohne PyPDF2 - nur Abrechnung, keine Belege
            with open(str(dateiname), "wb") as f:
                f.write(buffer.getvalue())
            return str(dateiname)

        # Hilfsfunktion: Prüft ob Seite leer ist (mit OCR)
        def ist_seite_leer(seite):
            """Prüft ob eine PDF-Seite leer/ohne sinnvollen Inhalt ist"""
            try:
                # Basis-Prüfungen
                if '/Contents' not in seite:
                    return True
                contents = seite['/Contents']
                if contents is None:
                    return True
                if '/MediaBox' in seite:
                    box = seite['/MediaBox']
                    if box[2] < 50 or box[3] < 50:
                        return True

                # OCR-Prüfung: Hat die Seite lesbaren Text?
                try:
                    import pytesseract
                    from pdf2image import convert_from_bytes
                    from PyPDF2 import PdfWriter as TempWriter

                    temp_writer = TempWriter()
                    temp_writer.add_page(seite)
                    temp_buffer = BytesIO()
                    temp_writer.write(temp_buffer)
                    temp_buffer.seek(0)

                    images = convert_from_bytes(temp_buffer.read(), dpi=100)
                    if not images:
                        return True

                    # Text extrahieren
                    text = pytesseract.image_to_string(images[0], lang='deu')
                    # Nur alphanumerische Zeichen zählen
                    alnum_chars = sum(1 for c in text if c.isalnum())

                    # Weniger als 50 Zeichen = wahrscheinlich leer
                    if alnum_chars < 50:
                        print(f"Seite gefiltert: nur {alnum_chars} Zeichen erkannt")
                        return True

                except Exception as e:
                    print(f"OCR-Prüfung fehlgeschlagen: {e}")

                return False
            except:
                return False

        # Orientierung erkennen und korrigieren
        def korrigiere_seite(seite):
            """Erkennt Textausrichtung mit OCR und dreht Seite falls nötig"""
            try:
                import pytesseract
                from pdf2image import convert_from_bytes
                from PyPDF2 import PdfWriter as TempWriter

                # Seite temporär als PDF speichern
                temp_writer = TempWriter()
                temp_writer.add_page(seite)
                temp_buffer = BytesIO()
                temp_writer.write(temp_buffer)
                temp_buffer.seek(0)

                # PDF in Bild konvertieren
                images = convert_from_bytes(temp_buffer.read(), dpi=150)
                if not images:
                    return seite

                # Orientierung mit Tesseract erkennen
                osd = pytesseract.image_to_osd(images[0], output_type=pytesseract.Output.DICT)
                rotation_needed = osd.get('rotate', 0)

                print(f"OCR erkannt: Rotation {rotation_needed}°")

                # Seite drehen falls nötig
                if rotation_needed != 0:
                    seite.rotate(rotation_needed)
                    seite.transfer_rotation_to_content()

                return seite
            except Exception as e:
                print(f"Orientierungserkennung fehlgeschlagen: {e}")
                return seite

        # Belege anhängen
        beleg_seiten = []  # Sammelt alle Beleg-Seiten
        if belege and PYPDF2_AVAILABLE:
            for kostenart, dateien in belege.items():
                for datei in dateien:
                    if datei and Path(datei).exists():
                        datei_pfad = Path(datei)

                        # Leere/sehr kleine Dateien überspringen
                        if datei_pfad.stat().st_size < 500:  # < 500 Bytes
                            print(f"Überspringe leere Datei: {datei}")
                            continue

                        # PDFs direkt anhängen
                        if datei_pfad.suffix.lower() == '.pdf':
                            try:
                                beleg_pdf = PdfReader(str(datei_pfad))
                                for seite in beleg_pdf.pages:
                                    # Leere Seiten überspringen
                                    if ist_seite_leer(seite):
                                        print(f"Überspringe leere Seite in: {datei}")
                                        continue
                                    # ERST rotieren
                                    seite = korrigiere_seite(seite)
                                    beleg_seiten.append((seite, kostenart, datei_pfad.name))
                            except Exception as e:
                                print(f"Fehler beim Anhängen von {datei}: {e}")
                        # Bilder in PDF konvertieren
                        elif datei_pfad.suffix.lower() in ['.jpg', '.jpeg', '.png']:
                            try:
                                from reportlab.lib.utils import ImageReader
                                bild_buffer = BytesIO()
                                bild_c = canvas.Canvas(bild_buffer, pagesize=A4)
                                bild_breite, bild_hoehe = A4

                                img = ImageReader(str(datei_pfad))
                                img_w, img_h = img.getSize()

                                # Skalierung (max 85% wegen Fußzeile)
                                max_w = bild_breite * 0.85
                                max_h = (bild_hoehe - 2*cm) * 0.85
                                scale = min(max_w / img_w, max_h / img_h)
                                new_w = img_w * scale
                                new_h = img_h * scale

                                # Zentriert zeichnen (etwas höher wegen Fußzeile)
                                x = (bild_breite - new_w) / 2
                                y = (bild_hoehe - new_h) / 2 + 0.5*cm

                                bild_c.drawImage(str(datei_pfad), x, y, new_w, new_h)
                                bild_c.save()
                                bild_buffer.seek(0)

                                bild_pdf = PdfReader(bild_buffer)
                                beleg_seiten.append((bild_pdf.pages[0], kostenart, datei_pfad.name))
                            except Exception as e:
                                print(f"Fehler beim Konvertieren von {datei}: {e}")

        # Alle Beleg-Seiten zum Writer hinzufügen
        for seite, _, _ in beleg_seiten:
            writer.add_page(seite)

        # Gesamtseitenzahl ermitteln
        gesamt_seiten = len(writer.pages)

        # Seitenzahlen als Overlay hinzufügen
        final_writer = PdfWriter()
        for i, seite in enumerate(writer.pages):
            seiten_nr = i + 1

            # Text für Fußzeile
            seiten_text = f"Seite {seiten_nr} von {gesamt_seiten}"
            anlage_text = ""
            if seiten_nr > 1 and (seiten_nr - 2) < len(beleg_seiten):
                _, kostenart, dateiname_beleg = beleg_seiten[seiten_nr - 2]
                anlage_text = f"Anlage: {kostenart} - {dateiname_beleg}"

            # Overlay erstellen - Text links am Rand vertikal
            overlay_buffer = BytesIO()
            overlay_c = canvas.Canvas(overlay_buffer, pagesize=A4)
            overlay_c.setFont(FONT, 8)

            # Beide Texte links am Rand (vertikal, von unten nach oben)
            overlay_c.saveState()
            overlay_c.translate(0.8*cm, 2*cm)
            overlay_c.rotate(90)
            # Anlage-Text und Seitenzahl kombinieren
            if anlage_text:
                overlay_c.drawString(0, 0, f"{anlage_text}  -  {seiten_text}")
            else:
                overlay_c.drawString(0, 0, seiten_text)
            overlay_c.restoreState()
            overlay_c.save()
            overlay_buffer.seek(0)

            # Overlay auf Seite legen
            overlay_pdf = PdfReader(overlay_buffer)
            seite.merge_page(overlay_pdf.pages[0])

            final_writer.add_page(seite)

        # Finales PDF speichern
        with open(str(dateiname), "wb") as f:
            final_writer.write(f)

        return str(dateiname)


class StatistikSeite(QWidget):
    """Seite für Statistik/Historie"""

    def __init__(self, daten: DatenManager):
        super().__init__()
        self.daten = daten
        self.setup_ui()

    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setSpacing(20)

        titel = QLabel("Statistik / Historie")
        titel.setFont(QFont("", 18, QFont.Bold))
        layout.addWidget(titel)

        # Übersicht
        self.tabelle = QTableWidget()
        self.tabelle.setColumnCount(4)
        self.tabelle.setHorizontalHeaderLabels(["Jahr", "Kosten", "Vorauszahlung", "Differenz"])
        self.tabelle.horizontalHeader().setStretchLastSection(True)
        self.tabelle.setSelectionBehavior(QTableWidget.SelectRows)
        layout.addWidget(self.tabelle)

        # Refresh Button
        btn = QPushButton("Aktualisieren")
        btn.clicked.connect(self.lade_daten)
        layout.addWidget(btn)

        self.lade_daten()

    def lade_daten(self):
        self.daten.lade_historie()
        jahre = sorted(self.daten.historie.keys(), reverse=True)

        self.tabelle.setRowCount(len(jahre))

        for i, jahr in enumerate(jahre):
            eintrag = self.daten.historie[jahr]

            self.tabelle.setItem(i, 0, QTableWidgetItem(str(jahr)))
            self.tabelle.setItem(i, 1, QTableWidgetItem(f"{eintrag.get('summe_kosten', 0):.2f} €"))
            self.tabelle.setItem(i, 2, QTableWidgetItem(f"{eintrag.get('summe_vorauszahlung', 0):.2f} €"))

            diff = eintrag.get('differenz', 0)
            diff_item = QTableWidgetItem(f"{diff:+.2f} €")
            if diff > 0:
                diff_item.setForeground(QColor("#CC0000"))
            else:
                diff_item.setForeground(QColor("#006600"))
            self.tabelle.setItem(i, 3, diff_item)


class EinstellungenSeite(QWidget):
    """Seite für Einstellungen"""

    def __init__(self, daten: DatenManager):
        super().__init__()
        self.daten = daten
        self.setup_ui()

    def setup_ui(self):
        layout = QVBoxLayout(self)
        layout.setSpacing(20)

        titel = QLabel("Einstellungen")
        titel.setFont(QFont("", 18, QFont.Bold))
        layout.addWidget(titel)

        # Ordner-Einstellungen
        ordner_group = QGroupBox("Ordner")
        ol = QFormLayout(ordner_group)

        # Daten-Ordner
        daten_layout = QHBoxLayout()
        self.daten_pfad = QLineEdit(self.daten.daten_ordner)
        daten_layout.addWidget(self.daten_pfad)
        btn_daten = QPushButton("...")
        btn_daten.setFixedWidth(40)
        btn_daten.clicked.connect(lambda: self.waehle_ordner(self.daten_pfad))
        daten_layout.addWidget(btn_daten)
        ol.addRow("Daten:", daten_layout)

        # Dokumente-Ordner
        dok_layout = QHBoxLayout()
        self.dok_pfad = QLineEdit(self.daten.dokumente_ordner)
        dok_layout.addWidget(self.dok_pfad)
        btn_dok = QPushButton("...")
        btn_dok.setFixedWidth(40)
        btn_dok.clicked.connect(lambda: self.waehle_ordner(self.dok_pfad))
        dok_layout.addWidget(btn_dok)
        ol.addRow("Dokumente:", dok_layout)

        # Vorlagen-Ordner
        vorl_layout = QHBoxLayout()
        self.vorl_pfad = QLineEdit(self.daten.vorlagen_ordner)
        vorl_layout.addWidget(self.vorl_pfad)
        btn_vorl = QPushButton("...")
        btn_vorl.setFixedWidth(40)
        btn_vorl.clicked.connect(lambda: self.waehle_ordner(self.vorl_pfad))
        vorl_layout.addWidget(btn_vorl)
        ol.addRow("Vorlagen:", vorl_layout)

        layout.addWidget(ordner_group)

        # PDF-Einstellungen
        pdf_group = QGroupBox("PDF-Vorlage")
        pl = QFormLayout(pdf_group)

        self.briefkopf = QDoubleSpinBox()
        self.briefkopf.setRange(0, 15)
        self.briefkopf.setDecimals(1)
        self.briefkopf.setSuffix(" cm")
        self.briefkopf.setValue(self.daten.briefkopf_hoehe)
        pl.addRow("Briefkopf-Höhe:", self.briefkopf)

        self.vorlage_label = QLabel(self._get_vorlage_status())
        pl.addRow("Vorlage-Status:", self.vorlage_label)

        layout.addWidget(pdf_group)

        # Speichern
        btn_layout = QHBoxLayout()
        btn_layout.addStretch()
        btn = QPushButton("Speichern")
        btn.setMinimumWidth(150)
        btn.clicked.connect(self.speichern)
        btn_layout.addWidget(btn)
        layout.addLayout(btn_layout)

        layout.addStretch()

    def waehle_ordner(self, line_edit):
        ordner = QFileDialog.getExistingDirectory(self, "Ordner wählen", line_edit.text())
        if ordner:
            line_edit.setText(ordner)

    def _get_vorlage_status(self):
        if self.daten.vorlage_datei.exists():
            return f"✓ {self.daten.vorlage_datei}"
        return f"Keine Vorlage in {self.daten.vorlagen_ordner}"

    def speichern(self):
        # Ordner aktualisieren
        self.daten.daten_ordner = self.daten_pfad.text()
        self.daten.dokumente_ordner = self.dok_pfad.text()
        self.daten.vorlagen_ordner = self.vorl_pfad.text()
        self.daten.speichere_config()
        self.daten.aktualisiere_pfade()

        # PDF-Einstellungen
        self.daten.briefkopf_hoehe = self.briefkopf.value()
        self.daten.speichere_stammdaten()

        # Status aktualisieren
        self.vorlage_label.setText(self._get_vorlage_status())

        QMessageBox.information(self, "Gespeichert", "Einstellungen gespeichert.")


VERSION = "1.0.0"


class HauptFenster(QMainWindow):
    """Hauptfenster der Anwendung"""

    def __init__(self):
        super().__init__()
        self.daten = DatenManager()
        self.letzte_pdf = None
        self.setup_ui()
        self.setup_menu()

    def setup_ui(self):
        self.setWindowTitle("Nebenkostenabrechnung")
        self.setMinimumSize(900, 650)

        # Icon setzen
        icon_pfad = Path(__file__).parent / "icon.svg"
        if icon_pfad.exists():
            self.setWindowIcon(QIcon(str(icon_pfad)))

        # Zentrales Widget
        central = QWidget()
        self.setCentralWidget(central)
        layout = QHBoxLayout(central)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        # Navigation (links)
        self.nav = QListWidget()
        self.nav.setFixedWidth(180)
        self.nav.setSpacing(2)

        items = [
            ("📝 Neue Abrechnung", 0),
            ("👤 Stammdaten", 1),
            ("📋 Kostenarten", 2),
            ("📊 Statistik", 3),
            ("⚙️ Einstellungen", 4),
        ]

        for text, _ in items:
            item = QListWidgetItem(text)
            item.setSizeHint(QSize(170, 45))
            self.nav.addItem(item)

        self.nav.currentRowChanged.connect(self.seite_wechseln)
        layout.addWidget(self.nav)

        # Trennlinie
        line = QFrame()
        line.setFrameShape(QFrame.VLine)
        line.setStyleSheet("color: #ccc;")
        layout.addWidget(line)

        # Seiten (rechts)
        self.stack = QStackedWidget()

        self.abrechnung_seite = AbrechnungSeite(self.daten)
        self.stammdaten_seite = StammdatenSeite(self.daten)
        self.kostenarten_seite = KostenartenSeite(self.daten)
        self.statistik_seite = StatistikSeite(self.daten)
        self.einstellungen_seite = EinstellungenSeite(self.daten)

        self.stack.addWidget(self.abrechnung_seite)
        self.stack.addWidget(self.stammdaten_seite)
        self.stack.addWidget(self.kostenarten_seite)
        self.stack.addWidget(self.statistik_seite)
        self.stack.addWidget(self.einstellungen_seite)

        content_widget = QWidget()
        content_layout = QVBoxLayout(content_widget)
        content_layout.setContentsMargins(20, 20, 20, 20)
        content_layout.addWidget(self.stack)

        layout.addWidget(content_widget, 1)

        # Erste Seite auswählen
        self.nav.setCurrentRow(0)

    def setup_menu(self):
        """Erstellt die Menüleiste"""
        from PySide6.QtGui import QAction, QKeySequence

        menubar = self.menuBar()

        # Datei-Menü
        datei_menu = menubar.addMenu("&Datei")

        action_neu = QAction("&Neue Abrechnung", self)
        action_neu.setShortcut(QKeySequence("Ctrl+N"))
        action_neu.triggered.connect(lambda: self.nav.setCurrentRow(0))
        datei_menu.addAction(action_neu)

        action_drucken = QAction("&Drucken...", self)
        action_drucken.setShortcut(QKeySequence("Ctrl+P"))
        action_drucken.triggered.connect(self.drucken)
        datei_menu.addAction(action_drucken)

        action_ordner = QAction("Dokumente-&Ordner öffnen", self)
        action_ordner.triggered.connect(self.ordner_oeffnen)
        datei_menu.addAction(action_ordner)

        datei_menu.addSeparator()

        action_beenden = QAction("&Beenden", self)
        action_beenden.setShortcut(QKeySequence("Ctrl+Q"))
        action_beenden.triggered.connect(self.close)
        datei_menu.addAction(action_beenden)

        # Bearbeiten-Menü
        bearbeiten_menu = menubar.addMenu("&Bearbeiten")

        action_stamm = QAction("&Stammdaten", self)
        action_stamm.triggered.connect(lambda: self.nav.setCurrentRow(1))
        bearbeiten_menu.addAction(action_stamm)

        action_kosten = QAction("&Kostenarten", self)
        action_kosten.triggered.connect(lambda: self.nav.setCurrentRow(2))
        bearbeiten_menu.addAction(action_kosten)

        action_einst = QAction("&Einstellungen", self)
        action_einst.triggered.connect(lambda: self.nav.setCurrentRow(4))
        bearbeiten_menu.addAction(action_einst)

        # Ansicht-Menü
        ansicht_menu = menubar.addMenu("&Ansicht")

        action_statistik = QAction("&Statistik / Historie", self)
        action_statistik.triggered.connect(lambda: self.nav.setCurrentRow(3))
        ansicht_menu.addAction(action_statistik)

        # Hilfe-Menü
        hilfe_menu = menubar.addMenu("&?")

        action_info = QAction("&Info", self)
        action_info.setShortcut(QKeySequence("F1"))
        action_info.triggered.connect(self.zeige_info)
        hilfe_menu.addAction(action_info)

    def drucken(self):
        """Öffnet den Druckdialog für das letzte PDF"""
        from PySide6.QtPrintSupport import QPrinter, QPrintDialog
        from PySide6.QtGui import QPainter, QPixmap

        # Prüfen ob ein PDF existiert
        jahr = self.abrechnung_seite.jahr.value()
        mieter_name = self.daten.mieter.get("name", "").replace(" ", "_")
        pdf_pfad = Path(self.daten.dokumente_ordner) / str(jahr) / f"Nebenkostenabrechnung_{jahr}_{mieter_name}.pdf"

        if not pdf_pfad.exists():
            QMessageBox.warning(self, "Kein PDF", "Bitte erst eine Abrechnung erstellen.")
            return

        # Druckdialog
        printer = QPrinter(QPrinter.HighResolution)
        dialog = QPrintDialog(printer, self)

        if dialog.exec() == QPrintDialog.Accepted:
            # PDF mit Systembefehl drucken
            import subprocess
            subprocess.run(["lpr", str(pdf_pfad)])
            QMessageBox.information(self, "Gedruckt", f"Druckauftrag gesendet:\n{pdf_pfad.name}")

    def ordner_oeffnen(self):
        """Öffnet den Dokumente-Ordner"""
        import subprocess
        subprocess.run(["xdg-open", self.daten.dokumente_ordner])

    def zeige_info(self):
        """Zeigt den Info-Dialog"""
        info_text = f"""<h2>Nebenkostenabrechnung</h2>
        <p><b>Version:</b> {VERSION}</p>
        <p><b>Beschreibung:</b><br>
        Erstellt Nebenkostenabrechnungen für Mietobjekte
        gemäß § 556 BGB mit allen Pflichtangaben.</p>

        <p><b>Funktionen:</b></p>
        <ul>
        <li>Automatische Speicherung von Entwürfen</li>
        <li>Belege anhängen (PDF, JPG, PNG)</li>
        <li>PDF-Vorlage mit Briefkopf</li>
        <li>Vorjahresvergleich</li>
        <li>Historie aller Abrechnungen</li>
        </ul>

        <p><b>Ordner:</b></p>
        <ul>
        <li>Daten: {self.daten.daten_ordner}</li>
        <li>Dokumente: {self.daten.dokumente_ordner}</li>
        <li>Vorlagen: {self.daten.vorlagen_ordner}</li>
        </ul>

        <p><b>PDF-Vorlage:</b><br>
        Legen Sie eine Datei <code>vorlage.pdf</code> im Vorlagen-Ordner ab,
        um einen Briefkopf/Wasserzeichen zu verwenden.</p>

        <hr>
        <p style="color: gray;">© 2024 - Entwickelt mit Python & PySide6</p>
        """

        QMessageBox.about(self, "Info", info_text)

    def seite_wechseln(self, index):
        self.stack.setCurrentIndex(index)

        # Daten aktualisieren
        if index == 0:
            self.abrechnung_seite.aktualisiere_kosten()
        elif index == 2:
            self.kostenarten_seite.lade_daten()
        elif index == 3:
            self.statistik_seite.lade_daten()


def installiere_startmenu():
    """Installiert Startmenü-Eintrag beim ersten Start"""
    import shutil

    # Pfade
    programm_ordner = Path(__file__).parent.resolve()
    desktop_quelle = programm_ordner / "nebenkostenabrechnung.desktop"
    desktop_ziel = Path.home() / ".local" / "share" / "applications" / "nebenkostenabrechnung.desktop"

    # Nur installieren wenn Quelldatei existiert und Ziel noch nicht
    if desktop_quelle.exists() and not desktop_ziel.exists():
        try:
            desktop_ziel.parent.mkdir(parents=True, exist_ok=True)
            shutil.copy2(desktop_quelle, desktop_ziel)
            print(f"Startmenü-Eintrag installiert: {desktop_ziel}")
        except Exception as e:
            print(f"Startmenü-Installation fehlgeschlagen: {e}")


def main():
    # Startmenü-Eintrag installieren (beim ersten Start)
    installiere_startmenu()

    app = QApplication(sys.argv)
    app.setStyle("Fusion")

    fenster = HauptFenster()
    fenster.show()

    sys.exit(app.exec())


if __name__ == "__main__":
    main()
